Compare commits
9 Commits
695751627a
...
0bcd5861ec
Author | SHA1 | Date | |
---|---|---|---|
|
0bcd5861ec | ||
|
e2eac2a19c | ||
|
2427d43db2 | ||
|
c65f2cb516 | ||
|
3559b2ac43 | ||
|
9b6d478a62 | ||
|
47eb8be435 | ||
|
8d8abef45a | ||
|
9682f646cb |
@ -25,7 +25,8 @@
|
||||
"aot": true,
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
"src/assets",
|
||||
"src/manifest.json"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.scss"
|
||||
|
733
package-lock.json
generated
23
package.json
@ -11,22 +11,23 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~10.2.0",
|
||||
"@angular/common": "~10.2.0",
|
||||
"@angular/compiler": "~10.2.0",
|
||||
"@angular/core": "~10.2.0",
|
||||
"@angular/forms": "~10.2.0",
|
||||
"@angular/platform-browser": "~10.2.0",
|
||||
"@angular/platform-browser-dynamic": "~10.2.0",
|
||||
"@angular/router": "~10.2.0",
|
||||
"@angular/animations": "~10.2.1",
|
||||
"@angular/common": "~10.2.1",
|
||||
"@angular/compiler": "~10.2.1",
|
||||
"@angular/core": "~10.2.1",
|
||||
"@angular/forms": "~10.2.1",
|
||||
"@angular/platform-browser": "~10.2.1",
|
||||
"@angular/platform-browser-dynamic": "~10.2.1",
|
||||
"@angular/router": "~10.2.1",
|
||||
"@vimeo/player": "^2.14.1",
|
||||
"rxjs": "~6.6.3",
|
||||
"tslib": "^2.0.0",
|
||||
"zone.js": "~0.10.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~0.1001.7",
|
||||
"@angular/cli": "~10.1.7",
|
||||
"@angular/compiler-cli": "~10.2.0",
|
||||
"@angular-devkit/build-angular": "~0.1002.0",
|
||||
"@angular/cli": "~10.2.0",
|
||||
"@angular/compiler-cli": "~10.2.1",
|
||||
"@types/node": "^12.11.1",
|
||||
"@types/jasmine": "~3.5.0",
|
||||
"@types/jasminewd2": "~2.0.3",
|
||||
|
16
src/_variables.scss
Normal file
@ -0,0 +1,16 @@
|
||||
// Create your Sass color vars (will be available in all the project)
|
||||
$primary: #ffffff;
|
||||
$accent: #d33131;
|
||||
$reverse: #000000;
|
||||
$green: #4caf50;
|
||||
$yellow: #ffeb3b;
|
||||
$warn: yellow;
|
||||
|
||||
//media query
|
||||
$breakpoint-tablet: 768px;
|
||||
$breakpoint-phone: 500px;
|
||||
$background-color: #1c1c1c;
|
||||
// $slide-background: #f90;
|
||||
$slide-background: #090501;
|
||||
|
||||
$backgroundhover: #ff0038b5;
|
@ -6,7 +6,8 @@ import { InitComponent} from './init/init.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: ':name', component: SlideComponent },
|
||||
{ path: '', component: InitComponent }
|
||||
{ path: '', redirectTo: '/home', pathMatch: 'full'}
|
||||
// { path: '', component: InitComponent }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div [@myAnimation]="o.isActivated ? o.activatedRoute : ''">
|
||||
<div class="router" [@myAnimation]="o.isActivated ? o.activatedRoute : ''">
|
||||
<router-outlet #o="outlet"></router-outlet>
|
||||
</div>
|
||||
|
||||
|
@ -0,0 +1 @@
|
||||
div.router { overflow:hidden;}
|
@ -1,4 +1,4 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import {
|
||||
transition,
|
||||
@ -27,4 +27,21 @@ import {
|
||||
|
||||
export class AppComponent {
|
||||
title = 'beire-frontend';
|
||||
|
||||
ngOnInit() {
|
||||
// var $ = document.getElementById.bind(document);
|
||||
//
|
||||
// var orientKey = 'orientation';
|
||||
// if ('mozOrientation' in screen) {
|
||||
// orientKey = 'mozOrientation';
|
||||
// } else if ('msOrientation' in screen) {
|
||||
// orientKey = 'msOrientation';
|
||||
// }
|
||||
//
|
||||
// var promise = null;
|
||||
// if (screen[orientKey].lock) { promise = screen[orientKey].lock('landscape-primary'); }
|
||||
// lockedAllowed = window.screen.lockOrientation(orientation);
|
||||
|
||||
// document.documentElement.requestFullscreen();
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,10 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { SlideComponent } from './slide/slide.component';
|
||||
import { InitComponent } from './init/init.component';
|
||||
|
||||
import { ClientService } from './client.service';
|
||||
import { InitComponent } from './init/init.component';
|
||||
import { PlayerService } from './player.service';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@ -23,7 +24,8 @@ import { InitComponent } from './init/init.component';
|
||||
HttpClientModule
|
||||
],
|
||||
providers: [
|
||||
ClientService
|
||||
ClientService,
|
||||
PlayerService,
|
||||
],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
|
@ -1,5 +1,14 @@
|
||||
<div class="slide">
|
||||
<div class="slide" routerLink="home" style="background-image:url('/assets/img/trailer.gif');">
|
||||
<div class="element">
|
||||
<div class="round-button" title="Pulsa para iniciar" routerLink="home"></div>
|
||||
<!-- <h1 routerLink="home" style="cursor:pointer">Beire</h1> -->
|
||||
<!-- <h2>Un propuesta de Maite Redondo y Luca Rullo</h2> -->
|
||||
<!-- <div class="round-button" title="Pulsa para iniciar" routerLink="home" (click)="play()"></div> -->
|
||||
<!-- <h3>Con la ayuda de Pedro, María, Luis, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre,Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre </h3> -->
|
||||
<div class="element logo">
|
||||
<img src="assets/img/landarte_logo.png"/>
|
||||
<img src="assets/img/logoCK.png"/>
|
||||
<img src="assets/img/logoBeire.png"/>
|
||||
<img src="assets/img/logoSoinumapa.png"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,9 +1,16 @@
|
||||
@import "../../_variables.scss";
|
||||
|
||||
h1 {
|
||||
margin-top:0;
|
||||
margin-bottom:0;
|
||||
}
|
||||
|
||||
div.slide {
|
||||
color:#fff;
|
||||
color:$primary;
|
||||
width:100vw;
|
||||
height:100vh;
|
||||
background-size:cover;
|
||||
background-color:#f90;
|
||||
background-color:#ccc;
|
||||
background-blend-mode: luminosity;
|
||||
display:flex;
|
||||
justify-content: center;
|
||||
@ -19,18 +26,40 @@ div.element {
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
div.logo img {
|
||||
padding:10px;
|
||||
max-height:40px;
|
||||
max-width:100px;
|
||||
}
|
||||
|
||||
div.round-button {
|
||||
opacity:0.6;
|
||||
cursor:pointer;
|
||||
margin:auto;
|
||||
font-size:2em;
|
||||
border:5px solid #fff;
|
||||
/*border:5px solid #fff;*/
|
||||
color:#fff;
|
||||
border-radius:100%;
|
||||
width:10vw;
|
||||
height:10vw;
|
||||
width:5vw;
|
||||
height:5vw;
|
||||
background:$primary;
|
||||
transition:1s;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
text-align: center;
|
||||
|
||||
animation-name: heartBeat;
|
||||
-webkit-animation-name: heartBeat;
|
||||
animation-duration: 1.5s;
|
||||
-webkit-animation-duration: 1.5s;
|
||||
animation-iteration-count: infinite;
|
||||
-webkit-animation-iteration-count: infinite;
|
||||
animation-delay: 3;
|
||||
-webkit-animation-delay: 3;
|
||||
}
|
||||
|
||||
div.round-button:hover {
|
||||
background:#fff;
|
||||
background-color:$backgroundhover;
|
||||
opacity:0.3;
|
||||
//transform:rotate(-90deg);
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { PlayerService } from '../player.service';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-init',
|
||||
@ -7,9 +9,15 @@ import { Component, OnInit } from '@angular/core';
|
||||
})
|
||||
export class InitComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
constructor(
|
||||
private playerService:PlayerService
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
// //document.documentElement.requestFullscreen();
|
||||
// screen.orientation.lock('landscape').then(null, function(error) {
|
||||
// console.error('orientation')
|
||||
// });
|
||||
}
|
||||
|
||||
}
|
||||
|
16
src/app/player.service.spec.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { PlayerService } from './player.service';
|
||||
|
||||
describe('PlayerService', () => {
|
||||
let service: PlayerService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(PlayerService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
219
src/app/player.service.ts
Normal file
@ -0,0 +1,219 @@
|
||||
import { Injectable,OnInit } from '@angular/core';
|
||||
import { Subject,Observable } from 'rxjs';
|
||||
import { ClientService } from './client.service';
|
||||
import { HttpClient,HttpResponse } from '@angular/common/http';
|
||||
import {environment} from '../environments/environment';
|
||||
|
||||
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class PlayerService {
|
||||
|
||||
audio:any;
|
||||
audio_paused:boolean = true;
|
||||
audio_stopped = true;
|
||||
audio_status = "init";
|
||||
|
||||
/* Playing */
|
||||
private _audio_is_playing = new Subject();
|
||||
public audio_is_playing$ = this._audio_is_playing.asObservable();
|
||||
audio_buffered;
|
||||
|
||||
/* Playlist */
|
||||
ListURL = environment.ListURL;
|
||||
ListIndex = 0;
|
||||
|
||||
/* Time */
|
||||
private _audio_current_time = new Subject();
|
||||
public audio_current_time$ = this._audio_current_time.asObservable();
|
||||
audio_duration;
|
||||
audio_elapsed;
|
||||
audio_position;
|
||||
|
||||
/* Player App */
|
||||
private _init_app = new Subject();
|
||||
init_app$ = this._init_app.asObservable();
|
||||
|
||||
/* Title */
|
||||
private _audio_title = new Subject();
|
||||
public audio_title$ = this._audio_title.asObservable();
|
||||
|
||||
audio_title;
|
||||
audio_id;
|
||||
audio_url;
|
||||
|
||||
constructor(
|
||||
private clientService:ClientService,
|
||||
private http:HttpClient
|
||||
) {
|
||||
this.audio = new Audio();
|
||||
this.audio_paused = true; //audio not playing
|
||||
this._audio_is_playing.next(this.audio_paused);
|
||||
this.audio_stopped = true;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
// https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
|
||||
//end audio play
|
||||
this.audio_status = "init"
|
||||
this.audio.onended = this.handleEnded.bind(this);
|
||||
this.audio.oncanplay= this.handledCanPlay.bind(this);
|
||||
|
||||
//play updates
|
||||
this.audio.ontimeupdate = this.handleTimeUpdate.bind(this);
|
||||
this.audio.onwaiting = this.handleWaiting.bind(this);
|
||||
this.audio.onloadedmetadata = this.handleLoadMetadata.bind(this);
|
||||
}
|
||||
|
||||
// JSON playlist environment config
|
||||
playList() {
|
||||
this.http.get<any>(this.ListURL).
|
||||
subscribe(
|
||||
(r) => {
|
||||
let data = r.data;
|
||||
if (data.length <= 0) { return }
|
||||
this.ListIndex = this.getRandomInt(data.length);
|
||||
if (this.ListIndex >= data.length) { this.ListIndex = 0 }
|
||||
if (!data[this.ListIndex]["title"]) {this.audio_title = "desde Beire"}
|
||||
else {this.audio_title = data[this.ListIndex]["title"]}
|
||||
this.playUrl(data[this.ListIndex]["url"],this.audio_title)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
playUrl(url,title) {
|
||||
|
||||
//if (title==this.audio_title) this.playList();
|
||||
|
||||
this.audio.src = url;
|
||||
this.audio_title = title;
|
||||
this.audio.load();
|
||||
this.audio.ontimeupdate = this.handleTimeUpdate.bind(this);
|
||||
this.audio.onloadstart = () => {this.audio_buffered = 0;}
|
||||
this.audio.onended = (url) => { this.ListIndex++; this.playList(); /* loop player */ };
|
||||
this.audio.onprogress = this.onProgress()
|
||||
|
||||
this.audio.oncanplay = () => {
|
||||
this._init_app.next(true);
|
||||
|
||||
|
||||
this.audio_paused=false;
|
||||
this._audio_is_playing.next(this.audio_paused);
|
||||
this._audio_title.next(this.audio_title);
|
||||
|
||||
|
||||
this.canPlay();
|
||||
};
|
||||
}
|
||||
|
||||
canPlay() {
|
||||
this.audio_status = "canplay";
|
||||
var a = this.audio.play();
|
||||
try {
|
||||
if (a!==undefined) {
|
||||
a.then(_ => {
|
||||
this.initPlayer(this.audio_title,this.audio_id);
|
||||
}).catch(error=>{
|
||||
console.log(error)
|
||||
console.log("not possible to play")
|
||||
// show play button!!!
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
/* firefox & old browsers not use Observale*/
|
||||
this.initPlayer(this.audio_title,this.audio_id);
|
||||
}
|
||||
}
|
||||
|
||||
initPlayer(title,id) {
|
||||
this.audio_title=title;
|
||||
this.audio_stopped = false;
|
||||
this.audio_paused = false;
|
||||
this.audio_id = id;
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.audio.onloadstart = null;
|
||||
this.audio.oncanplay = null
|
||||
this.audio.onprogress = null;
|
||||
this.audio.pause();
|
||||
this.audio_buffered=-1
|
||||
this.audio.currentTime = 0;
|
||||
this.audio.removeAttribute('src');
|
||||
this.audio.load();
|
||||
this.audio_paused = true;
|
||||
this.audio_stopped = true;
|
||||
this.audio_id = 0;
|
||||
this.audio_url="";
|
||||
}
|
||||
|
||||
mute() {
|
||||
if (this.audio.muted) { this.audio.muted=false } else { this.audio.muted=true}
|
||||
}
|
||||
|
||||
onProgress() {
|
||||
var duration = this.audio.duration;
|
||||
if (duration > 0) {
|
||||
for (var i=0; i<this.audio.buffered.length; i++) {
|
||||
if (this.audio.buffered.start(this.audio.buffered.length - 1 - i) < this.audio.currentTime) {
|
||||
this.audio_buffered = this.audio.buffered.end(this.audio.buffered.length-1);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//handleEvents
|
||||
handleStop() {
|
||||
this.stop();
|
||||
}
|
||||
|
||||
handleEnded(e) {
|
||||
this.stop();
|
||||
this.audio_status = "finish";
|
||||
}
|
||||
|
||||
handleTimeUpdate(e) {
|
||||
this.audio_status = "playing";
|
||||
let elapsed = this.audio.currentTime;
|
||||
let duration = this.audio.duration;
|
||||
|
||||
/* para pinchar un streaming */
|
||||
//if (duration == NaN || duration == Infinity || this.audio.src === environment.urlStream) duration=0;
|
||||
|
||||
if (elapsed) {
|
||||
this.audio_position = elapsed / duration;
|
||||
this.audio_elapsed = this.formatTime(elapsed);
|
||||
this.audio_duration = this.formatTime(duration);
|
||||
this._audio_current_time.next({currentTime: this.formatTime(elapsed), duration: this.formatTime(duration)});
|
||||
}
|
||||
}
|
||||
|
||||
handledCanPlay(e) {
|
||||
console.log(e)
|
||||
//play
|
||||
}
|
||||
|
||||
handleWaiting() {
|
||||
this.audio_status = "waiting";
|
||||
}
|
||||
|
||||
handleLoadMetadata(e) {
|
||||
console.log(e)
|
||||
}
|
||||
|
||||
/* utils */
|
||||
private formatTime(seconds) {
|
||||
let minutes:any = Math.floor(seconds / 60);
|
||||
minutes = (minutes >= 10) ? minutes : "0" + minutes;
|
||||
seconds = Math.floor(seconds % 60);
|
||||
seconds = (seconds >= 10) ? seconds : "0" + seconds;
|
||||
return minutes + ":" + seconds;
|
||||
}
|
||||
|
||||
private getRandomInt(max) {
|
||||
return Math.floor(Math.random() * Math.floor(max));
|
||||
}
|
||||
}
|
@ -1,14 +1,59 @@
|
||||
<div class="slide" *ngIf="slide" [ngStyle]="{'background-image':'url('+getFeaturedImage()+')'}">
|
||||
<ng-container *ngIf="!showInit">
|
||||
|
||||
<div class="slide" *ngIf="slide" [ngStyle]="{'background-image':'url('+getFeaturedImage()+')'}" (click)="playUrl()">
|
||||
<div class="content">
|
||||
<div class="element big-title" [innerHTML]="slide.title"></div>
|
||||
<div class="element logo" *ngIf="slide.name=='about'">
|
||||
<a href="http://www.landarte.es/"><img style="max-height:60px;" src="assets/img/landarte_logo.png"/></a>
|
||||
</div>
|
||||
<div *ngIf="slide.name!='about' && audio_title!=slide.title" class="element big-title" [innerHTML]="slide.title"></div>
|
||||
<div class="element big-title" *ngIf="audio_title==slide.title && currentTime && duration!='00:00'" (click)="play()">{{currentTime}}</div>
|
||||
<div class="element second-title" [innerHTML]="slide.content"></div>
|
||||
<div class="element logo" *ngIf="slide.name=='home'"><img style="padding-top:30px;max-width:100px;" src="assets/img/landarte_logo.png"/></div>
|
||||
<div class="element logo" *ngIf="slide.name=='about'">
|
||||
<a href="http://www.culturanavarra.es/"><img src="assets/img/logoCK.png"/></a>
|
||||
<a href="http://www.navarra.es/"><img src="assets/img/navarra.png"/></a>
|
||||
</div>
|
||||
<div class="element logo" *ngIf="slide.name=='about'">
|
||||
<a href="https://www.beire.es/"><img src="assets/img/logoBeire.png"/></a>
|
||||
<a href="http://soinumapa.net"><img src="assets/img/logoSoinumapa.png" style="max-width:80px;"/></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="controls" *ngIf="slide">
|
||||
<div class="left control"><div class="arrow" [id]="slide.o" (click)="left($event)"><img src="assets/img/left.svg"/></div></div>
|
||||
<div class="right control"><div class="arrow" [id]="slide.e" (click)="right($event)"><img src="assets/img/right.svg"/></div></div>
|
||||
<div class="top control"><div class="arrow" [id]="slide.n" (click)="up($event)"><img src="assets/img/top.svg"/></div></div>
|
||||
<div class="bottom control"><div class="arrow" [id]="slide.s" (click)="down($event)"><img src="assets/img/down.svg"/></div></div>
|
||||
<div *ngIf="slide.o" class="left control"><div class="arrow" [id]="slide.o" (click)="left($event)"><img src="assets/img/left.svg"/></div></div>
|
||||
<div *ngIf="slide.e" class="right control end"><div class="arrow" [id]="slide.e" (click)="right($event)"><img src="assets/img/right.svg"/></div></div>
|
||||
<div *ngIf="slide.n" class="top control"><div class="arrow" [id]="slide.n" (click)="up($event)"><img src="assets/img/top.svg"/></div></div>
|
||||
<div *ngIf="slide.s" class="bottom control"><div class="arrow" [id]="slide.s" (click)="down($event)"><img src="assets/img/down.svg"/></div></div>
|
||||
</div>
|
||||
|
||||
<div class="header">
|
||||
<h1 routerLink="/home">Beire </h1>
|
||||
</div>
|
||||
|
||||
<div class="header menu">
|
||||
<h1 routerLink="/about" *ngIf="slide && slide.name!='about'">+</h1>
|
||||
</div>
|
||||
|
||||
<div class="footer player">
|
||||
<span class="mute" (click)="mute()" [ngClass]="{'muted': muted}">mute</span>
|
||||
<span class="audioElement audioTimer" *ngIf="currentTime && duration!='00:00'">{{currentTime}}<ng-container *ngIf="duration!='00:00'">/{{duration}}</ng-container></span>
|
||||
</div>
|
||||
|
||||
<div class="footer right">
|
||||
<span class="audioElement"[innerHTML]="'Escuchando '+audio_title"></span>
|
||||
</div>
|
||||
|
||||
<div class="video-player" [ngStyle]="{'display':showVideo }" (click)="stopVideo()">
|
||||
<div id="video-player-content" (click)="stopVideo()"></div>
|
||||
</div>
|
||||
|
||||
</ng-container>
|
||||
|
||||
<div *ngIf="showInit" class="slide init-slide" style="background-image:url('/assets/img/trailer.gif');" (click)="forcePlay()">
|
||||
<div class="element">
|
||||
<!-- <h1 routerLink="home" style="cursor:pointer">Beire</h1> -->
|
||||
<!-- <h2>Un propuesta de Maite Redondo y Luca Rullo</h2> -->
|
||||
<!-- <div class="round-button" title="Pulsa para iniciar" routerLink="home" (click)="play()"></div> -->
|
||||
<!-- <h3>Con la ayuda de Pedro, María, Luis, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre,Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre, Nombre </h3> -->
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,48 +1,141 @@
|
||||
@import "../../_variables.scss";
|
||||
|
||||
div.slide {
|
||||
color:#fff;
|
||||
color:$primary;
|
||||
width:100vw;
|
||||
height:100vh;
|
||||
background-size:cover;
|
||||
background-color:#f90;
|
||||
background-blend-mode: luminosity;
|
||||
background-color:$slide-background;
|
||||
// background-blend-mode: luminosity;
|
||||
filter:grayscale(1);
|
||||
background-position: center center;
|
||||
display:flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
overflow:crosshair;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
div.slide.init-slide {
|
||||
background-size:cover;
|
||||
background-position:center center;
|
||||
position:absolute;
|
||||
background-repeat: no-repeat;
|
||||
z-index:2000;
|
||||
top:0;
|
||||
left:0;
|
||||
filter:none;
|
||||
}
|
||||
|
||||
div.element {
|
||||
width:50vw;
|
||||
margin:auto;
|
||||
text-align:center;
|
||||
text-align:justify;
|
||||
}
|
||||
|
||||
div.big-title {
|
||||
font-family:"Staatliches",sans-serif;
|
||||
font-size:10rem;
|
||||
opacity:0.6;
|
||||
font-weight: bold;
|
||||
font-family:"Helvetica Bold",sans-serif;
|
||||
// font-size:2vw;
|
||||
font-size:calc(12px + 2vw);
|
||||
color:$primary;
|
||||
opacity:1;
|
||||
max-width: 100px;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
div.second-title {
|
||||
font-size:3rem;
|
||||
font-family:"Reenie Beanie",serif;
|
||||
font-size:1.2vmax;
|
||||
font-family:"Helvetica",serif;
|
||||
overflow-wrap:break-word;
|
||||
text-align:justify;
|
||||
a { text-decoration:none; font-weight:bold;}
|
||||
}
|
||||
|
||||
/* controls */
|
||||
div.controls{
|
||||
div.control {position:absolute;z-index:100;width:10vw;height:20vh;display:flex;justify-content: center; align-items: center;}
|
||||
div.left { top:0;left:0;height:100vh; }
|
||||
div.right { top:0;right:0;height:100vh; }
|
||||
div.top { top:0;left:0;width:100vw; }
|
||||
div.bottom { bottom:0;left:0;width:100vw; }
|
||||
div.control {
|
||||
position:absolute;
|
||||
z-index:100;
|
||||
width:22vw;
|
||||
height:18vh;
|
||||
display:flex;justify-content: center; align-items: center;}
|
||||
div.left { top:0;left:4.5vw;height:100vh;max-width:80px; }
|
||||
div.right { top:0;right:4.5vw;height:100vh;max-width:80px; }
|
||||
div.top { top:5.5vh;left:0;width:100vw;padding-top:2vh;max-height:80px; }
|
||||
div.bottom { bottom:6vh;left:0;width:100vw;max-height:80px; }
|
||||
}
|
||||
|
||||
div.controls.end {
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
div.arrow {
|
||||
display:inline-flex;
|
||||
cursor:pointer;
|
||||
min-width:75px;
|
||||
min-height:75px;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
text-align: center;
|
||||
// font-size:2vw;
|
||||
font-size:calc(12px + 2vw);
|
||||
font-weight:bold;
|
||||
div.rotate-up { transform:rotate(90deg);}
|
||||
div.rotate-down { transform:rotate(-90deg);}
|
||||
img { max-width:60px; max-height:60px; margin:auto;}
|
||||
}
|
||||
|
||||
/* header */
|
||||
div.header {
|
||||
h1 { font-size:calc(12px + 2vw); cursor:pointer;}
|
||||
color:$primary;
|
||||
position:absolute;z-index:200;top:0;left:0;height:10vh;
|
||||
// width:100vw;
|
||||
max-width:100%;
|
||||
text-align:left;margin-left:5vw;margin-top:3vw;
|
||||
}
|
||||
|
||||
.muted { opacity:0.6; text-decoration:line-through;;}
|
||||
.audioElement { margin:0 20px;
|
||||
@media screen and (max-width: $breakpoint-phone) { display:none;}
|
||||
}
|
||||
|
||||
div.footer {
|
||||
overflow:hidden;
|
||||
color:$primary;
|
||||
position:absolute;z-index:200;bottom:0;left:0;height:10vh;
|
||||
max-width:50%;
|
||||
text-align:left;margin-left:5vw;margin-top:3vw;
|
||||
span.mute { cursor:pointer;}
|
||||
}
|
||||
|
||||
div.footer.right {
|
||||
left:auto;
|
||||
right:0;
|
||||
}
|
||||
div.menu {
|
||||
z-index:200;cursor:pointer;left:auto;
|
||||
right:0;padding-right:5vw;
|
||||
}
|
||||
|
||||
|
||||
div.video-player {
|
||||
position:absolute;
|
||||
width:100vw;
|
||||
height:100vh;
|
||||
z-index:300;
|
||||
align-items: center;
|
||||
display:flex;
|
||||
background:rgba(0,0,0,0.5);
|
||||
top:0;
|
||||
* { margin:auto;}
|
||||
#video-player-content { max-width:100%; max-height:100%; display:inherit; }
|
||||
}
|
||||
|
||||
/** logo **/
|
||||
div.logo img {
|
||||
padding:10px;
|
||||
max-height:40px;
|
||||
max-width:200px;
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
|
||||
import { ClientService } from '../client.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import {environment} from '../../environments/environment';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
|
||||
|
||||
import { PlayerService } from '../player.service';
|
||||
import Player from '@vimeo/player';
|
||||
|
||||
|
||||
@Component({
|
||||
@ -15,16 +15,50 @@ import { ActivatedRoute, Router } from '@angular/router';
|
||||
export class SlideComponent implements OnInit {
|
||||
|
||||
slide: any;
|
||||
muted:boolean = false;
|
||||
showInit:boolean = true;
|
||||
|
||||
/*player info*/
|
||||
duration=""
|
||||
currentTime=""
|
||||
audio_title="Streaming from Beire"
|
||||
|
||||
/* video player */
|
||||
showVideo = "none";
|
||||
videoPlayer:any;
|
||||
_videoID:string;
|
||||
//@ViewChild('vimeoPlayer') vimeoPlayer: ElementRef;
|
||||
|
||||
constructor(
|
||||
private clientService:ClientService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
) {}
|
||||
private playerService:PlayerService,
|
||||
) {
|
||||
|
||||
/* subscribe timer */
|
||||
playerService.audio_current_time$
|
||||
.subscribe(
|
||||
(res:any) => {
|
||||
this.duration = res.duration;
|
||||
this.currentTime = res.currentTime;
|
||||
}
|
||||
)
|
||||
|
||||
playerService.audio_title$
|
||||
.subscribe(
|
||||
(res:any) => {
|
||||
this.audio_title = res;
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
// play stream
|
||||
this.play();
|
||||
|
||||
document.addEventListener('keydown', (e) => { this.onKeydown(e) });
|
||||
//document.addEventListener('keydown', (e) => { console.log(e)})
|
||||
|
||||
this.route.params.subscribe(
|
||||
params => {
|
||||
@ -38,6 +72,39 @@ export class SlideComponent implements OnInit {
|
||||
|
||||
}
|
||||
|
||||
getVideoId():string {
|
||||
return this._videoID;
|
||||
}
|
||||
|
||||
showVideoVimeo(id:string) {
|
||||
|
||||
var options = {loop: false, id: id, responsive: false, autoplay: true};
|
||||
|
||||
if (this.videoPlayer && this.getVideoId() != id) { this.videoPlayer = this.videoPlayer.destroy();}
|
||||
else if ( this.getVideoId() == id ) {
|
||||
//this.videoPlayer.requestFullscreen();
|
||||
}
|
||||
|
||||
this.videoPlayer = new Player('video-player-content', options);
|
||||
this.showVideo = "flex"
|
||||
this.videoPlayer.on('play', () => {
|
||||
this._videoID = id;
|
||||
this.videoPlayer.getFullscreen().then( (f) => {
|
||||
//if (!f) { this.videoPlayer.requestFullscreen(); }
|
||||
});
|
||||
}
|
||||
);
|
||||
this.videoPlayer.on('ended', () => { this.stopVideo(); });
|
||||
this.videoPlayer.on('fullscreenchange', (data) => { if (!data.fullscreen) { this.stopVideo(); } })
|
||||
}
|
||||
|
||||
stopVideo() {
|
||||
this.videoPlayer.pause().then( () => {
|
||||
this.mute(); //unmute
|
||||
this.showVideo = "none";
|
||||
});
|
||||
}
|
||||
|
||||
getFeaturedImage(): string {
|
||||
return environment.uriAPI+"items/"+this.slide.name+"/"+this.slide.featuredImage;
|
||||
}
|
||||
@ -48,7 +115,6 @@ export class SlideComponent implements OnInit {
|
||||
//ArrowRight
|
||||
//ArrowUp
|
||||
//ArrowDown
|
||||
console.log(e)
|
||||
switch (e.code) {
|
||||
case "ArrowLeft" :
|
||||
this.left(e);
|
||||
@ -60,12 +126,37 @@ export class SlideComponent implements OnInit {
|
||||
this.up(e); break;
|
||||
case "ArrowDown" :
|
||||
this.down(e); break;
|
||||
case "Space" :
|
||||
this.playUrl(); break;
|
||||
}
|
||||
}
|
||||
|
||||
left(e) { this.router.navigate(['/', this.slide.o]);}
|
||||
right(e) { this.router.navigate(['/', this.slide.e]); }
|
||||
up(e) { this.router.navigate(['/', this.slide.n]); }
|
||||
down(e) { this.router.navigate(['/', this.slide.s]); }
|
||||
left(e) { if (this.slide.o) this.router.navigate(['/', this.slide.o]);}
|
||||
right(e) { if (this.slide.e) this.router.navigate(['/', this.slide.e]); }
|
||||
up(e) { if (this.slide.n) this.router.navigate(['/', this.slide.n]); }
|
||||
down(e) { if (this.slide.s) this.router.navigate(['/', this.slide.s]); }
|
||||
|
||||
mute() {
|
||||
this.playerService.mute();
|
||||
this.muted = !this.muted;
|
||||
}
|
||||
|
||||
play() {
|
||||
this.playerService.playList()
|
||||
}
|
||||
|
||||
playUrl() {
|
||||
/* stop audio */
|
||||
if (this.slide.title === this.audio_title) { this.playerService.playList() }
|
||||
/* playVideo */
|
||||
if (this.slide.featuredVideo) { this.mute(); this.showVideoVimeo(this.slide.featuredVideo); }
|
||||
/* playAudio */
|
||||
else if (this.slide.featuredAudio) { this.playerService.playUrl(this.slide.featuredAudio, this.slide.title); }
|
||||
}
|
||||
|
||||
forcePlay() {
|
||||
this.showInit = false;
|
||||
this.play();
|
||||
}
|
||||
|
||||
}
|
||||
|
BIN
src/assets/font/FrutigerLTStd-Cn.otf
Normal file
BIN
src/assets/font/HelvFE Bold.ttf
Normal file
BIN
src/assets/font/HelvFE-Bold.otf
Normal file
BIN
src/assets/font/HelvLight Regular.ttf
Normal file
BIN
src/assets/font/HelveticaWorld-Bold.ttf
Normal file
BIN
src/assets/font/swissboldcondensed.woff2
Normal file
BIN
src/assets/font/swisslight.woff2
Normal file
BIN
src/assets/img/logoBeire.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
src/assets/img/logoCK.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
src/assets/img/logoEscuelaMusicaOlite.jpg
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
src/assets/img/logoSoinumapa.png
Normal file
After Width: | Height: | Size: 9.6 KiB |
BIN
src/assets/img/navarra.png
Normal file
After Width: | Height: | Size: 142 KiB |
BIN
src/assets/img/trailer.gif
Executable file
After Width: | Height: | Size: 14 MiB |
7
src/assets/playlist.json
Normal file
@ -0,0 +1,7 @@
|
||||
{ "data" : [
|
||||
{"title":"Traktorea", "url":"https://www.soinumapa.net/wp-content/uploads/2020/10/20201017_TRACTOR_ARANDO.mp3"},
|
||||
{"title":"Kanpaiak", "url":"https://www.soinumapa.net/wp-content/uploads/2020/10/20201017_BEIRE_CAMPANAS_EDIT.mp3"},
|
||||
{"title":"Erlezaintza", "url":"https://www.soinumapa.net/wp-content/uploads/2020/10/20200909_ABEJAS_COMER_APICULTOR_DIA_BEIRE_ARGUEDAS.mp3"},
|
||||
{"title":"Uxue Santutegia", "url":"https://www.soinumapa.net/wp-content/uploads/2020/10/20200912_INTERIOR_IGLESIA_PUERTA_UJUE_EDITED.mp3"}
|
||||
]
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
export const environment = {
|
||||
production: true
|
||||
production: true,
|
||||
uriAPI: "https://public.audio-lab.org/beireapi/",
|
||||
ListURL: "https://beire.soinumapa.net/assets/playlist.json"
|
||||
};
|
||||
|
@ -4,7 +4,8 @@
|
||||
|
||||
export const environment = {
|
||||
production: false,
|
||||
uriAPI: "https://public.audio-lab.org/beireapi/"
|
||||
uriAPI: "https://public.audio-lab.org/beireapi/",
|
||||
ListURL: "http://localhost:4200/assets/playlist.json"
|
||||
};
|
||||
|
||||
/*
|
||||
|
BIN
src/favicon.ico
Before Width: | Height: | Size: 948 B After Width: | Height: | Size: 2.0 KiB |
@ -2,10 +2,14 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>BeireFrontend</title>
|
||||
<title>Beire - Una propuesta de Maite Redondo y Luca Rullo</title>
|
||||
<base href="/">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<meta name="description" content="Una propuesta de Maite Redondo y Luca Rullo para el programa Landarte, Cultura contemporánea y ruralidad. Con la ayuda de JESUSA — PAZ — LOLA — JUANA — CATALINA — ARACELI — YASMIN — ANGÉLICA — MIREN — NAIARA — NOA — TERE — AMAYA — IDOIA — PATRICIA — DAVID — LUIS MARI — PAULA — DAVID — JUAN — MARI CARMEN — AINARA — MARGARITA RUBIO — FERMINA [BURRA] — AZAHARA — ASIER — JUDITH — MARKEL — ION — NIEZYELA — SAAD — ALICIA — OIHANE — JOAQUIN — JAVIER GORRIA — ALFONSO — MARI — PEPÍN — BERTA — JOSÉ PIERRE — BRUNO — VIRGINIA — POLI — VALENTÍN — CHARO — CECILIA — FERMINA — FLAVIO — CASINO DE BEIRE — MARI — PEDRO LUIS — HILDA — BAR BARIAIN — ANGÉLICA — MARGARITA ONGAY — VICTOR — EDUARDO — CARLOS — IGNACIO — ESCALERAS ARIZONA — ESCUELA DE MÚSICA DE OLITE — GERMÁN — JAVIER CLEMENTE — AMETS — MIKEL — GARAZI — PERU — NURIA — JON — ANNE — MARC">
|
||||
<meta name="keywords" content="beire, landarte, navarra, nafarroa, cultura, documental, interactivo, documentary, interactive, maite redondo, luca rullo">
|
||||
<meta name="author" content="Maite Redondo y Luca Rullo">
|
||||
<link rel="manifest" href="manifest.json" />
|
||||
</head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
|
4
src/manifest.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"display": "standalone",
|
||||
"orientation": "landscape-primary"
|
||||
}
|
128
src/styles.scss
@ -1,10 +1,132 @@
|
||||
/* You can add global styles to this file, and also import other style files */
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Raleway&family=Reenie+Beanie&family=Staatliches&display=swap');
|
||||
//@import url('https://fonts.googleapis.com/css2?family=Raleway&family=Reenie+Beanie&family=Staatliches&display=swap');
|
||||
@import './_variables.scss';
|
||||
|
||||
@font-face{
|
||||
font-family:"Swiss Bold";
|
||||
src:url('assets/font/swissboldcondensed.woff2');
|
||||
}
|
||||
|
||||
@font-face{
|
||||
font-family:"Swiss Light";
|
||||
src:url('assets/font/swisslight.woff2');
|
||||
}
|
||||
|
||||
@font-face{
|
||||
font-family:"Helvetica";
|
||||
src:url('assets/font/HelvLight Regular.ttf');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family:"Helvetica Bold";
|
||||
src:url('assets/font/HelveticaWorld-Bold.ttf');
|
||||
}
|
||||
|
||||
@font-face{
|
||||
font-family:"Frutiger";
|
||||
src:url('assets/font/FrutigerLTStd-Cn.otf');
|
||||
}
|
||||
|
||||
body {
|
||||
margin:0;
|
||||
padding:0;
|
||||
background-color:#1c1c1c;
|
||||
cursor:none;
|
||||
background-color:$background-color;
|
||||
cursor:crosshair;
|
||||
font-family:"Frutiger";
|
||||
}
|
||||
|
||||
*:focus{
|
||||
outline: none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
// font-family:"Staatliches",sans-serif;
|
||||
text-transform:uppercase;
|
||||
font-family:"Frutiger";
|
||||
font-weight:100;
|
||||
font-size:2vw;
|
||||
// opacity:0.6;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size:3vw;
|
||||
font-family:"Frutiger",serif;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-family:"Frutiger";
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration:none;
|
||||
font-weight:bold;
|
||||
color:$primary;
|
||||
}
|
||||
|
||||
|
||||
/* animations css */
|
||||
|
||||
@keyframes heartBeat {
|
||||
0% {
|
||||
transform: scale(none);
|
||||
-webkit-transform: scale(none);
|
||||
}
|
||||
|
||||
20% {
|
||||
transform: scale(1.2);
|
||||
-webkit-transform: scale(1.2);
|
||||
}
|
||||
|
||||
30% {
|
||||
transform: scale(1.05);
|
||||
-webkit-transform: scale(1.05);
|
||||
}
|
||||
|
||||
45% {
|
||||
transform: scale(1.25);
|
||||
-webkit-transform: scale(1.25);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(none);
|
||||
-webkit-transform: scale(none);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(none);
|
||||
-webkit-transform: scale(none);
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes heartBeat {
|
||||
0% {
|
||||
transform: scale(none);
|
||||
-webkit-transform: scale(none);
|
||||
}
|
||||
|
||||
20% {
|
||||
transform: scale(1.2);
|
||||
-webkit-transform: scale(1.2);
|
||||
}
|
||||
|
||||
30% {
|
||||
transform: scale(1.05);
|
||||
-webkit-transform: scale(1.05);
|
||||
}
|
||||
|
||||
45% {
|
||||
transform: scale(1.25);
|
||||
-webkit-transform: scale(1.25);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(none);
|
||||
-webkit-transform: scale(none);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(none);
|
||||
-webkit-transform: scale(none);
|
||||
}
|
||||
}
|
||||
|