| @@ -12,8 +12,14 @@ | |||||
| </div> | </div> | ||||
| <ul class="stories"> | <ul class="stories"> | ||||
| <li *ngFor="let story of fanStories" [ngClass]="{'active' : !story.opened }"> | |||||
| {{ story.profileImage }} | |||||
| <li> | |||||
| <ion-icon name="add-circle-outline"></ion-icon> | |||||
| <span> Add Story </span> | |||||
| </li> | |||||
| <li *ngFor="let story of fanStories; let i = index" [ngClass]="{'inactive' : story.opened }" | |||||
| (click)="showSlides = true; story.opened = true; goToSlide(i)"> | |||||
| <img [src]="story.profileImage"> | |||||
| <span> {{ story.name }} </span> | |||||
| </li> | </li> | ||||
| </ul> | </ul> | ||||
| @@ -55,6 +61,29 @@ | |||||
| </div> | </div> | ||||
| </li> | </li> | ||||
| </ul> | </ul> | ||||
| </div> | </div> | ||||
| <ion-slides #slides [options]="slideOpts" class="story-slides" [ngClass]="{'active' : showSlides }" | |||||
| (ionSlideDidChange)="updateStory()"> | |||||
| <ion-slide *ngFor="let story of fanStories" [ngStyle]="{'background-image': 'url(' + story.storyImage + ')' }"> | |||||
| <header> | |||||
| <h5> <img [src]="story.profileImage"> {{ story.name }} </h5> | |||||
| <button (click)="showSlides = false"> <ion-icon name="close-outline"></ion-icon> </button> | |||||
| </header> | |||||
| <div class="emoji-buffer" [ngClass]="{'active' : selectedEmoji }"> | |||||
| <img *ngFor="let emoji of emojiBuffer" [src]="emoji.emoji" | |||||
| [ngStyle]="{'left.%' : emoji.positionX, 'top.%' : emoji.positionY, 'width.px' : emoji.size}"> | |||||
| </div> | |||||
| <section class="action-buttons"> | |||||
| <button *ngFor="let emoji of emojis" | |||||
| (click)="selectedEmoji = emoji; generateEmojiStream()"> <img [src]="emoji"> </button> | |||||
| <button> <ion-icon name="share-social-outline"></ion-icon> </button> | |||||
| </section> | |||||
| </ion-slide> | |||||
| </ion-slides> | |||||
| </ion-content> | </ion-content> | ||||
| @@ -65,8 +65,201 @@ | |||||
| .stories { | .stories { | ||||
| display: inline-block; | display: inline-block; | ||||
| list-style: none; | |||||
| padding: 0 5%; | |||||
| margin: 20px 0; | |||||
| white-space: nowrap; | |||||
| overflow-x: auto; | |||||
| overflow-y: hidden; | |||||
| li { | li { | ||||
| margin-right: 15px; | |||||
| display: inline-block; | |||||
| &.inactive img { | |||||
| background-color: $blue-grey; | |||||
| } | |||||
| img { | |||||
| border-radius: 50%; | |||||
| width: 50px; | |||||
| height: 50px; | |||||
| margin: 0 auto; | |||||
| display: block; | |||||
| background-color: $pink; | |||||
| padding: 2px; | |||||
| object-fit: contain; | |||||
| } | |||||
| ion-icon { | |||||
| width: 50px; | |||||
| height: 50px; | |||||
| display: block; | |||||
| color: $pink; | |||||
| margin: 0 auto; | |||||
| } | |||||
| span { | |||||
| display: block; | |||||
| margin-top: 7px; | |||||
| color: $blue-grey; | |||||
| font-size: 0.9rem; | |||||
| text-align: center; | |||||
| } | |||||
| } | |||||
| } | |||||
| .story-slides { | |||||
| position: fixed; | |||||
| top: 0; | |||||
| z-index: 1; | |||||
| height: calc(100vh - 55px); | |||||
| width: 100%; | |||||
| transform: scale(0); | |||||
| transition: transform 0.3s; | |||||
| &.active { | |||||
| transform: scale(1); | |||||
| } | |||||
| ion-slide { | |||||
| display: block; | |||||
| overflow: hidden; | |||||
| height: 100%; | |||||
| position: relative; | |||||
| transition: transform 0.3s; | |||||
| box-shadow: 10px 10px 15px -7px darken($dark-blue, 10%); | |||||
| width: 100%; | |||||
| background-color: rgba(black, 0.9); | |||||
| background-size: cover; | |||||
| background-repeat: no-repeat; | |||||
| background-position: center; | |||||
| overflow: hidden; | |||||
| } | |||||
| header { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: space-between; | |||||
| background-color: rgba(black, 0.8); | |||||
| padding: 10px 15px; | |||||
| h5 { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: flex-start; | |||||
| color: $blue-grey; | |||||
| font-size: 1rem; | |||||
| margin: 0; | |||||
| img { | |||||
| width: 30px; | |||||
| height: 30px; | |||||
| border-radius: 50%; | |||||
| background-color: $blue-grey; | |||||
| padding: 1px; | |||||
| object-fit: contain; | |||||
| margin-right: 10px; | |||||
| } | |||||
| } | |||||
| button { | |||||
| width: 40px; | |||||
| height: 40px; | |||||
| border-radius: 50%; | |||||
| border: 1px solid $blue-grey; | |||||
| background-color: transparent; | |||||
| color: $blue-grey; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| font-size: 20px; | |||||
| } | |||||
| } | |||||
| .action-buttons { | |||||
| position: absolute; | |||||
| left: 0; | |||||
| bottom: 20px; | |||||
| width: 70%; | |||||
| margin-left: 15%; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: space-between; | |||||
| padding: 10px; | |||||
| background-color: rgba(black, 0.6); | |||||
| border-radius: 30px; | |||||
| z-index: 1; | |||||
| button { | |||||
| width: 40px; | |||||
| height: 40px; | |||||
| border-radius: 50%; | |||||
| border: 1px solid rgba($blue-grey, 0.6); | |||||
| background-color: transparent; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| img { | |||||
| width: 20px; | |||||
| } | |||||
| ion-icon { | |||||
| color: white; | |||||
| font-size: 20px; | |||||
| } | |||||
| } | |||||
| } | |||||
| .emoji-buffer { | |||||
| position: absolute; | |||||
| left: 0; | |||||
| top: 70px; | |||||
| height: 90%; | |||||
| width: 100%; | |||||
| transform: translateY(10vh); | |||||
| &.active { | |||||
| animation: riseUp 2s forwards linear; | |||||
| } | |||||
| @keyframes riseUp { | |||||
| 0% { | |||||
| transform: translateY(20vh); | |||||
| } | |||||
| 50% { | |||||
| transform: translateY(0); | |||||
| } | |||||
| 100% { | |||||
| opacity: 0; | |||||
| transform: translateY(-20vh); | |||||
| } | |||||
| } | |||||
| img { | |||||
| position: absolute; | |||||
| left: 0; | |||||
| top: 0; | |||||
| width: 30px; | |||||
| animation: bigSmall 1s infinite linear; | |||||
| } | |||||
| @keyframes bigSmall { | |||||
| 0% { | |||||
| transform: scale(1); | |||||
| } | |||||
| 25% { | |||||
| transform: scale(1.2); | |||||
| } | |||||
| 50% { | |||||
| transform: scale(0.9); | |||||
| } | |||||
| 100% { | |||||
| transform: scale(1); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -1,4 +1,5 @@ | |||||
| import { Component, OnInit } from '@angular/core'; | |||||
| import { Component, OnInit, ViewChild } from '@angular/core'; | |||||
| import { IonSlides } from '@ionic/angular'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-fan-zone', | selector: 'app-fan-zone', | ||||
| @@ -6,15 +7,37 @@ import { Component, OnInit } from '@angular/core'; | |||||
| styleUrls: ['./fan-zone.page.scss'], | styleUrls: ['./fan-zone.page.scss'], | ||||
| }) | }) | ||||
| export class FanZonePage implements OnInit { | export class FanZonePage implements OnInit { | ||||
| @ViewChild('slides') slides: IonSlides; | |||||
| emojis = ['assets/icons/emojis/heart.png', 'assets/icons/emojis/laughing.png', 'assets/icons/emojis/surprised.png', 'assets/icons/emojis/thumb-up.png']; | |||||
| showSlides: boolean = false; | |||||
| fanStories: Array<{ | fanStories: Array<{ | ||||
| profileImage: string, | profileImage: string, | ||||
| name: string, | name: string, | ||||
| storyImage: string, | storyImage: string, | ||||
| likeCount: number, | likeCount: number, | ||||
| opened: boolean | |||||
| opened: boolean, | |||||
| }>; | }>; | ||||
| selectedEmoji: string = ''; | |||||
| emojiBuffer: Array<{ | |||||
| emoji: string, | |||||
| positionX: number, | |||||
| positionY: number, | |||||
| size: number, | |||||
| }> = []; | |||||
| slideOpts = { | |||||
| slidesPerView: 1, | |||||
| initialSlide: 0, | |||||
| centeredSlides: true, | |||||
| // simulateTouch: false, | |||||
| // followFinger: false, | |||||
| }; | |||||
| constructor() { } | constructor() { } | ||||
| ngOnInit() { | ngOnInit() { | ||||
| @@ -30,9 +53,38 @@ export class FanZonePage implements OnInit { | |||||
| likeCount: 230, | likeCount: 230, | ||||
| profileImage: 'https://m.media-amazon.com/images/M/MV5BMmNkMjNkZmEtYWNhYS00ZjI0LTkzZTktZmViODI1NmI0ZmMyXkEyXkFqcGdeQXVyMTM1ODM2MjM@._V1_UY317_CR130,0,214,317_AL_.jpg', | profileImage: 'https://m.media-amazon.com/images/M/MV5BMmNkMjNkZmEtYWNhYS00ZjI0LTkzZTktZmViODI1NmI0ZmMyXkEyXkFqcGdeQXVyMTM1ODM2MjM@._V1_UY317_CR130,0,214,317_AL_.jpg', | ||||
| storyImage: 'https://i.pinimg.com/originals/dd/78/64/dd78643b1b2980bcfa83daa2d188fa91.jpg', | storyImage: 'https://i.pinimg.com/originals/dd/78/64/dd78643b1b2980bcfa83daa2d188fa91.jpg', | ||||
| opened: false | |||||
| }] | |||||
| opened: false, | |||||
| }]; | |||||
| } | |||||
| generateEmojiStream() { | |||||
| this.emojiBuffer = []; | |||||
| for (let i = 0; i < 150; i += 1) { | |||||
| this.emojiBuffer.push({ | |||||
| emoji: this.selectedEmoji, | |||||
| positionX: Math.floor((Math.random()) * 100), | |||||
| positionY: Math.floor((Math.random()) * 100), | |||||
| size: Math.floor((Math.random()) * 60), | |||||
| }); | |||||
| } | |||||
| setTimeout(() => { | |||||
| this.selectedEmoji = ''; | |||||
| this.emojiBuffer = []; | |||||
| }, 2100); | |||||
| } | |||||
| goToSlide(index: number) { | |||||
| this.slides.slideTo(index); | |||||
| } | |||||
| updateStory() { | |||||
| this.slides.getActiveIndex().then((index) => { | |||||
| this.fanStories[index].opened = true; | |||||
| }); | |||||
| } | } | ||||
| } | } | ||||