Gestor de nuevos markers en proceso...

This commit is contained in:
Siroco 2018-09-22 00:03:53 +02:00
parent 48233010e7
commit 46d4c450a1
25 changed files with 1126 additions and 157 deletions

569
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -21,8 +21,10 @@
"@angular/platform-browser": "^5.2.0",
"@angular/platform-browser-dynamic": "^5.2.0",
"@angular/router": "^5.2.0",
"@mapbox/mapbox-gl-geocoder": "^2.3.0",
"classlist.js": "1.1.20150312",
"core-js": "^2.4.1",
"mapbox-gl": "^0.49.0",
"rxjs": "^5.5.6",
"zone.js": "^0.8.19"
},

View File

@ -0,0 +1,40 @@
.container {
width:250px;
min-width:200px;
min-height:50px;
max-height:80vh;
overflow-y:auto;
background:rgba(0,0,0,0.8);
border:#fff solid 0px;
margin:20px;
color:#fff;
padding:30px 10px;
font-size:0.8em;
}
.container::before {
display: block;
position: absolute;
top: 15px;
right: 2.7rem;
width: 0;
height: 0;
border-right: 8px solid transparent;
border-bottom: 8px solid #333;
border-left: 8px solid transparent;
content: "";
z-index: 1000;
}
h1 { font-size:1em; }
button { font-family:'Raleway',sans-serif; background:transparent; padding:5px; width:100%; color:#fff; border:#fff solid 2px;}
button:hover {background:#fff;color:#000;cursor:pointer;}
.ng-valid[required], .ng-valid.required {
border-left: 5px solid #42A948; /* green */
}
.ng-invalid:not(form) {
border-left: 5px solid #a94442; /* red */
}

View File

@ -0,0 +1,33 @@
<div class="container" [hidden]="!appService.markers.length">
<div [hidden]="!submitted">
<p>Gracias por participar</p>
</div>
<div [hidden]="submitted">
<h1>Agrega un nuevo sonido</h1>
<p>Publica nuevos contenidos</p>
<h2>Coord: {{appService.markers}}</h2>
{{diagnostic}}
<form (ngSubmit)="onSubmit()" #documentForm="ngForm">
<div class="form-group">
<label for="title">Título</label>
<input type="text" id="title" [(ngModel)]="document.title" name="title" required/>
</div>
<div class="form-group">
<label for="author">Autor/a</label>
<input type="text" id="author" [(ngModel)]="document.author" name="author" required/>
</div>
<div class="form-group">
<label for="description">Descripción</label>
<textarea id="description" [(ngModel)]="document.description" name="description"></textarea>
</div>
<div class="form-group">
<label for="category">Categoría</label>
<select id="category" [(ngModel)]="document.category" name="category" required>
<option *ngFor="let cat of categories" [value]="cat">{{cat}}</option>
</select>
</div>
<button type="submit" [disabled]="!documentForm.form.valid">Envía</button>
<button type="button" (click)="appService.clearMarker()">Cancela</button>
</form>
</div>
</div>

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AddContentComponent } from './add-content.component';
describe('AddContentComponent', () => {
let component: AddContentComponent;
let fixture: ComponentFixture<AddContentComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AddContentComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AddContentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,36 @@
import { Component, OnInit } from '@angular/core';
import { Documento, GeoJson } from '../map';
import { AppService } from '../app.service';
@Component({
selector: 'add-content',
templateUrl: './add-content.component.html',
styleUrls: ['./add-content.component.css']
})
export class AddContentComponent implements OnInit {
categories = ['bioacustica', 'social', 'urbano', 'natural'];
document = new Documento(1,new GeoJson([0,0]),'', '', '', this.categories[0], '');
submitted = false;
constructor(public appService : AppService) {
console.log('onConstruct')
}
onSubmit() {
this.document.setCoord(this.appService.markers)
console.log(this.document);
this.submitted = false
}
ngOnInit() {
console.log('oninit')
this.document.setCoord(this.appService.markers)
}
get diagnostic() { return JSON.stringify(this.document) }
}

View File

@ -1,10 +1,11 @@
<app-messages></app-messages>
<messages></messages>
<add-content></add-content>
<header>
<soinu-progress *ngIf="!isMap"></soinu-progress>
</header>
<section *ngIf="!isMap">
<h1>Construir a través del oído</h1>
<p>El objetivo de Landarte 2018, el programa de arte y ruralidad de la Dirección General-Institución Príncipe de Viana,, es desarrollar un mapa sonoro de Sartaguda que pueda proyectarse tanto en el parque de la memoria como en otros espacios de localidad. Los encargados de guiar al vecindario en la realización de esta peculiar obra de arte es el artista sonoro <b>Xabier Erkizia</b> y <b>Luca Rullo</b>, de la asociación <a href="https://www.audio-lab.org">AUDIOLAB</a>.</p>
<p i18n="Texto intro">El objetivo de Landarte 2018, el programa de arte y ruralidad de la Dirección General-Institución Príncipe de Viana,, es desarrollar un mapa sonoro de Sartaguda que pueda proyectarse tanto en el parque de la memoria como en otros espacios de localidad. Los encargados de guiar al vecindario en la realización de esta peculiar obra de arte es el artista sonoro <b>Xabier Erkizia</b> y <b>Luca Rullo</b>, de la asociación <a href="https://www.audio-lab.org">AUDIOLAB</a>.</p>
<nav *ngIf="appService.acceptCookies">
<button pButton label="map" (click)="showMap()" title="Muestra el mapa">Mapa</button>
<button pButton label="listen" (click)="listenStream()" title="En directo">En directo</button>

View File

@ -1,5 +1,7 @@
import { Component } from '@angular/core';
import { AppService } from './app.service';
import { GeojsonService } from './geojson.service';
import { Observable } from 'rxjs/Observable';
@Component({
selector: 'app-root',
@ -9,8 +11,12 @@ import { AppService } from './app.service';
export class AppComponent {
title = 'Sartaguda suena';
isMap = false;
info: Observable<any>;
constructor(public appService: AppService) { }
constructor(public appService: AppService,
public geojsonService: GeojsonService ) {
this.geojsonService.getData();
}
showMap() {
this.isMap = true;

View File

@ -1,13 +1,17 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule } from '@angular/forms';
import { MapService } from './map.service';
import { AppService } from './app.service';
import { GeojsonService } from './geojson.service';
import { AppComponent } from './app.component';
import { MapBoxComponent } from './map-box/map-box.component';
import { SoinuProgressComponent } from './soinu-progress/soinu-progress.component';
import { MessagesComponent } from './messages/messages.component';
import { AddContentComponent } from './add-content/add-content.component';
@NgModule({
@ -15,14 +19,18 @@ import { MessagesComponent } from './messages/messages.component';
AppComponent,
MapBoxComponent,
SoinuProgressComponent,
MessagesComponent
MessagesComponent,
AddContentComponent
],
imports: [
BrowserModule
BrowserModule,
HttpClientModule,
FormsModule
],
providers: [
MapService,
AppService
AppService,
GeojsonService
],
bootstrap: [AppComponent]
})

View File

@ -1,4 +1,5 @@
import { Injectable } from '@angular/core';
import { GeoJson } from './map';
@Injectable()
export class AppService {
@ -7,14 +8,24 @@ export class AppService {
acceptCookies: boolean = false;
audioStreamingUrl = "http://irratia.zintzilik.net";
button: boolean = false;
markers: any[] = [];
constructor() {}
constructor() { }
add(message: string, button:boolean = false) {
this.messages.push(message);
this.button=button;
}
addMarker(message: string, coord:any[]) {
this.markers = coord
console.log('new marker: '+coord)
}
clearMarker() {
this.markers = [];
}
clear() {
this.messages = [];
this.acceptCookies = true;

View File

@ -0,0 +1,15 @@
import { TestBed, inject } from '@angular/core/testing';
import { GeojsonService } from './geojson.service';
describe('GeojsonService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [GeojsonService]
});
});
it('should be created', inject([GeojsonService], (service: GeojsonService) => {
expect(service).toBeTruthy();
}));
});

View File

@ -0,0 +1,43 @@
import { Injectable } from '@angular/core';
import { GeoJson, MARKERS } from './map';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import 'rxjs/add/operator/map';
@Injectable()
export class GeojsonService {
accessToken:string;
apiUrl:string;
constructor( private http: HttpClient) {
this.accessToken = '1245c38775ff9fd8b8a721e4fe7472ab5d06020f853f66c516f26eb96fb87235'
this.apiUrl = 'http://ca.ecouterlemonde.net/service.php/find/ca_objects'
}
getData() {
const data = {
"bundles" : {
"access" : { "convertCodesToDisplayText" : true },
"status" : { "convertCodesToDisplayText" : true },
"ca_entities.entity_id" : {"returnAsArray" : true }
}
}
const params = new HttpParams()
.set('authToken',this.accessToken)
.set('q','*')
.set('source',encodeURIComponent(JSON.stringify(data)))
console.log(encodeURIComponent(JSON.stringify(data)))
/*this.http.get(this.apiUrl, { params: params } )
.subscribe( resp=> {
console.log('.... data ...');
console.log(resp);
});*/
return of();
}
}

View File

@ -1,3 +1,4 @@
/*@import '../../../node_modules/@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css';*/
.map { width:100%;height:100%; position:absolute; top:0; left:0;}
.mapboxgl-marker { width:30px;height:30px;background:#fff;}
.mapboxgl-marker { width:300px; height:300px; background:#fff !important; }

View File

@ -3,6 +3,8 @@ import * as mapboxgl from 'mapbox-gl';
import { MapService } from '../map.service';
import { AppService } from '../app.service';
import { GeoJson, FeatureCollection} from '../map';
//import * as MapboxGeocoder from '@mapbox/mapbox-gl-geocoder';
@Component({
selector: 'map-box',
@ -23,6 +25,7 @@ export class MapBoxComponent implements OnInit {
markers: any;
hoverid: null;
activeMarker: any;
newMarker: any;
constructor(
private mapService: MapService,
@ -47,14 +50,26 @@ export class MapBoxComponent implements OnInit {
pitch: 60, // pitch in degrees
bearing: 0, // bearing in degrees
center: [this.lng, this.lat],
attributionControl: {
compact: true,
customAttribution: "Developed by Audiolab"
}
});
// controls
this.map.addControl(new mapboxgl.NavigationControl())
// this.map.addControl(new MapboxGeocoder({
// accessToken: mapboxgl.accessToken
// }));
let feed = "http://www.soinumapa.net/geojson/"
/*mapboxgl.util.getJSON(feed, (err,data) => {
this.map.addSource('soinumapa', {
type:'geojson',
data: data,
cluster:true,
clusterMaxZoom:30,
clusterRadius: 50
})*/
this.map.on('click','clusters', (event) => {
let features = this.map.queryRenderedFeatures(event.point, { layers: ['clusters'] });
@ -68,6 +83,24 @@ export class MapBoxComponent implements OnInit {
})
})
this.map.on('click',(event)=> {
if (this.newMarker!=undefined) this.newMarker.remove()
var features = this.map.queryRenderedFeatures(event.point, {layers:['clusters','soinumapa']});
//console.log(features);
if (features.length==0) {
var el = document.createElement('div');
el.className = 'marker new-marker';
const coordinates = [event.lngLat.lng, event.lngLat.lat]
// const newMarker = new GeoJson(coordinates, { message : 'new marker' })
this.appService.addMarker('new marker',coordinates)
this.newMarker = new mapboxgl.Marker(el)
.setLngLat(coordinates)
.addTo(this.map);
}
//console.log(event)
})
this.map.on('click','soinumapa', (event) => {
// clean old markers
//let m = document.getElementsByClassName('active-marker')
@ -76,16 +109,18 @@ export class MapBoxComponent implements OnInit {
if (this.activeMarker!=undefined) this.activeMarker.remove()
const coordinates = [event.lngLat.lng, event.lngLat.lat]
const newMarker = new GeoJson(coordinates, { message : 'new marker' })
//const newMarker = new GeoJson(coordinates, { message : 'new marker' })
//this.appService.addMarker('new marker',newMarker)
let content = event.features[0].properties.content
let title = event.features[0].properties.title
let url = event.features[0].properties.attachment
let author = event.features[0].properties.author
let category = event.features[0].properties.category
let date = event.features[0].properties.date
console.log(event.features[0].properties)
//console.log(event.features[0].properties)
let info = "<h2>"+title+"</h2><h3>"+author+"</h3><p>"+date+"</p>"+content+"<br/><audio class=\"marker-player\"controls autoplay src=\""+url+"\"></audio>"
console.log(event.features[0]);
//console.log(event.features[0]);
this.appService.clear()
this.appService.add(info)
@ -118,27 +153,13 @@ export class MapBoxComponent implements OnInit {
});
this.map.on('load',(event) => {
let feed = "http://www.soinumapa.net/geojson/"
this.map.addSource('soinumapa', {
type: 'geojson',
//data: feed,
data: '/assets/soinumapa.geojson',
cluster:true,
clusterMaxZoom: 30,
clusterRadius: 50
})
/*mapboxgl.util.getJSON(feed, (err,data) => {
this.map.addSource('soinumapa', {
type:'geojson',
data: data,
cluster:true,
clusterMaxZoom:30,
clusterRadius: 50
})*/
this.map.addSource('soinumapa', {
type: 'geojson',
data: '/assets/soinumapa.geojson',
cluster: true,
clusterMaxZoom: 30,
clusterRadius: 50,
})
this.map.addLayer({
id: "clusters",
@ -146,32 +167,33 @@ export class MapBoxComponent implements OnInit {
source: "soinumapa",
filter: ["has", "point_count"],
paint: {
// Use step expressions (https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-step)
// with three steps to implement three types of circles:
// * Blue, 20px circles when point count is less than 100
// * Yellow, 30px circles when point count is between 100 and 750
// * Pink, 40px circles when point count is greater than or equal to 750
"circle-color": [
"step",
["get", "point_count"],
"#ff6968",
100,
"#efeec2",
750,
"#f28cb1"
"#e5c126",
5,
"#e5c53c",
10,
"#f46a40"
],
"circle-blur": 0.3,
"circle-radius": [
"step",
["get", "point_count"],
20,
100,
20,
3,
30,
5,
40,
7,
50,
10,
60,
750,
40
80
]
}
});
this.map.addLayer({
id: "cluster-count",
type: "symbol",
@ -183,11 +205,9 @@ export class MapBoxComponent implements OnInit {
"text-size": 12
}
});
this.map.loadImage('/assets/icon-red.png', (error,image) => {
if (error) throw error;
this.map.addImage('icon-red',image);
this.map.addLayer({
id: "soinumapa",
source: "soinumapa",
@ -207,7 +227,6 @@ export class MapBoxComponent implements OnInit {
}
})
}) //load image
//}) // load feed
})
}

View File

@ -0,0 +1,233 @@
import { Component, OnInit } from '@angular/core';
import * as mapboxgl from 'mapbox-gl';
import { MapService } from '../map.service';
import { AppService } from '../app.service';
import { GeoJson, FeatureCollection} from '../map';
@Component({
selector: 'map-box',
templateUrl: './map-box.component.html',
styleUrls: ['./map-box.component.css']
})
export class MapBoxComponent implements OnInit {
map: mapboxgl.Map;
style = 'mapbox://styles/mapbox/outdoors-v9';
lng = -2.047919;
lat = 42.383986;
message = 'Map from Sartaguda';
// data
source: any;
markers: any;
hoverid: null;
activeMarker: any;
constructor(
private mapService: MapService,
public appService: AppService
) { }
ngOnInit() {
this.initializeMap()
}
private initializeMap() {
this.markers = this.mapService.getMarkers()
this.buildMap()
}
buildMap() {
console.log("building map")
this.map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/outdoors-v9',
//style: 'mapbox://styles/lrullo/cjm4bqlj2b36y2ss4mpq41uxs',
zoom: 13,
pitch: 60, // pitch in degrees
bearing: 0, // bearing in degrees
center: [this.lng, this.lat],
});
// controls
this.map.addControl(new mapboxgl.NavigationControl())
this.map.on('click','clusters', (event) => {
let features = this.map.queryRenderedFeatures(event.point, { layers: ['clusters'] });
let clusterId = features[0].properties.cluster_id;
this.map.getSource('soinumapa').getClusterExpansionZoom(clusterId, (err,zoom) => {
if (err) return
this.map.easeTo({
center: features[0].geometry.coordinates,
zoom: zoom
});
})
})
this.map.on('click','soinumapa', (event) => {
// clean old markers
//let m = document.getElementsByClassName('active-marker')
//if (m.length > 0) document.removeChild(m[0])
if (this.activeMarker!=undefined) this.activeMarker.remove()
const coordinates = [event.lngLat.lng, event.lngLat.lat]
const newMarker = new GeoJson(coordinates, { message : 'new marker' })
let content = event.features[0].properties.content
let title = event.features[0].properties.title
let url = event.features[0].properties.attachment
let author = event.features[0].properties.author
let category = event.features[0].properties.category
let date = event.features[0].properties.date
console.log(event.features[0].properties)
let info = "<h2>"+title+"</h2><h3>"+author+"</h3><p>"+date+"</p>"+content+"<br/><audio class=\"marker-player\"controls autoplay src=\""+url+"\"></audio>"
console.log(event.features[0]);
this.appService.clear()
this.appService.add(info)
var el = document.createElement('div');
el.className = 'marker active-marker';
this.activeMarker = new mapboxgl.Marker(el)
.setLngLat(event.features[0].geometry.coordinates)
.addTo(this.map);
})
this.map.on('mouseenter',"clusters", (event) => {
this.map.getCanvas().style.cursor = 'pointer';
});
this.map.on('mouseenter','soinumapa', (event) => {
this.map.getCanvas().style.cursor = 'pointer';
let id = event.features[0].properties.id
this.map.setFeatureState({source:'soinumapa',id: id}, { hover:true })
this.hoverid = id
})
this.map.on("mouseleave", "clusters", () => {
this.map.getCanvas().style.cursor = '';
});
this.map.on("mouseleave", "soinumapa", () => {
this.map.getCanvas().style.cursor = '';
if (this.hoverid) this.map.setFeatureState({source: 'soinumapa', id: this.hoverid}, { hover: false});
this.hoverid = null
});
this.map.on('load',(event) => {
console.log("map is loadded")
console.log(this.map)
/* test */
var em = document.createElement('div');
em.className = 'marker ecouterlemonde';
this.activeMarker = new mapboxgl.Marker(em)
.setLngLat([2.349014,48.864716])
.addTo(this.map);
let feed = "http://www.soinumapa.net/geojson/"
this.map.addSource('soinumapa', {
type: 'geojson',
//data: feed,
data: '/assets/soinumapa.geojson',
cluster:true,
clusterMaxZoom: 30,
clusterRadius: 50
})
/*mapboxgl.util.getJSON(feed, (err,data) => {
this.map.addSource('soinumapa', {
type:'geojson',
data: data,
cluster:true,
clusterMaxZoom:30,
clusterRadius: 50
})*/
this.map.addLayer({
id: "clusters",
type: "circle",
source: "soinumapa",
filter: ["has", "point_count"],
paint: {
"circle-color": [
"step",
["get", "point_count"],
"#ff6968",
5,
"#efeec2",
10,
"#f28cb1"
],
"circle-radius": [
"step",
["get", "point_count"],
10,
3,
20,
5,
30,
7,
40,
10,
30,
750,
40
]
}
});
this.map.addLayer({
id: "cluster-count",
type: "symbol",
source: "soinumapa",
filter: ["has", "point_count"],
layout: {
"text-field": "{point_count_abbreviated}",
"text-font": ["DIN Offc Pro Medium", "Arial Unicode MS Bold"],
"text-size": 12
}
});
this.map.loadImage('/assets/icon-red.png', (error,image) => {
if (error) throw error;
this.map.addImage('icon-red',image);
this.map.addLayer({
id: "soinumapa",
source: "soinumapa",
type: "symbol",
filter: ["!", ["has", "point_count"]],
layout: {
'icon-image': "icon-red",
'icon-size': 0.5,
},
paint: {
'icon-opacity': ["case",
["boolean", ["feature-state", "hover"], false],
0.5,
1
]
}
})
}) //load image
//}) // load feed
})
}
}
/* DOCUMENTATION */
/*----
https://www.mapbox.com/help/working-with-large-geojson-data/
https://www.mapbox.com/mapbox-gl-js/example/cluster/
https://www.mapbox.com/mapbox-gl-js/example/popup-on-hover/
https://www.mapbox.com/mapbox-gl-js/example/hover-styles/
https://angularfirebase.com/lessons/build-realtime-maps-in-angular-with-mapbox-gl/
----*/

View File

@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { environment } from '../environments/environment';
import { GeoJson, MARKERS } from './map';
import * as mapboxgl from 'mapbox-gl';
import { GeoJson, MARKERS } from './map';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';

View File

@ -70,3 +70,20 @@ export const MARKERS: IGeoJson[] = [
]
export class Map {}
export class Documento {
constructor (
public id: number,
public coord: GeoJson,
public title: string,
public author: string,
public email: string,
public category: string,
public file: string,
public description?: string
) {}
public setCoord(coord:number[]) {
this.coord = new GeoJson(coord)
}
}

View File

@ -1,3 +1,4 @@
div.messages-container {
width:250px;
min-width:200px;
@ -12,6 +13,21 @@ div.messages-container {
font-size:0.8em;
}
div.messages-container::before {
display: block;
position: absolute;
top: 15px;
left: 2.7rem;
width: 0;
height: 0;
border-right: 8px solid transparent;
border-bottom: 8px solid #333;
border-left: 8px solid transparent;
content: "";
z-index: 1000;
}
h1 { font-size:1em; }
button { font-family:'Raleway',sans-serif; background:transparent; padding:5px; width:100%; color:#fff; border:#fff solid 2px;}

View File

@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core';
import { AppService } from '../app.service';
@Component({
selector: 'app-messages',
selector: 'messages',
templateUrl: './messages.component.html',
styleUrls: ['./messages.component.css']
})

BIN
src/assets/em.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

15
src/messages.xlf Normal file
View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="ng2.template">
<body>
<trans-unit id="e953472f729d42a94847e36dca8c86f2ff37f0e8" datatype="html">
<source>El objetivo de Landarte 2018, el programa de arte y ruralidad de la Dirección General-Institución Príncipe de Viana,, es desarrollar un mapa sonoro de Sartaguda que pueda proyectarse tanto en el parque de la memoria como en otros espacios de localidad. Los encargados de guiar al vecindario en la realización de esta peculiar obra de arte es el artista sonoro <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Xabier Erkizia<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> y <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b&gt;"/>Luca Rullo<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/>, de la asociación <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>AUDIOLAB<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
<context-group purpose="location">
<context context-type="sourcefile">app/app.component.ts</context>
<context context-type="linenumber">7</context>
</context-group>
<note priority="1" from="description">Texto intro</note>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -7,20 +7,47 @@ a { color:#fff; font-weight:bold; cursor:pointer; text-decoration:none;}
/* map */
#map { width:100%;height:100%; position:absolute; top:0; left:0;}
.active-marker {
width:50px;
height:50px;
border-radius:100%;
border:#f95f5f solid 5px;
border:#000 solid 2px;
border-top:0;
animation: hideshow 3s ease infinite;
}
.new-marker {
width:50px;
height:50px;
border-radius:100%;
border:0;
background-color:#f3e;
}
.ecouterlemonde {
width:200px;
height:200px;
background-image:url('/assets/em.jpg');
background-size:cover;
background-color:transparent;
background-position:center center;
background-repeat: no-repeat;
-webkit-box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.5);
-moz-box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.5);
box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.5);
}
@keyframes hideshow {
0% { opacity:0; transform:scale(1); }
50% { opacity:1; transform:scale(1.5); }
100% { opacity:0; transform:scale(1);}
0% { opacity:0; transform:rotate(0deg); }
50% { opacity:1; transform:rotate(180deg); }
100% { opacity:0; transform:rotate(360deg);}
}
.marker-player { max-width:100%;margin-top:50px;}
/* add content */
messages { position:fixed; z-index:100; left:0; top:0;z-index:1000; }
add-content { position:absolute; right:0; top:0; z-index:1000;}