@@ -8,9 +8,11 @@ | |||
<canvas id="result-canvas" #canvasElement width="{{ width }}" height="{{ height }}"></canvas> | |||
</div> | |||
<img [src]="temp" *ngIf="temp" #temp class="test-img" width="100px" height="100px" alt=""> | |||
<section class="temp-image" [ngClass]="{'active' : tempImg }"> | |||
<img *ngIf="tempImg" src="{{ tempImg }}"> | |||
</section> | |||
<div class="action-buttons"> | |||
<div class="action-buttons" *ngIf="!tempImg"> | |||
<!-- <button *ngIf="areNeuralNetsLoaded" (click)="stopCameraStream()">Stop stream</button> --> | |||
<!-- <button *ngIf="areNeuralNetsLoaded" (click)="toggleDetection()">{{ isDetecting ? 'Stop detection' : 'Detect and draw' }}</button> --> | |||
@@ -19,4 +21,11 @@ | |||
<button class="skin-button" *ngIf="areNeuralNetsLoaded" (click)="toggleDetection()" | |||
[ngClass]="{'active' : isDetecting }"> <ion-icon name="glasses"></ion-icon> </button> | |||
</div> | |||
<section class="image-action-buttons" *ngIf="tempImg"> | |||
<button (click)="approveImage()"> <img src="assets/icons/emojis/thumb-up.png"> </button> | |||
<button (click)="tempImg = null"> <img src="assets/icons/emojis/thumb-up.png"> </button> | |||
<button> <ion-icon name="share-social-outline"></ion-icon> </button> | |||
</section> | |||
</ion-content> |
@@ -1,10 +1,24 @@ | |||
@import '../colors'; | |||
.test-img { | |||
.temp-image { | |||
position: fixed; | |||
z-index: 1; | |||
left: 50%; | |||
top: 50%; | |||
left: 0; | |||
top: 0; | |||
width: 100vw; | |||
height: 100vh; | |||
transform: scale(0); | |||
transition: transform 0.1s; | |||
&.active { | |||
transform: scale(1); | |||
} | |||
img { | |||
width: 100%; | |||
height: 100%; | |||
object-fit: contain; | |||
} | |||
} | |||
.back-button { | |||
@@ -13,7 +27,7 @@ | |||
right: 10px; | |||
width: 40px; | |||
height: 40px; | |||
background: rgba(white, 0.5); | |||
background: rgba($pink, 0.5); | |||
border: 0px; | |||
border-radius: 50%; | |||
display: flex; | |||
@@ -29,6 +43,7 @@ | |||
.container { | |||
position: relative; | |||
z-index: 0; | |||
} | |||
.glass-image { | |||
@@ -75,6 +90,7 @@ | |||
display: flex; | |||
align-items: center; | |||
width: 100%; | |||
z-index: 1; | |||
button { | |||
width: 50px; | |||
@@ -104,4 +120,43 @@ | |||
} | |||
} | |||
} | |||
} | |||
.image-action-buttons { | |||
position: fixed; | |||
left: 0; | |||
bottom: 20px; | |||
width: 200px; | |||
margin-left: calc(50% - 100px); | |||
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: 50px; | |||
height: 50px; | |||
border-radius: 50%; | |||
border: 1px solid rgba($blue-grey, 0.6); | |||
background-color: transparent; | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
&:nth-child(2) { | |||
transform: rotate(180deg); | |||
} | |||
img { | |||
width: 20px; | |||
} | |||
ion-icon { | |||
color: white; | |||
font-size: 20px; | |||
} | |||
} | |||
} |
@@ -1,6 +1,7 @@ | |||
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; | |||
import { detectSingleFace, loadFaceExpressionModel, loadFaceLandmarkModel, loadFaceLandmarkTinyModel, loadFaceRecognitionModel, loadSsdMobilenetv1Model, loadTinyFaceDetectorModel, TinyFaceDetectorOptions } from 'face-api.js'; | |||
import { Location } from '@angular/common'; | |||
import { ModalController } from '@ionic/angular'; | |||
@Component({ | |||
selector: 'app-ar-fan-cam', | |||
@@ -24,14 +25,15 @@ export class ArFanCamPage implements OnInit { | |||
areNeuralNetsLoaded = false; | |||
isDetecting = false; | |||
width = 360; | |||
height = 270; | |||
width: number; | |||
height: number; | |||
temp: string; | |||
tempImg = ''; | |||
stream: any; | |||
constructor( | |||
private location: Location | |||
private location: Location, | |||
private modalController: ModalController | |||
) { } | |||
loadNeuralNetModels = async () => { | |||
@@ -48,7 +50,7 @@ export class ArFanCamPage implements OnInit { | |||
} | |||
back() { | |||
this.location.back(); | |||
this.modalController.dismiss(); | |||
this.stopCameraStream(); | |||
} | |||
@@ -107,6 +109,8 @@ export class ArFanCamPage implements OnInit { | |||
const dataURI = canvas.toDataURL('image/png'); | |||
this.capturedImageStrings.push(dataURI); | |||
this.tempImg = dataURI; | |||
context.resetTransform(); | |||
context.clearRect(0, 0, window.innerWidth, window.innerHeight); | |||
} | |||
@@ -142,19 +146,22 @@ export class ArFanCamPage implements OnInit { | |||
} | |||
} | |||
ngOnInit() { | |||
ngOnInit() { | |||
this.width = window.innerWidth; | |||
this.height = window.innerHeight; | |||
} | |||
ngAfterViewInit() { | |||
this.loadNeuralNetModels(); | |||
const feedWidth = window.innerWidth; | |||
const feedHeight = window.innerHeight; | |||
this.width = feedWidth; | |||
this.height = feedHeight; | |||
this.getCameraStream().then(() => this.detectAndDrawFace(), (err) => console.log(err)); | |||
} | |||
approveImage() { | |||
this.stopCameraStream(); | |||
this.modalController.dismiss({ | |||
imageData: this.tempImg | |||
}); | |||
} | |||
} |
@@ -26,11 +26,11 @@ | |||
</div> | |||
<ul class="stories"> | |||
<li [routerLink]="['/ar-fan-cam']"> | |||
<li (click)="presentCamModal()"> | |||
<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 }" | |||
<li *ngFor="let story of reversed(fanStories); let i = index" [ngClass]="{'inactive' : story.opened }" | |||
(click)="showSlides = true; story.opened = true; goToSlide(i)"> | |||
<img [src]="story.profileImage"> | |||
<span> {{ story.name }} </span> | |||
@@ -38,7 +38,7 @@ | |||
</ul> | |||
<ul class="fan-feature-list"> | |||
<li [routerLink]="['/ar-fan-cam']"> | |||
<li (click)="presentCamModal()"> | |||
<div> | |||
<ion-icon name="camera-outline"></ion-icon> | |||
@@ -1,10 +1,11 @@ | |||
import { Component, OnInit, ViewChild } from '@angular/core'; | |||
import { IonSlides } from '@ionic/angular'; | |||
import { IonItemOption, IonSlides, ModalController } from '@ionic/angular'; | |||
import { GooglePlus } from '@ionic-native/google-plus/ngx'; | |||
import { Platform } from '@ionic/angular'; | |||
import { AngularFireAuth } from '@angular/fire/auth'; | |||
import firebase from 'firebase'; | |||
import { ArFanCamPage } from '../ar-fan-cam/ar-fan-cam.page'; | |||
@Component({ | |||
selector: 'app-fan-zone', | |||
@@ -59,6 +60,7 @@ export class FanZonePage implements OnInit { | |||
private google: GooglePlus, | |||
private fireAuth: AngularFireAuth, | |||
private platform: Platform, | |||
private modalController: ModalController, | |||
) { } | |||
// async loginWithGoogle() { | |||
@@ -193,4 +195,28 @@ export class FanZonePage implements OnInit { | |||
}); | |||
} | |||
reversed(data: Array<any>) { | |||
return data.reverse(); | |||
} | |||
async presentCamModal() { | |||
const modal = await this.modalController.create({ | |||
component: ArFanCamPage, | |||
}); | |||
modal.onDidDismiss().then((data: any) => { | |||
if (data.data && data.data.imageData) { | |||
this.fanStories.push({ | |||
profileImage: this.googleUserData.profileImage, | |||
name: this.googleUserData.name, | |||
storyImage: data.data.imageData, | |||
likeCount: 1, | |||
opened: false | |||
}); | |||
} | |||
}); | |||
return await modal.present(); | |||
} | |||
} |