| @@ -12,8 +12,14 @@ | |||
| </div> | |||
| <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> | |||
| </ul> | |||
| @@ -55,6 +61,29 @@ | |||
| </div> | |||
| </li> | |||
| </ul> | |||
| </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> | |||
| @@ -65,8 +65,201 @@ | |||
| .stories { | |||
| display: inline-block; | |||
| list-style: none; | |||
| padding: 0 5%; | |||
| margin: 20px 0; | |||
| white-space: nowrap; | |||
| overflow-x: auto; | |||
| overflow-y: hidden; | |||
| 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({ | |||
| selector: 'app-fan-zone', | |||
| @@ -6,15 +7,37 @@ import { Component, OnInit } from '@angular/core'; | |||
| styleUrls: ['./fan-zone.page.scss'], | |||
| }) | |||
| 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<{ | |||
| profileImage: string, | |||
| name: string, | |||
| storyImage: string, | |||
| 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() { } | |||
| ngOnInit() { | |||
| @@ -30,9 +53,38 @@ export class FanZonePage implements OnInit { | |||
| likeCount: 230, | |||
| 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', | |||
| 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; | |||
| }); | |||
| } | |||
| } | |||