Commit d4dde87d authored by Dumplings X's avatar Dumplings X

fix

parent 55d8ec14
<div class="model-content"> <div class="model-content">
<div style="position: absolute; left: 200px; top: 100px; width: 300px;"> <app-custom-hot-zone
[bgItem]="bgItem"
[hotZoneItemArr]="hotZoneItemArr"
(save)="saveData($event)"
>
</app-custom-hot-zone>
<input type="text" nz-input [(ngModel)]="item.text" (blur)="save()">
<app-upload-image-with-preview <p style="padding-bottom: 5vw">
[picUrl]="item.pic_url"
(imageUploaded)="onImageUploadSuccess($event, 'pic_url')"
></app-upload-image-with-preview>
<app-audio-recorder </p>
[audioUrl]="item.audio_url"
(audioUploaded)="onAudioUploadSuccess($event, 'audio_url')"
></app-audio-recorder>
</div>
<div *ngFor="let it of picArr; let i = index">
<div style="padding: 2vw">
<div style="position: absolute; left: 1000px; top: 100px; width: 300px;"> <div style="display: flex; align-items: center; width: 70%">
<input type="text" nz-input [(ngModel)]="item.text_2" (blur)="save()">
<app-upload-image-with-preview
[picUrl]="item.pic_url_2"
(imageUploaded)="onImageUploadSuccess($event, 'pic_url_2')"
></app-upload-image-with-preview>
<span style="padding-right: 5px; width: 120px;"> question-{{i + 1}}: </span>
<input type="text" nz-input placeholder="" [(ngModel)]="it.text" (blur)="saveItem()">
<button style="margin-left: 10px;" nz-button nzType="danger" (click)="deleteItem(it)">
<i nz-icon type="close"></i>
</button>
<div style="display:inline-block; margin-left: 10px">
<app-audio-recorder <app-audio-recorder
[audioUrl]="item.audio_url_2" [audioUrl]="it.audio_url? it.audio_url:null"
(audioUploaded)="onAudioUploadSuccess($event, 'audio_url_2')" (audioUploaded)="onAudioUploadSuccessByItem($event, it)"
[needRemove]="true"
></app-audio-recorder> ></app-audio-recorder>
</div>
</div> </div>
<div style="display: flex; align-items: center; width: 70%">
<span style="padding-right: 5px; width: 120px;"> answer-{{i + 1}}: </span>
<nz-checkbox-group [(ngModel)]="it.options" (ngModelChange)="changeOptions(it.options)"></nz-checkbox-group>
</div>
</div> </div>
<!--<app-audio-recorder-->
<!--[audioUrl]="item.audio_url"-->
<!--(audioUploaded)="onAudioUploadSuccess($event)"-->
<!--&gt;</app-audio-recorder>-->
<!--<div *ngFor="let it of picArr; let i = index"-->
<!--nz-col nzSpan="8" >-->
<!--<div class="item-box">--> <!--<div class="item-box">-->
<!---->
<!--<app-upload-image-with-preview--> <!--<app-upload-image-with-preview-->
<!--style="width: 100%"--> <!--style="width: 100%"-->
<!--[picUrl]="it.pic_url"--> <!--[picUrl]="it.pic_url"-->
<!--(imageUploaded)="onImageUploadSuccessByItem($event, it)"--> <!--(imageUploaded)="onImageUploadSuccessByItem($event, it)"-->
<!--&gt;</app-upload-image-with-preview>--> <!--&gt;</app-upload-image-with-preview>-->
<!--<div style="display: flex; justify-items: center; padding-top: 10px">--> <!--<div style="display: flex; justify-items: center; padding-top: 10px">-->
<!--<app-audio-recorder--> <!--<app-audio-recorder-->
<!--[audioUrl]="it.audio_url"--> <!--[audioUrl]="it.audio_url"-->
...@@ -123,213 +65,195 @@ ...@@ -123,213 +65,195 @@
<!--</div>--> <!--</div>-->
<!--&lt;!&ndash;<h5> id-{{i+1}} </h5>&ndash;&gt;-->
<!--&lt;!&ndash;<div style="display: flex; align-items: center; justify-content: center; padding-bottom: 5px">&ndash;&gt;-->
<!--&lt;!&ndash;<input type="text" nz-input placeholder="" [(ngModel)]="it.text" (blur)="saveItem()">&ndash;&gt;-->
<!--&lt;!&ndash;<button style="margin-left: 10px;" nz-button nzType="danger" (click)="deleteItem(it)">&ndash;&gt;-->
<!--&lt;!&ndash;<i nz-icon type="close"></i>&ndash;&gt;-->
<!--&lt;!&ndash;</button>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--&lt;!&ndash;<app-upload-image-with-preview&ndash;&gt;-->
<!--&lt;!&ndash;style="width: 100%"&ndash;&gt;-->
<!--&lt;!&ndash;[picUrl]="it.pic_url"&ndash;&gt;-->
<!--&lt;!&ndash;(imageUploaded)="onImageUploadSuccessByItem($event, it)"&ndash;&gt;-->
<!--&lt;!&ndash;&gt;</app-upload-image-with-preview>&ndash;&gt;-->
<!--&lt;!&ndash;<div style="display: flex; align-items: center; justify-content: center">&ndash;&gt;-->
<!--&lt;!&ndash;<span style="width: 80px;">&ndash;&gt;-->
<!--&lt;!&ndash;question:&ndash;&gt;-->
<!--&lt;!&ndash;</span>&ndash;&gt;-->
<!--&lt;!&ndash;<app-audio-recorder&ndash;&gt;-->
<!--&lt;!&ndash;[audioUrl]="it['q_audio_url']"&ndash;&gt;-->
<!--&lt;!&ndash;(audioUploaded)="onAudioUploadSuccessByItem($event, it, 'q')">&ndash;&gt;-->
<!--&lt;!&ndash;</app-audio-recorder>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--&lt;!&ndash;<div style="display: flex; align-items: center; justify-content: center">&ndash;&gt;-->
<!--&lt;!&ndash;<span style="width: 80px;">&ndash;&gt;-->
<!--&lt;!&ndash;answer:&ndash;&gt;-->
<!--&lt;!&ndash;</span>&ndash;&gt;-->
<!--&lt;!&ndash;<app-audio-recorder&ndash;&gt;-->
<!--&lt;!&ndash;[audioUrl]="it['a_audio_url']"&ndash;&gt;-->
<!--&lt;!&ndash;(audioUploaded)="onAudioUploadSuccessByItem($event, it, 'a')">&ndash;&gt;-->
<!--&lt;!&ndash;</app-audio-recorder>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--&lt;!&ndash;<nz-radio-group [(ngModel)]="it.radioValue" >&ndash;&gt;-->
<!--&lt;!&ndash;<label nz-radio nzValue="A" (click)="radioClick(it, 'A')"> <i nz-icon nzType="check" nzTheme="outline"></i> </label>&ndash;&gt;-->
<!--&lt;!&ndash;<label nz-radio nzValue="B" (click)="radioClick(it, 'B')"> <i nz-icon nzType="close" nzTheme="outline"></i> </label>&ndash;&gt;-->
<!--&lt;!&ndash;</nz-radio-group>&ndash;&gt;-->
<!--<h5> id-{{i+1}} </h5>-->
<!--<div style="display: flex; align-items: center; justify-content: center; padding-bottom: 5px">-->
<!--<input type="text" nz-input placeholder="" [(ngModel)]="it.text" (blur)="saveItem()">-->
<!--<button style="margin-left: 10px;" nz-button nzType="danger" (click)="deleteItem(it)">-->
<!--<i nz-icon type="close"></i>-->
<!--</button>-->
<!--</div>--> <!--</div>-->
<!--<app-upload-image-with-preview-->
<!--style="width: 100%"-->
<!--[picUrl]="it.pic_url"-->
<!--(imageUploaded)="onImageUploadSuccessByItem($event, it)"-->
<!--&gt;</app-upload-image-with-preview>-->
<!--<div nz-col nzSpan="8" class="add-btn-box" >-->
<!--&lt;!&ndash;<div style="width: 100%; height: 100%;">&ndash;&gt;-->
<!--<button style=" margin: auto; width: 60%; height: 60%;" nz-button nzType="dashed" class="add-btn"-->
<!--(click)="addPic()">-->
<!--<i nz-icon nzType="plus-circle" nzTheme="outline"></i>-->
<!--Add-->
<!--</button>-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--<div style="display: flex; align-items: center; justify-content: center">-->
<!--<span style="width: 80px;">-->
<!--question:-->
<!--</span>-->
<!--<app-audio-recorder-->
<!--[audioUrl]="it['q_audio_url']"-->
<!--(audioUploaded)="onAudioUploadSuccessByItem($event, it, 'q')">-->
<!--</app-audio-recorder>-->
<!--</div>--> <!--</div>-->
<!--<div style="display: flex; align-items: center; justify-content: center">-->
<!--<span style="width: 80px;">-->
<!--answer:-->
<!--</span>-->
<!--<app-audio-recorder-->
<!--[audioUrl]="it['a_audio_url']"-->
<!--(audioUploaded)="onAudioUploadSuccessByItem($event, it, 'a')">-->
<!--</app-audio-recorder>-->
<!--</div>-->
<!--<nz-radio-group [(ngModel)]="it.radioValue" >-->
<!--<label nz-radio nzValue="A" (click)="radioClick(it, 'A')"> <i nz-icon nzType="check" nzTheme="outline"></i> </label>-->
<!--<label nz-radio nzValue="B" (click)="radioClick(it, 'B')"> <i nz-icon nzType="close" nzTheme="outline"></i> </label>-->
<!--</nz-radio-group>-->
</div>
<div nz-col nzSpan="8" class="add-btn-box">
<!--&lt;!&ndash;<div style="padding-bottom: 30px;">&ndash;&gt;--> <!--<div style="width: 100%; height: 100%;">-->
<button style=" margin: auto; width: 60%; height: 60%;" nz-button nzType="dashed" class="add-btn"
<!--&lt;!&ndash;<h5> title-sound: </h5>&ndash;&gt;--> (click)="addPic()">
<!--&lt;!&ndash;<app-audio-recorder&ndash;&gt;--> <i nz-icon nzType="plus-circle" nzTheme="outline"></i>
<!--&lt;!&ndash;[audioUrl]="item.contentObj.title_audio_url"&ndash;&gt;--> Add
<!--&lt;!&ndash;(audioUploaded)="onAudioUploadSuccessByItem($event, item.contentObj, 'title')">&ndash;&gt;--> </button>
<!--&lt;!&ndash;</app-audio-recorder>&ndash;&gt;--> <!--</div>-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--&lt;!&ndash;<div style="padding-bottom: 30px;">&ndash;&gt;-->
<!--&lt;!&ndash;<h5> bg-sound: </h5>&ndash;&gt;-->
<!--&lt;!&ndash;<app-audio-recorder&ndash;&gt;-->
<!--&lt;!&ndash;[audioUrl]="item.contentObj.bg_audio_url"&ndash;&gt;-->
<!--&lt;!&ndash;(audioUploaded)="onAudioUploadSuccessByItem($event, item.contentObj, 'bg')">&ndash;&gt;-->
<!--&lt;!&ndash;</app-audio-recorder>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;--> </div>
<!--&lt;!&ndash;<span style="margin-bottom: 20px"> 10 : 23 </span>&ndash;&gt;-->
<!--&lt;!&ndash;<div *ngFor="let it of picArr; let i = index">&ndash;&gt;--> <!--<div style="padding-bottom: 30px;">-->
<!--<h5> title-sound: </h5>-->
<!--<app-audio-recorder-->
<!--[audioUrl]="item.contentObj.title_audio_url"-->
<!--(audioUploaded)="onAudioUploadSuccessByItem($event, item.contentObj, 'title')">-->
<!--</app-audio-recorder>-->
<!--&lt;!&ndash;<span> pic-{{i + 1}}: </span>&ndash;&gt;--> <!--</div>-->
<!--&lt;!&ndash;<div style="display: flex; align-items: center; padding-bottom: 20px">&ndash;&gt;-->
<!--&lt;!&ndash;<div style="width: 40%; padding-right: 20px">&ndash;&gt;-->
<!--&lt;!&ndash;<app-upload-image-with-preview&ndash;&gt;-->
<!--&lt;!&ndash;[picUrl]="it.pic_url"&ndash;&gt;-->
<!--&lt;!&ndash;(imageUploaded)="onImageUploadSuccessByItem($event, it)"&ndash;&gt;-->
<!--&lt;!&ndash;&gt;</app-upload-image-with-preview>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--&lt;!&ndash;<div class="pic-sound-box">&ndash;&gt;--> <!--<div style="padding-bottom: 30px;">-->
<!--&lt;!&ndash;<div nz-row style="width: 50%; padding-bottom: 20px;">&ndash;&gt;--> <!--<h5> bg-sound: </h5>-->
<!--<app-audio-recorder-->
<!--[audioUrl]="item.contentObj.bg_audio_url"-->
<!--(audioUploaded)="onAudioUploadSuccessByItem($event, item.contentObj, 'bg')">-->
<!--</app-audio-recorder>-->
<!--&lt;!&ndash;<div *ngFor="let it2 of it.soundArr; let i2 = index" nz-col nzSpan="8">&ndash;&gt;--> <!--</div>-->
<!--&lt;!&ndash;<label nz-checkbox nzValue="{{'answer_' + (i2 + 1)}}" [(ngModel)]="it2.answer" (ngModelChange)="clickCheckBox()" >{{i2 + 1}}</label>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;--> <!--<span style="margin-bottom: 20px"> 10 : 23 </span>-->
<!--&lt;!&ndash;<div *ngFor="let it2 of it.soundArr; let i2 = index" style="display: flex; align-items: center; padding-bottom: 5px">&ndash;&gt;--> <!--<div *ngFor="let it of picArr; let i = index">-->
<!--&lt;!&ndash;<span style="padding-right: 10px">sound-{{i2 + 1}}:</span>&ndash;&gt;-->
<!--&lt;!&ndash;<app-audio-recorder&ndash;&gt;-->
<!--&lt;!&ndash;[audioUrl]="it2.audio_url"&ndash;&gt;-->
<!--&lt;!&ndash;(audioUploaded)="onAudioUploadSuccessByItem($event, it2)">&ndash;&gt;-->
<!--&lt;!&ndash;</app-audio-recorder>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--<span> pic-{{i + 1}}: </span>-->
<!--<div style="display: flex; align-items: center; padding-bottom: 20px">-->
<!--&lt;!&ndash;</div>&ndash;&gt;--> <!--<div style="width: 40%; padding-right: 20px">-->
<!--<app-upload-image-with-preview-->
<!--[picUrl]="it.pic_url"-->
<!--(imageUploaded)="onImageUploadSuccessByItem($event, it)"-->
<!--&gt;</app-upload-image-with-preview>-->
<!--</div>-->
<!--&lt;!&ndash;</div>&ndash;&gt;--> <!--<div class="pic-sound-box">-->
<!--<div nz-row style="width: 50%; padding-bottom: 20px;">-->
<!--<div *ngFor="let it2 of it.soundArr; let i2 = index" nz-col nzSpan="8">-->
<!--<label nz-checkbox nzValue="{{'answer_' + (i2 + 1)}}" [(ngModel)]="it2.answer" (ngModelChange)="clickCheckBox()" >{{i2 + 1}}</label>-->
<!--</div>-->
<!--&lt;!&ndash;<div style="margin: auto; width: 95%;" nz-row nzType="flex" nzJustify="start" nzAlign="middle">&ndash;&gt;--> <!--</div>-->
<!--<div *ngFor="let it2 of it.soundArr; let i2 = index" style="display: flex; align-items: center; padding-bottom: 5px">-->
<!--<span style="padding-right: 10px">sound-{{i2 + 1}}:</span>-->
<!--<app-audio-recorder-->
<!--[audioUrl]="it2.audio_url"-->
<!--(audioUploaded)="onAudioUploadSuccessByItem($event, it2)">-->
<!--</app-audio-recorder>-->
<!--</div>-->
<!--&lt;!&ndash;<div *ngFor="let it of picArr; let i = index"&ndash;&gt;--> <!--</div>-->
<!--&lt;!&ndash;nz-col nzSpan="8" >&ndash;&gt;-->
<!--&lt;!&ndash;<div class="item-box">&ndash;&gt;-->
<!--</div>-->
<!--&lt;!&ndash;<h5> id-{{i+1}} </h5>&ndash;&gt;--> <!--</div>-->
<!--&lt;!&ndash;<div style="display: flex; align-items: center; justify-content: center; padding-bottom: 5px">&ndash;&gt;-->
<!--&lt;!&ndash;<input type="text" nz-input placeholder="" [(ngModel)]="it.text" (blur)="saveItem()">&ndash;&gt;-->
<!--&lt;!&ndash;<button style="margin-left: 10px;" nz-button nzType="danger" (click)="deleteItem(it)">&ndash;&gt;-->
<!--&lt;!&ndash;<i nz-icon type="close"></i>&ndash;&gt;-->
<!--&lt;!&ndash;</button>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--<div style="margin: auto; width: 95%;" nz-row nzType="flex" nzJustify="start" nzAlign="middle">-->
<!--&lt;!&ndash;<app-upload-image-with-preview&ndash;&gt;-->
<!--&lt;!&ndash;style="width: 100%"&ndash;&gt;-->
<!--&lt;!&ndash;[picUrl]="it.pic_url"&ndash;&gt;-->
<!--&lt;!&ndash;(imageUploaded)="onImageUploadSuccessByItem($event, it)"&ndash;&gt;-->
<!--&lt;!&ndash;&gt;</app-upload-image-with-preview>&ndash;&gt;-->
<!--<div *ngFor="let it of picArr; let i = index"-->
<!--nz-col nzSpan="8" >-->
<!--&lt;!&ndash;<div style="display: flex; align-items: center; justify-content: center">&ndash;&gt;--> <!--<div class="item-box">-->
<!--&lt;!&ndash;<span style="width: 80px;">&ndash;&gt;-->
<!--&lt;!&ndash;question:&ndash;&gt;-->
<!--&lt;!&ndash;</span>&ndash;&gt;-->
<!--&lt;!&ndash;<app-audio-recorder&ndash;&gt;-->
<!--&lt;!&ndash;[audioUrl]="it['q_audio_url']"&ndash;&gt;-->
<!--&lt;!&ndash;(audioUploaded)="onAudioUploadSuccessByItem($event, it, 'q')">&ndash;&gt;-->
<!--&lt;!&ndash;</app-audio-recorder>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;--> <!--<h5> id-{{i+1}} </h5>-->
<!--&lt;!&ndash;<div style="display: flex; align-items: center; justify-content: center">&ndash;&gt;--> <!--<div style="display: flex; align-items: center; justify-content: center; padding-bottom: 5px">-->
<!--<input type="text" nz-input placeholder="" [(ngModel)]="it.text" (blur)="saveItem()">-->
<!--<button style="margin-left: 10px;" nz-button nzType="danger" (click)="deleteItem(it)">-->
<!--<i nz-icon type="close"></i>-->
<!--</button>-->
<!--</div>-->
<!--&lt;!&ndash;<span style="width: 80px;">&ndash;&gt;-->
<!--&lt;!&ndash;answer:&ndash;&gt;-->
<!--&lt;!&ndash;</span>&ndash;&gt;-->
<!--&lt;!&ndash;<app-audio-recorder&ndash;&gt;-->
<!--&lt;!&ndash;[audioUrl]="it['a_audio_url']"&ndash;&gt;-->
<!--&lt;!&ndash;(audioUploaded)="onAudioUploadSuccessByItem($event, it, 'a')">&ndash;&gt;-->
<!--&lt;!&ndash;</app-audio-recorder>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;--> <!--<app-upload-image-with-preview-->
<!--style="width: 100%"-->
<!--[picUrl]="it.pic_url"-->
<!--(imageUploaded)="onImageUploadSuccessByItem($event, it)"-->
<!--&gt;</app-upload-image-with-preview>-->
<!--<div style="display: flex; align-items: center; justify-content: center">-->
<!--&lt;!&ndash;<nz-radio-group [(ngModel)]="it.radioValue" >&ndash;&gt;--> <!--<span style="width: 80px;">-->
<!--&lt;!&ndash;<label nz-radio nzValue="A" (click)="radioClick(it, 'A')"> <i nz-icon nzType="check" nzTheme="outline"></i> </label>&ndash;&gt;--> <!--question:-->
<!--&lt;!&ndash;<label nz-radio nzValue="B" (click)="radioClick(it, 'B')"> <i nz-icon nzType="close" nzTheme="outline"></i> </label>&ndash;&gt;--> <!--</span>-->
<!--&lt;!&ndash;</nz-radio-group>&ndash;&gt;--> <!--<app-audio-recorder-->
<!--[audioUrl]="it['q_audio_url']"-->
<!--(audioUploaded)="onAudioUploadSuccessByItem($event, it, 'q')">-->
<!--</app-audio-recorder>-->
<!--</div>-->
<!--&lt;!&ndash;</div>&ndash;&gt;--> <!--<div style="display: flex; align-items: center; justify-content: center">-->
<!--<span style="width: 80px;">-->
<!--answer:-->
<!--</span>-->
<!--<app-audio-recorder-->
<!--[audioUrl]="it['a_audio_url']"-->
<!--(audioUploaded)="onAudioUploadSuccessByItem($event, it, 'a')">-->
<!--</app-audio-recorder>-->
<!--</div>-->
<!--&lt;!&ndash;</div>&ndash;&gt;--> <!--<nz-radio-group [(ngModel)]="it.radioValue" >-->
<!--<label nz-radio nzValue="A" (click)="radioClick(it, 'A')"> <i nz-icon nzType="check" nzTheme="outline"></i> </label>-->
<!--<label nz-radio nzValue="B" (click)="radioClick(it, 'B')"> <i nz-icon nzType="close" nzTheme="outline"></i> </label>-->
<!--</nz-radio-group>-->
<!--</div>-->
<!--</div>-->
<!--</div>--> </div>
import {Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, ApplicationRef} from '@angular/core'; import {
Component,
EventEmitter,
Input,
OnDestroy,
OnChanges,
OnInit,
Output,
ApplicationRef,
ChangeDetectorRef
} from '@angular/core';
...@@ -9,13 +19,40 @@ import {Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, Ap ...@@ -9,13 +19,40 @@ import {Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, Ap
}) })
export class FormComponent implements OnInit, OnChanges, OnDestroy { export class FormComponent implements OnInit, OnChanges, OnDestroy {
// 储存数据用 picArr = [];
saveKey = "test_0011";
// 储存对象
item;
_item: any;
constructor(private appRef: ApplicationRef) {
KEY = 'hw_online_008';
// @Input()
set item(item) {
this._item = item;
// this.init();
}
get item() {
return this._item;
}
@Output()
update = new EventEmitter();
bgItem;
hotZoneItemArr;
constructor(private appRef: ApplicationRef,
public changeDetectorRef: ChangeDetectorRef) {
} }
...@@ -23,68 +60,205 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -23,68 +60,205 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
ngOnInit() { ngOnInit() {
this.item = {}; this.item = {};
this.item.contentObj = {};
// 获取存储的数据 const getData = (<any> window).courseware.getData;
(<any> window).courseware.getData((data) => { getData((data) => {
if (data) { if (data) {
this.item = data; this.item = data;
} else {
this.item = {};
} }
if ( !this.item.contentObj ) {
this.item.contentObj = {};
}
console.log('~data:', data);
this.init(); this.init();
this.refresh();
}, this.saveKey); this.changeDetectorRef.markForCheck();
this.changeDetectorRef.detectChanges();
} this.refresh();
}, this.KEY);
// this.initData();
}
ngOnChanges() { ngOnChanges() {
} }
ngOnDestroy() { ngOnDestroy() {
} }
init() { init() {
if (this.item.contentObj.picArr) {
this.picArr = this.item.contentObj.picArr;
} else {
this.picArr = this.getDefaultPicArr();
this.item.contentObj.picArr = this.picArr;
}
this.bgItem = this.item.contentObj.bgItem || {};
this.hotZoneItemArr = this.item.contentObj.hotZoneItemArr || [];
console.log('item:' , this.item);
// this.picArr = this.getDefaultPicArr();
// this.item.contentObj.picArr = this.picArr;
// console.log('this.item:;', this.picArr);
}
getDefaultPicArr() {
const arr = [];
return arr;
}
changeOptions(data) {
console.log('data: ', data);
this.save();
}
getOptions() {
const options = [];
const arr = this.hotZoneItemArr;
for (let i = 0; i < arr.length; i++) {
const data = {};
data['key'] = arr[i]['key'];
data['index'] = arr[i]['index'];
data['label'] = 'item-' + (arr[i]['index'] + 1);
data['value'] = arr[i]['index'];
options.push(data);
} }
return options;
}
refreshOptions() {
const picArr = this.picArr;
for (let i = 0; i < picArr.length; i++) {
picArr[i].options = this.getOptions();
}
}
deleteItem(data, arr = null) {
if (!arr) {
arr = this.picArr;
}
const index = arr.indexOf(data);
if (index !== -1) {
arr.splice(index, 1);
}
// this.update.emit(this.item);
// this.refreshOptions();
this.save();
}
onImageUploadSuccessByItem(e, item, id = null) {
if (id != null) {
item[id + '_pic_url'] = e.url;
} else {
item.pic_url = e.url;
}
this.save();
// this.update.emit(this.item);
// console.log('this.item: ', this.item);
}
/** onAudioUploadSuccessByItem(e, item, id = null) {
* 储存图片数据
* @param e
*/
onImageUploadSuccess(e, key) {
this.item[key] = e.url; if (id != null) {
item[id + '_audio_url'] = e.url;
} else {
item.audio_url = e.url;
}
// this.update.emit(this.item);
this.save(); this.save();
} }
/**
* 储存音频数据
* @param e
*/
onAudioUploadSuccess(e, key) {
this.item[key] = e.url;
addPic() {
this.picArr.push({
pic_url: '',
audio_url: '',
text: '',
options: this.getOptions()
// text: '',
// radioValue: 'A'
});
// this.refreshOptions();
this.saveItem();
}
radioClick(it, radioValue) {
it.radioValue = radioValue;
this.saveItem();
}
clickCheckBox() {
console.log(' in clickCheckBox');
this.saveItem();
}
saveItem() {
// this.update.emit(this.item);
this.save(); this.save();
} }
saveData(e) {
console.log('savedata e:', e);
/** this.bgItem = e.bgItem;
* 储存数据 this.hotZoneItemArr = e.hotZoneItemArr;
*/
this.item.contentObj.bgItem = this.bgItem;
this.item.contentObj.hotZoneItemArr = this.hotZoneItemArr;
this.refreshOptions();
this.save();
}
save() { save() {
(<any> window).courseware.setData(this.item, null, this.saveKey); (<any> window).courseware.setData(this.item, null, this.KEY);
this.refresh(); this.refresh();
} }
/**
* 刷新 渲染页面
*/
refresh() { refresh() {
setTimeout(() => { setTimeout(() => {
this.appRef.tick(); this.appRef.tick();
......
import TWEEN from '@tweenjs/tween.js'; import TWEEN from '@tweenjs/tween.js';
import {del} from 'selenium-webdriver/http';
import construct = Reflect.construct;
class Sprite { class Sprite {
...@@ -50,6 +49,14 @@ export class MySprite extends Sprite { ...@@ -50,6 +49,14 @@ export class MySprite extends Sprite {
skewX = 0; skewX = 0;
skewY = 0; skewY = 0;
_shadowFlag = false;
_shadowColor;
_shadowOffsetX = 0;
_shadowOffsetY = 0;
_shadowBlur = 5;
_radius = 0;
children = [this]; children = [this];
childDepandVisible = true; childDepandVisible = true;
...@@ -76,6 +83,21 @@ export class MySprite extends Sprite { ...@@ -76,6 +83,21 @@ export class MySprite extends Sprite {
} }
setShadow(offX, offY, blur, color = 'rgba(0, 0, 0, 0.3)') {
this._shadowFlag = true;
this._shadowColor = color;
this._shadowOffsetX = offX;
this._shadowOffsetY = offY;
this._shadowBlur = blur;
}
setRadius(r) {
this._radius = r;
}
update($event = null) { update($event = null) {
if (!this.visible && this.childDepandVisible) { if (!this.visible && this.childDepandVisible) {
...@@ -94,6 +116,8 @@ export class MySprite extends Sprite { ...@@ -94,6 +116,8 @@ export class MySprite extends Sprite {
this.updateChildren(); this.updateChildren();
this.ctx.restore(); this.ctx.restore();
} }
drawInit() { drawInit() {
...@@ -109,12 +133,51 @@ export class MySprite extends Sprite { ...@@ -109,12 +133,51 @@ export class MySprite extends Sprite {
this.ctx.transform(1, this.skewX, this.skewY, 1, 0, 0); this.ctx.transform(1, this.skewX, this.skewY, 1, 0, 0);
if (this._radius) {
const r = this._radius;
const w = this.width;
const h = this.height;
this.ctx.lineTo(-w / 2, h / 2); // 创建水平线
this.ctx.arcTo(-w / 2, -h / 2, -w / 2 + r, -h / 2, r);
this.ctx.arcTo(w / 2, -h / 2, w / 2, -h / 2 + r, r);
this.ctx.arcTo(w / 2, h / 2, w / 2 - r, h / 2, r);
this.ctx.arcTo(-w / 2, h / 2, -w / 2, h / 2 - r, r);
this.ctx.clip();
}
} }
drawSelf() { drawSelf() {
if (this._shadowFlag) {
this.ctx.shadowOffsetX = this._shadowOffsetX;
this.ctx.shadowOffsetY = this._shadowOffsetY;
this.ctx.shadowBlur = this._shadowBlur;
this.ctx.shadowColor = this._shadowColor;
} else {
this.ctx.shadowOffsetX = 0;
this.ctx.shadowOffsetY = 0;
this.ctx.shadowBlur = null;
this.ctx.shadowColor = null;
}
if (this.img) { if (this.img) {
this.ctx.drawImage(this.img, this._offX, this._offY); this.ctx.drawImage(this.img, this._offX, this._offY);
} }
} }
updateChildren() { updateChildren() {
...@@ -442,15 +505,15 @@ export class Label extends MySprite { ...@@ -442,15 +505,15 @@ export class Label extends MySprite {
fontSize = 40; fontSize = 40;
fontColor = '#000000'; fontColor = '#000000';
fontWeight = 900; fontWeight = 900;
maxWidth; _maxWidth;
outline = 0; outline = 0;
outlineColor = '#ffffff'; outlineColor = '#ffffff';
_shadowFlag = false; // _shadowFlag = false;
_shadowColor; // _shadowColor;
_shadowOffsetX; // _shadowOffsetX;
_shadowOffsetY; // _shadowOffsetY;
_shadowBlur; // _shadowBlur;
_outlineFlag = false; _outlineFlag = false;
_outLineWidth; _outLineWidth;
...@@ -481,7 +544,7 @@ export class Label extends MySprite { ...@@ -481,7 +544,7 @@ export class Label extends MySprite {
setMaxSize(w) { setMaxSize(w) {
this.maxWidth = w; this._maxWidth = w;
this.refreshSize(); this.refreshSize();
if (this.width >= w) { if (this.width >= w) {
this.scaleX *= w / this.width; this.scaleX *= w / this.width;
...@@ -508,16 +571,16 @@ export class Label extends MySprite { ...@@ -508,16 +571,16 @@ export class Label extends MySprite {
.start(); // Start the tween immediately. .start(); // Start the tween immediately.
} }
setShadow(offX = 2, offY = 2, blur = 2, color = 'rgba(0, 0, 0, 0.2)') { // setShadow(offX = 0, offY = 2, blur = 2, color = 'rgba(0, 0, 0, 0.2)') {
//
this._shadowFlag = true; // this._shadowFlag = true;
this._shadowColor = color; // this._shadowColor = color;
// 将阴影向右移动15px,向上移动10px // // 将阴影向右移动15px,向上移动10px
this._shadowOffsetX = offX; // this._shadowOffsetX = 5;
this._shadowOffsetY = offY; // this._shadowOffsetY = 5;
// 轻微模糊阴影 // // 轻微模糊阴影
this._shadowBlur = blur; // this._shadowBlur = 5;
} // }
setOutline(width = 5, color = '#ffffff') { setOutline(width = 5, color = '#ffffff') {
...@@ -534,15 +597,15 @@ export class Label extends MySprite { ...@@ -534,15 +597,15 @@ export class Label extends MySprite {
if (!this.text) { return; } if (!this.text) { return; }
if (this._shadowFlag) { // if (this._shadowFlag) {
//
this.ctx.shadowColor = this._shadowColor; // this.ctx.shadowColor = this._shadowColor;
// 将阴影向右移动15px,向上移动10px // // 将阴影向右移动15px,向上移动10px
this.ctx.shadowOffsetX = this._shadowOffsetX; // this.ctx.shadowOffsetX = this._shadowOffsetX;
this.ctx.shadowOffsetY = this._shadowOffsetY; // this.ctx.shadowOffsetY = this._shadowOffsetY;
// 轻微模糊阴影 // // 轻微模糊阴影
this.ctx.shadowBlur = this._shadowBlur; // this.ctx.shadowBlur = this._shadowBlur;
} // }
...@@ -776,102 +839,58 @@ export class RichText extends Label { ...@@ -776,102 +839,58 @@ export class RichText extends Label {
export class LineRect extends MySprite {
export class ShapeRect extends MySprite { lineColor = "#ffffff";
lineWidth = 10;
fillColor = '#FF0000';
setSize(w, h) { setSize(w, h) {
this.width = w; this.width = w;
this.height = h; this.height = h;
// console.log('w:', w);
// console.log('h:', h);
} }
drawShape() { drawLine() {
this.ctx.fillStyle = this.fillColor; this.ctx.beginPath();
this.ctx.fillRect(this._offX, this._offY, this.width, this.height); this.ctx.moveTo(this._offX, this._offY);
this.ctx.lineTo(this._offX + this.width, this._offY);
this.ctx.lineTo(this._offX + this.width, this._offY + this.height);
this.ctx.lineTo(this._offX, this._offY + this.height);
this.ctx.closePath();
this.ctx.lineWidth = this.lineWidth;
// this.ctx.fillStyle = "rgb(2,33,42)"; //指定填充颜色
// this.ctx.fill(); //对多边形进行填充
this.ctx.strokeStyle = this.lineColor; // "#ffffff";
this.ctx.stroke();
} }
drawSelf() { drawSelf() {
super.drawSelf(); super.drawSelf();
this.drawShape(); this.drawLine();
} }
} }
export class ShapeRect extends MySprite {
export class ShapeRectNew extends MySprite { fillColor = '#FF0000';
radius = 0;
fillColor = '#ffffff';
strokeColor = '#000000';
fill = true;
stroke = false;
lineWidth = 1;
setSize(w, h, r) { setSize(w, h) {
this.width = w; this.width = w;
this.height = h; this.height = h;
this.radius = r;
}
setOutLine(color, lineWidth) { // console.log('w:', w);
this.stroke = true; // console.log('h:', h);
this.strokeColor = color;
this.lineWidth = lineWidth;
} }
drawShape() { drawShape() {
const ctx = this.ctx; this.ctx.fillStyle = this.fillColor;
const width = this.width; this.ctx.fillRect(this._offX, this._offY, this.width, this.height);
const height = this.height;
const radius = this.radius;
ctx.save();
ctx.beginPath(0);
// 从右下角顺时针绘制,弧度从0到1/2PI
ctx.arc(width - radius, height - radius, radius, 0, Math.PI / 2);
// 矩形下边线
ctx.lineTo(radius, height);
// 左下角圆弧,弧度从1/2PI到PI
ctx.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);
// 矩形左边线
ctx.lineTo(0, radius);
// 左上角圆弧,弧度从PI到3/2PI
ctx.arc(radius, radius, radius, Math.PI, Math.PI * 3 / 2);
// 上边线
ctx.lineTo(width - radius, 0);
// 右上角圆弧
ctx.arc(width - radius, radius, radius, Math.PI * 3 / 2, Math.PI * 2);
// 右边线
ctx.lineTo(width, height - radius);
ctx.closePath();
if (this.fill) {
ctx.fillStyle = this.fillColor;
ctx.fill();
}
if (this.stroke) {
ctx.lineWidth = this.lineWidth;
ctx.strokeStyle = this.strokeColor;
ctx.stroke();
}
ctx.restore();
} }
...@@ -880,7 +899,6 @@ export class ShapeRectNew extends MySprite { ...@@ -880,7 +899,6 @@ export class ShapeRectNew extends MySprite {
super.drawSelf(); super.drawSelf();
this.drawShape(); this.drawShape();
} }
} }
...@@ -1408,6 +1426,27 @@ export function delayCall(callback, second) { ...@@ -1408,6 +1426,27 @@ export function delayCall(callback, second) {
.start(); .start();
} }
export function formatTime(fmt, date) {
// "yyyy-MM-dd HH:mm:ss";
const o = {
"M+": date.getMonth() + 1, // 月份
"d+": date.getDate(), // 日
"h+": date.getHours(), // 小时
"m+": date.getMinutes(), // 分
"s+": date.getSeconds(), // 秒
"q+": Math.floor((date.getMonth() + 3) / 3), // 季度
"S": date.getMilliseconds() // 毫秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1)
? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
}
export function getMinScale(item, maxLen) { export function getMinScale(item, maxLen) {
const sx = maxLen / item.width; const sx = maxLen / item.width;
const sy = maxLen / item.height; const sy = maxLen / item.height;
...@@ -1456,9 +1495,9 @@ export function jelly(item, time = 0.7) { ...@@ -1456,9 +1495,9 @@ export function jelly(item, time = 0.7) {
export function showPopParticle(img, pos, parent) { export function showPopParticle(img, pos, parent, num = 20, minLen = 40, maxLen = 80, showTime = 0.4) {
const num = 20;
for (let i = 0; i < num; i ++) { for (let i = 0; i < num; i ++) {
const particle = new MySprite(); const particle = new MySprite();
...@@ -1470,8 +1509,8 @@ export function showPopParticle(img, pos, parent) { ...@@ -1470,8 +1509,8 @@ export function showPopParticle(img, pos, parent) {
const randomR = 360 * Math.random(); const randomR = 360 * Math.random();
particle.rotation = randomR; particle.rotation = randomR;
const randomS = 0.5 + Math.random() * 0.5; const randomS = 0.3 + Math.random() * 0.7;
particle.setScaleXY(randomS); particle.setScaleXY(randomS * 0.3);
const randomX = Math.random() * 20 - 10; const randomX = Math.random() * 20 - 10;
particle.x += randomX; particle.x += randomX;
...@@ -1479,17 +1518,111 @@ export function showPopParticle(img, pos, parent) { ...@@ -1479,17 +1518,111 @@ export function showPopParticle(img, pos, parent) {
const randomY = Math.random() * 20 - 10; const randomY = Math.random() * 20 - 10;
particle.y += randomY; particle.y += randomY;
const randomL = 40 + Math.random() * 40; const randomL = minLen + Math.random() * (maxLen - minLen);
const randomA = 360 * Math.random(); const randomA = 360 * Math.random();
const randomT = getPosByAngle(randomA, randomL); const randomT = getPosByAngle(randomA, randomL);
moveItem(particle, particle.x + randomT.x, particle.y + randomT.y, 0.4, () => { moveItem(particle, particle.x + randomT.x, particle.y + randomT.y, showTime, () => {
}, TWEEN.Easing.Exponential.Out); }, TWEEN.Easing.Exponential.Out);
scaleItem(particle, 0, 0.6, () => { // scaleItem(particle, 0, 0.6, () => {
//
// });
}); scaleItem(particle, randomS, 0.6, () => {
}, TWEEN.Easing.Exponential.Out);
setTimeout(() => {
hideItem(particle, 0.4, () => {
}, TWEEN.Easing.Cubic.In);
}, showTime * 0.5 * 1000);
}
}
export class ShapeRectNew extends MySprite {
radius = 0;
fillColor = '#ffffff';
strokeColor = '#000000';
fill = true;
stroke = false;
lineWidth = 1;
setSize(w, h, r) {
this.width = w;
this.height = h;
this.radius = r;
}
setOutLine(color, lineWidth) {
this.stroke = true;
this.strokeColor = color;
this.lineWidth = lineWidth;
}
drawShape() {
const ctx = this.ctx;
const width = this.width;
const height = this.height;
const radius = this.radius;
ctx.save();
ctx.beginPath(0);
// 从右下角顺时针绘制,弧度从0到1/2PI
ctx.arc(width - radius, height - radius, radius, 0, Math.PI / 2);
// 矩形下边线
ctx.lineTo(radius, height);
// 左下角圆弧,弧度从1/2PI到PI
ctx.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);
// 矩形左边线
ctx.lineTo(0, radius);
// 左上角圆弧,弧度从PI到3/2PI
ctx.arc(radius, radius, radius, Math.PI, Math.PI * 3 / 2);
// 上边线
ctx.lineTo(width - radius, 0);
// 右上角圆弧
ctx.arc(width - radius, radius, radius, Math.PI * 3 / 2, Math.PI * 2);
// 右边线
ctx.lineTo(width, height - radius);
ctx.closePath();
if (this.fill) {
ctx.fillStyle = this.fillColor;
ctx.fill();
}
if (this.stroke) {
ctx.lineWidth = this.lineWidth;
ctx.strokeStyle = this.strokeColor;
ctx.stroke();
} }
ctx.restore();
}
drawSelf() {
super.drawSelf();
this.drawShape();
}
} }
...@@ -1530,7 +1663,7 @@ export function shake(item, time = 0.5, callback = null, rate = 1) { ...@@ -1530,7 +1663,7 @@ export function shake(item, time = 0.5, callback = null, rate = 1) {
}; };
const move1 = () => { const move1 = () => {
moveItem(item, baseX + offX, baseY + offY, time / 8, () => { moveItem(item, baseX + offX, baseY + offY, time / 7.5, () => {
move2(); move2();
}, easing); }, easing);
}; };
...@@ -1541,4 +1674,3 @@ export function shake(item, time = 0.5, callback = null, rate = 1) { ...@@ -1541,4 +1674,3 @@ export function shake(item, time = 0.5, callback = null, rate = 1) {
// --------------- custom class -------------------- // --------------- custom class --------------------
import {Component, ElementRef, ViewChild, OnInit, Input, OnDestroy, HostListener} from '@angular/core'; import {Component, ElementRef, ViewChild, OnInit, Input, OnDestroy, HostListener} from '@angular/core';
import { import {
MySprite,
Label, Label,
MySprite, tweenChange, moveItem,
rotateItem,
removeItemFromArr,
ShapeRect, scaleItem, tweenChange, showPopParticle, hideItem, showItem, LineRect, shake, ShapeRectNew,
} from './Unit'; } from './Unit';
import {res, resAudio} from './resources'; import {res, resAudio} from './resources';
...@@ -10,35 +14,45 @@ import {res, resAudio} from './resources'; ...@@ -10,35 +14,45 @@ import {res, resAudio} from './resources';
import {Subject} from 'rxjs'; import {Subject} from 'rxjs';
import {debounceTime} from 'rxjs/operators'; import {debounceTime} from 'rxjs/operators';
import * as _ from 'lodash';
import TWEEN from '@tweenjs/tween.js'; import TWEEN from '@tweenjs/tween.js';
@Component({ @Component({
selector: 'app-play', selector: 'app-play',
templateUrl: './play.component.html', templateUrl: './play.component.html',
styleUrls: ['./play.component.scss'] styleUrls: ['./play.component.scss']
}) })
export class PlayComponent implements OnInit, OnDestroy { export class PlayComponent implements OnInit, OnDestroy {
// 数据
_data;
@ViewChild('canvas') canvas: ElementRef; @Input()
@ViewChild('wrap') wrap: ElementRef; set data(data) {
this._data = data;
}
// 数据 get data() {
data; return this._data;
}
ctx; @Input()
sid;
canvasWidth = 1280; // canvas实际宽度 @ViewChild('canvas') canvas: ElementRef;
canvasHeight = 720; // canvas实际高度 @ViewChild('wrap') wrap: ElementRef;
canvasWidth = 1280;
canvasHeight = 720;
canvasBaseW = 1280; // canvas 资源预设宽度 canvasBaseW = 1280;
canvasBaseH = 720; // canvas 资源预设高度 canvasBaseH = 720;
mx; // 点击x坐标 ctx;
my; // 点击y坐标 fps = 0;
frametime = 0; // 上一帧动画的时间, 两帧时间差
mx;
my; // 点击坐标
// 资源 // 资源
rawImages = new Map(res); rawImages = new Map(res);
...@@ -50,123 +64,1228 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -50,123 +64,1228 @@ export class PlayComponent implements OnInit, OnDestroy {
winResizeEventStream = new Subject(); winResizeEventStream = new Subject();
audioObj = {}; audioObj = {};
renderArr; renderArr;
mapScale = 1; mapScale = 1;
canvasLeft; canvasLeft;
canvasTop; canvasTop;
saveKey = 'test_0011';
btnLeft;
btnRight;
pic1;
pic2;
canTouch = true; canTouch = true;
curPic; KEY = 'hw_online_008';
// -----
picArr;
titleLabel;
light;
particleLayer;
shadowArr;
answerTarget;
answerCurrent;
bgRect;
starBgArr;
clickedSuccessArr;
pageLabel;
leftBtn;
rightBtn;
bgLayer;
curPageIndex;
hotZoneArr;
picIndex = 0;
bgArr;
endPageArr;
gameEndFlag;
showPetalFlag;
bg;
// 是否游戏进行中
isGaming;
@HostListener('window:resize', ['$event']) @HostListener('window:resize', ['$event'])
onResize(event) { onResize(event) {
this.winResizeEventStream.next(); this.winResizeEventStream.next();
} }
teachFlag;
coverPageArr = [];
startBtn;
ngOnInit() { ngOnInit() {
this.data = {};
// 获取数据
const getData = (<any> window).courseware.getData; const getData = (<any> window).courseware.getData;
getData((data) => { getData((data) => {
if (window['air'].airClassInfo.user.classRole == 'tea') {
this.teachFlag = true;
}
if (data && typeof data == 'object') { if (data && typeof data == 'object') {
this.data = data; this.data = data;
} else {
this.data = {};
}
this.addServerListener();
console.log('data:', data);
if (!this.data.contentObj) {
this.data.contentObj = {};
}
this.initDefaultData();
this.initAudio();
this.initImg();
this.initListener();
}, this.KEY);
}
initCover() {
const shapeBg = new ShapeRectNew();
const lenW = 400 * this.mapScale;
shapeBg.setSize(lenW, lenW / 3 * 1.5, 30 * this.mapScale);
shapeBg.alpha = 0.5;
shapeBg.fillColor = '#000000';
shapeBg.x = this.canvasWidth / 2 - shapeBg.width / 2;
shapeBg.y = this.canvasHeight / 2 - shapeBg.height / 2;
this.coverPageArr.push(shapeBg);
this.startBtn = shapeBg;
const label = new Label();
label.fontName = 'BRLNSDB';
label.fontColor = '#ffffff';
label.fontSize = 50;
label.textAlign = 'center';
label.x = shapeBg.width / 2;
label.y = shapeBg.height / 2;
shapeBg.addChild(label);
if (this.teachFlag) {
label.text = 'start';
} else {
label.text = 'ready ..';
}
}
initDefaultData() {
let picArr = this.data.contentObj.picArr;
// console.log('picArr: ', picArr);
if (!picArr || picArr.length == 0) {
const bgItem = {
rect: {
height: 472,
width: 839.8576512455516,
x: 222.57117437722422,
y: 0
},
url: 'assets/play/default/pic.jpg'
};
const hotZoneItemArr = [
{
index: 0,
key: '1575362511657',
rect: {
height: 103.49,
width: 115.49,
x: 481.21,
y: 316
}
},
{
index: 1,
key: '1575362515047',
rect: {
height: 119.08,
width: 119.08,
x: 257.3,
y: 312.99
}
},
{
index: 2,
key: '1575363832858',
rect: {
height: 107.35,
width: 108.66,
x: 415.77,
y: 199
}
},
{
index: 3,
key: '1575515846460',
rect: {
height: 103,
width: 103,
x: 709.43,
y: 319.5
}
}
];
let picArr = [];
for (let i = 0; i < 3; i++) {
const pic = {};
const options = JSON.parse(JSON.stringify(hotZoneItemArr));
switch (i) {
case 0:
options[0].checked = true;
pic['text'] = 'Where is the pig ?';
break;
case 1:
options[1].checked = true;
pic['text'] = 'Where is the fish ?';
break;
case 2:
options[2].checked = true;
options[3].checked = true;
pic['text'] = 'Please find the fruit .';
break;
}
pic['options'] = options;
picArr.push(pic);
}
//
// const picArr = [];
// for (let i = 0; i < 2; i++) {
// picArr.push({
// 'pic_url': 'assets/play/default/pic.jpg',
// 'audio_url': 'assets/play/default/audio.mp3'
// });
// }
this.data.contentObj.picArr = picArr;
this.data.contentObj.bgItem = bgItem;
this.data.contentObj.hotZoneItemArr = hotZoneItemArr;
}
}
ngOnDestroy() {
window['curCtx'] = null;
window.cancelAnimationFrame(this.animationId);
this.gameEndFlag = true;
}
initData() {
this.canvasWidth = this.wrap.nativeElement.clientWidth;
this.canvasHeight = this.wrap.nativeElement.clientHeight;
this.canvas.nativeElement.width = this.wrap.nativeElement.clientWidth;
this.canvas.nativeElement.height = this.wrap.nativeElement.clientHeight;
const sx = this.canvasWidth / this.canvasBaseW;
const sy = this.canvasHeight / this.canvasBaseH;
const s = Math.min(sx, sy);
this.mapScale = s;
this.renderArr = [];
this.coverPageArr = [];
console.log(' in initData', this.data);
this.canTouch = true;
this.curPageIndex = 0;
this.endPageArr = [];
this.shadowArr = [];
this.starBgArr = [];
if (!this.data.contentObj.picArr) {
this.data.contentObj.picArr = [];
}
this.picArr = this.data.contentObj.picArr;
this.picIndex = 0;
}
initAudio() {
const contentObj = this.data.contentObj;
if (!contentObj) {
return;
}
const addUrlToAudioObj = (audioUrl) => {
if (audioUrl) {
// console.log('audioUrl:', audioUrl);
const audio = new Audio();
audio.src = audioUrl;
audio.load();
this.audioObj[audioUrl] = audio;
}
};
let arr = contentObj.picArr;
if (arr) {
// console.log('arr: ', arr);
for (let i = 0; i < arr.length; i++) {
addUrlToAudioObj(arr[i].audio_url);
}
}
const audioObj = this.audioObj;
const addOneAudio = (key, url, vlomue = 1, loop = false, callback = null) => {
const audio = new Audio();
audio.src = url;
audio.load();
audio.loop = loop;
audio.volume = vlomue;
audioObj[key] = audio;
if (callback) {
audio.onended = () => {
callback();
};
}
};
addOneAudio('click', this.rawAudios.get('click'), 0.3);
addOneAudio('right', this.rawAudios.get('right'), 0.3);
addOneAudio('wrong', this.rawAudios.get('wrong'), 0.3);
addOneAudio('star', this.rawAudios.get('star'), 1);
addOneAudio('tip', this.rawAudios.get('tip'), 0.3);
addOneAudio('finish', this.rawAudios.get('finish'), 0.5);
}
initImg() {
const contentObj = this.data.contentObj;
if (contentObj) {
const addPicUrl = (url) => {
if (url) {
this.rawImages.set(url, url);
}
};
let arr = this.data.contentObj.picArr;
if (arr) {
for (let i = 0; i < arr.length; i++) {
addPicUrl(arr[i].pic_url);
}
}
addPicUrl(contentObj.bgItem.url);
}
// 预加载资源
this.loadResources().then(() => {
// this.setfontData();
window['air'].hideAirClassLoading(this.KEY, this.data);
this.init();
this.update();
});
}
initFontImg() {
// const fontbaseUrlW = 'assets/mechanical/letter/';
// const fontDataW = {};
//
// let num = 97;
// for (let i = 0; i < 26; i++) {
//
// const key = String.fromCharCode(num + i); // 'a'
// const url = fontbaseUrlW + key + '.png';
//
// this.rawImages.set(url, url);
// fontDataW[key] = url;
// }
//
//
// this.fontDataW = fontDataW;
}
setfontData() {
// for (let key in this.fontDataW) {
// this.fontDataW[key] = this.images.get(this.fontDataW[key]);
// }
}
init() {
this.initData();
this.initCtx();
this.initView();
}
initCtx() {
this.ctx = this.canvas.nativeElement.getContext('2d');
this.canvas.nativeElement.width = this.canvasWidth;
this.canvas.nativeElement.height = this.canvasHeight;
window['curCtx'] = this.ctx;
}
initView() {
this.initBg();
this.initHotZone();
this.initPic();
this.initTitle();
this.initLight();
this.refreshAnswerNum();
this.initCover();
this.initTeacherPage();
}
teacherPageArr;
// 这里存放的是数据
scoreDataArr;
// 这里存放的是最后ui的映射
teacherPageListArr;
teacherPage;
arrowL;
arrowR;
teacherPageLabel;
curTeacherPage = 1;
initTeacherPage() {
this.teacherPageArr = [];
this.scoreDataArr = [];
this.teacherPageListArr = [];
const bg = new MySprite();
bg.init(this.images.get('bg'));
bg.x = this.canvasWidth / 2;
bg.y = this.canvasHeight / 2;
const sx = this.canvasWidth / bg.width;
const sy = this.canvasHeight / bg.height;
const s = Math.max(sx, sy);
bg.setScaleXY(s);
bg.visible = false;
this.teacherPage = bg;
this.teacherPageArr.push(bg);
const w = 600;
const h = 500;
const lineW = 4 * this.mapScale;
const frame = new ShapeRectNew();
frame.setSize(w, h, 20 * this.mapScale);
frame.fill = false;
frame.setOutLine('#ffffff', lineW);
frame.setScaleXY(this.mapScale);
frame.x = this.canvasWidth / 2 - w * this.mapScale / 2;
frame.y = this.canvasHeight / 2 - h * this.mapScale / 2 - 20 * this.mapScale;
this.teacherPageArr.push(frame);
const pageShowNum = 5;
const itemH = h - lineW;
const baseY = lineW / 2;
for (let i = 0; i < pageShowNum; i++) {
const listItem = new ShapeRect();
listItem.setSize(w * 0.96, itemH / pageShowNum * 1);
listItem.x = (w - listItem.width) / 2;
listItem.y = baseY + i * itemH / pageShowNum;
listItem.alpha = 0;
frame.addChild(listItem);
const labelNum = new Label();
labelNum.textAlign = 'center';
labelNum.fontColor = '#ffffff';
labelNum.fontName = 'BRLNSDB';
labelNum.fontSize = 50;
labelNum.text = i.toString();
labelNum.x = 50;
labelNum.y = listItem.height / 2;
listItem.addChild(labelNum);
const labelName = new Label();
labelName.textAlign = 'center';
labelName.fontColor = '#ffffff';
// labelName.fontName = 'BRLNSDB';
labelName.fontSize = 40;
labelName.text = '张三';
labelName.x = 220;
labelName.y = listItem.height / 2;
listItem.addChild(labelName);
const labelScore = new Label();
labelScore.textAlign = 'center';
labelScore.fontColor = '#ffffff';
// labelScore.fontName = 'BRLNSDB';
labelScore.fontSize = 35;
labelScore.text = Math.floor(Math.random() * 100).toString();
labelScore.x = 410;
labelScore.y = listItem.height / 2;
listItem.addChild(labelScore);
const labelFinish = new MySprite();
labelFinish.init(this.images.get('t_right'));
labelFinish.setScaleXY(0.07);
labelFinish.x = listItem.width - 30;
labelFinish.y = listItem.height / 2;
listItem.addChild(labelFinish);
if (i != pageShowNum - 1) {
const line = new ShapeRect();
line.setSize(listItem.width, lineW);
line.fillColor = '#ffffff';
line.y = listItem.height;
listItem.addChild(line);
}
listItem['num'] = labelNum;
listItem['name'] = labelName;
listItem['score'] = labelScore;
listItem['finish'] = labelFinish;
labelNum.visible = false;
labelName.visible = false;
labelScore.visible = false;
labelFinish.visible = false;
this.teacherPageListArr.push(listItem);
}
const arrowL = new MySprite();
arrowL.init(this.images.get('t_arrow'));
arrowL.setScaleXY(this.mapScale * 0.17);
arrowL.x = this.canvasWidth / 2 - w * 0.3 * this.mapScale;
arrowL.y = frame.y + frame.height * frame.scaleY + 50 * this.mapScale;
this.arrowL = arrowL;
this.teacherPageArr.push(arrowL);
const arrowR = new MySprite();
arrowR.init(this.images.get('t_arrow'));
arrowR.setScaleXY(this.mapScale * 0.17);
arrowR.x = this.canvasWidth / 2 + w * 0.3 * this.mapScale;
arrowR.y = frame.y + frame.height * frame.scaleY + 50 * this.mapScale;
arrowR.scaleX *= -1;
this.arrowR = arrowR;
this.teacherPageArr.push(arrowR);
const pageLabel = new Label();
pageLabel.textAlign = 'center';
pageLabel.fontColor = '#ffffff';
pageLabel.fontName = 'BRLNSDB';
pageLabel.fontSize = 40 * this.mapScale;
pageLabel.text = '1 / 1';
pageLabel.x = this.canvasWidth / 2;
pageLabel.y = arrowL.y;
this.teacherPageLabel = pageLabel;
this.teacherPageArr.push(pageLabel);
this.curTeacherPage = 1;
}
initTitle() {
const label = new Label();
label.fontSize = 42 * this.mapScale;
label.fontName = 'BRLNSDB';
label.textAlign = 'center';
label.setMaxSize(this.canvasWidth * 0.9);
label.x = this.canvasWidth / 2;
label.y = (this.bgRect.y - this.bgRect.height / 2 * this.bgRect.scaleY) / 2;
label.fontColor = '#fff143';
label.setShadow(0, 5, 5, 'rgba(0,0,0,0.3)');
this.titleLabel = label;
this.renderArr.push(label);
const disH = 5 * this.mapScale;
const starBg = new MySprite();
starBg.init(this.images.get('top_star_bg'));
starBg.setScaleXY(this.mapScale);
const disW = starBg.width / 3 * starBg.scaleX;
const num = this.picArr.length;
const itemW = starBg.width * starBg.scaleX;
const totalW = (starBg.width) * starBg.scaleX * num + disW * (num - 1);
const offX = this.canvasWidth / 2 - totalW / 2 + itemW / 2;
this.starBgArr = [];
for (let i = 0; i < num; i++) {
const starBg = new MySprite();
starBg.init(this.images.get('top_star_bg'));
starBg.setScaleXY(this.mapScale);
starBg.x = offX + (itemW + disW) * i;
starBg.y = label.y - starBg.height / 2 * starBg.scaleY - disH / 2;
this.renderArr.push(starBg);
const star = new MySprite();
star.init(this.images.get('top_star'));
star.visible = false;
starBg['star'] = star;
starBg.addChild(star);
this.starBgArr.push(starBg);
}
label.y += label.height / 2 * label.scaleY + disH / 2;
// const textBg = new MySprite();
// textBg.init(this.images.get('text_bg'));
// textBg.setScaleXY(this.mapScale);
// textBg.x = label.x;
// textBg.y = label.y - textBg.height / 2 * textBg.scaleY - disH / 2;
// this.renderArr.push(textBg);
//
// label.y += label.height / 2 * label.scaleY + disH / 2;
//
//
// const pageLabel = new Label();
// pageLabel.text = '0 / 0';
// pageLabel.fontName = 'BRLNSDB';
// pageLabel.fontColor = '#ffffff';
// pageLabel.textAlign = 'center';
// pageLabel.fontSize = 24;
// textBg.addChild(pageLabel);
//
// this.pageLabel = pageLabel;
this.refreshTitleLabel();
this.refreshPageLabel();
}
refreshTitleLabel(animaFlag = false) {
const data = this.picArr[this.curPageIndex];
if (animaFlag) {
hideItem(this.titleLabel, 0.2, () => {
this.titleLabel.text = data.text;
showItem(this.titleLabel, 0.3);
this.playAudio('tip', true);
});
} else {
this.titleLabel.text = data.text;
}
}
refreshPageLabel() {
// const label = this.pageLabel;
// label.text = (this.curPageIndex + 1) + ' / ' + this.picArr.length;
for (let i = 0; i < this.curPageIndex; i++) {
const starBg = this.starBgArr[i];
if (starBg) {
const star = starBg.star;
if (!star.visible) {
star.visible = true;
star.setScaleXY(3);
star.alpha = 0;
tweenChange(star, {scaleX: 1, scaleY: 1, alpha: 1}, 1, () => {
}, TWEEN.Easing.Exponential.In);
}
}
}
} }
// console.log('data:' , data);
// 初始化 各事件监听 showAudio() {
this.initListener(); const data = this.picArr[this.curPageIndex];
const audio = this.audioObj[data.audio_url];
if (audio) {
audio.play();
}
}
initPic() {
}
initLight() {
const light = new LineRect();
light.init();
light.visible = false;
light.setShadow(0, 0, 15 * this.mapScale, 'rgba(255, 255, 0, 1)');
light.lineWidth = 7 * this.mapScale;
this.light = light;
this.renderArr.push(light);
}
initBg() {
this.bgArr = [];
const bg = new MySprite();
bg.init(this.images.get('bg'));
bg.x = this.canvasWidth / 2;
bg.y = this.canvasHeight / 2;
let sx = this.canvasWidth / bg.width;
let sy = this.canvasHeight / bg.height;
let s = Math.max(sx, sy);
bg.setScaleXY(s);
this.renderArr.push(bg);
const bgItem = new MySprite();
bgItem.init(this.images.get(this.data.contentObj.bgItem.url));
bgItem.x = this.canvasWidth / 2;
bgItem.y = this.canvasHeight / 10 * 5.5;
const maxW = this.canvasWidth * 0.9;
const maxH = this.canvasHeight * 0.8;
sx = maxW / bgItem.width;
sy = maxH / bgItem.height;
s = Math.min(sx, sy);
bgItem.setScaleXY(s);
bgItem.setShadow(5, 5, 10);
// bgItem.setShadow(15, 15, 20, 'rgba(0,0,0,0.5)');
this.bg = bgItem;
const edge = 20;
const shapeRect = new ShapeRect();
shapeRect.init();
shapeRect.setSize(bgItem.width * bgItem.scaleX + edge * this.mapScale, bgItem.height * bgItem.scaleY + edge * this.mapScale);
shapeRect.fillColor = '#ffffff';
shapeRect.setShadow(0, 5, 10);
shapeRect.x = bgItem.x;
shapeRect.y = bgItem.y;
this.bgRect = shapeRect;
this.renderArr.push(shapeRect);
bgItem.x = 0;
bgItem.y = 0;
shapeRect.addChild(bgItem);
// this.renderArr.push(bgItem);
const particleLayer = new MySprite();
particleLayer.width = this.canvasWidth;
particleLayer.height = this.canvasHeight;
this.particleLayer = particleLayer;
}
sendServerEvent(key, data = null) {
console.log(`event: ${key}, data: ${data}`);
const c = (<any> window).courseware;
c.sendEvent(key, data);
}
totalTeacherPage = 1;
addTeacherPageData(data) {
let hasFlag = false;
for (let i = 0; i < this.scoreDataArr.length; i++) {
if (data.user.uuid == this.scoreDataArr[i].user.uuid) {
data.updateTime = new Date().getTime();
this.scoreDataArr[i] = data;
hasFlag = true;
break;
}
}
if (!hasFlag) {
this.scoreDataArr.push(data);
}
this.scoreDataArr.sort((a, b) => {
if (a.score == b.score) {
return a.updateTime - b.updateTime;
} else {
return b.score - a.score;
}
});
const pageListNum = 5;
this.totalTeacherPage = Math.ceil(this.scoreDataArr.length / pageListNum);
this.refreshTeacherPage();
console.log('this.scoreDataArr.length:', this.scoreDataArr.length);
}
refreshTeacherPage() {
const pageNum = 5;
const startIndex = (this.curTeacherPage - 1) * pageNum;
const dataArr = this.scoreDataArr.slice(startIndex, startIndex + pageNum);
for (let i = 0; i < this.teacherPageListArr.length; i++) {
const list = this.teacherPageListArr[i];
if (dataArr[i]) {
list.num.visible = true;
list.name.visible = true;
list.score.visible = true;
list.finish.visible = dataArr[i].finish;
list.num.text = startIndex + i + 1;
list.name.text = dataArr[i].user.nick_name.toString();
list.score.text = dataArr[i].score.toString();
} else {
list.num.visible = false;
list.name.visible = false;
list.score.visible = false;
list.finish.visible = false;
}
}
this.teacherPageLabel.text = this.curTeacherPage + ' / ' + this.totalTeacherPage;
}
changePage(value) {
if (value < 0 && this.curTeacherPage > 1) {
this.curTeacherPage--;
this.refreshTeacherPage();
}
if (value > 0 && this.curTeacherPage < this.totalTeacherPage) {
this.curTeacherPage++;
this.refreshTeacherPage();
}
}
addServerListener() {
const c = (<any> window).courseware;
const that = this;
if (this.teachFlag) {
c.onEvent('start_game', function() {
console.log('show teacher page');
that.isGaming = true;
that.teacherPage.visible = true;
});
c.onEvent('score_data', function(data) {
that.addTeacherPageData(data);
});
} else {
c.onEvent('start_game', function() {
that.isGaming = true;
});
// todo 学生的游戏开始
}
}
// todo
mapDown(event) {
(window as any).test = this;
// 如果游戏未开始,并且是老师身份,则点击时开始游戏
if (!this.isGaming && this.teachFlag && this.checkClickTarget(this.startBtn)) {
this.sendServerEvent('start_game', {});
return;
}
if (!this.isGaming) {
return;
}
if (!this.canTouch) {
return;
}
if (this.teacherPage.visible) {
if (this.checkClickTarget(this.arrowL)) {
this.changePage(-1);
} else if (this.checkClickTarget(this.arrowR)) {
this.changePage(1);
}
return;
}
if (this.teachFlag) {
return;
}
for (let i = 0; i < this.hotZoneArr.length; i++) {
if (this.checkClickTarget(this.hotZoneArr[i])) {
this.clickHotZone(i);
return;
}
}
this.clickWrong();
}
mapMove(event) {
}
mapUp(event) {
}
clickHotZone(index) {
if (this.clickedSuccessArr.indexOf(index) != -1) {
console.log('return');
this.canTouch = true;
return;
}
this.clickedSuccessArr.push(index);
const data = this.picArr[this.curPageIndex];
const options = data.options;
if (options[index] && options[index].checked) {
console.log('right');
this.showFrame(index);
} else {
console.log('wrong');
this.clickWrong();
}
}
clickWrong() {
this.playAudio('wrong', true);
shake(this.bgRect, 0.5, () => {
this.canTouch = true;
});
}
showFrame(index) {
this.playAudio('right', true);
const light = this.light;
light.setScaleXY(0);
light.alpha = 0;
light.visible = true;
const hotZone = this.hotZoneArr[index];
const px = hotZone.x + hotZone.width / 2;
const py = hotZone.y + hotZone.height / 2;
light.x = px;
light.y = py;
const edge = 48;
light.setSize(hotZone.width, hotZone.height);
tweenChange(light, {
scaleX: 1, // hotZone.width / (light.width - edge * 2),
scaleY: 1, // hotZone.height / (light.height - edge * 2),
alpha: 1
}, 0.5, () => {
setTimeout(() => {
hideItem(light, 0.3, () => {
}, TWEEN.Easing.Quadratic.In);
}, 200);
}, TWEEN.Easing.Quadratic.Out);
setTimeout(() => {
this.playAudio('star', true);
showPopParticle(this.images.get('star'), {x: px, y: py},
this.particleLayer, 20, 50 * this.mapScale, 100 * this.mapScale, 1);
}, 400);
setTimeout(() => {
this.showShadow(hotZone);
}, 1000);
}
showShadow(hotZone) {
const shadow = new MySprite();
shadow.init(this.images.get('shadow'));
shadow.alpha = 0;
shadow.x = hotZone.x + hotZone.width / 2;
shadow.y = hotZone.y + hotZone.height / 2;
shadow.childDepandAlpha = true;
this.renderArr.push(shadow);
const lineRect = new LineRect();
lineRect.init();
lineRect.lineWidth = 2 * this.mapScale;
lineRect.lineColor = '#c2ff39';
lineRect.setSize(hotZone.width - lineRect.lineWidth, hotZone.height - lineRect.lineWidth);
shadow.addChild(lineRect);
const sx = hotZone.width / (shadow.width - 360);
const sy = hotZone.height / (shadow.height - 360);
shadow.scaleX = sx;
shadow.scaleY = sy;
lineRect.scaleX = 1 / sx;
lineRect.scaleY = 1 / sy;
showItem(shadow, 0.5, () => {
this.checkGameEnd();
});
this.shadowArr.push(shadow);
}
checkGameEnd() {
this.answerCurrent++;
if (this.answerCurrent < this.answerTarget) {
this.canTouch = true;
return;
}
this.curPageIndex++;
this.refreshPageLabel();
if (this.curPageIndex >= this.picArr.length) {
this.gameEnd();
return;
}
setTimeout(() => {
// if (this.curPageIndex >= this.picArr.length) {
// this.gameEnd();
// return;
// }
for (let i = 0; i < this.shadowArr.length; i++) {
const shadow = this.shadowArr[i];
hideItem(shadow, 0.2, () => {
removeItemFromArr(this.renderArr, shadow);
});
}
this.shadowArr = [];
// this.refreshPageLabel();
this.refreshTitleLabel(true);
this.refreshAnswerNum();
this.canTouch = true;
}, 2500);
}
refreshAnswerNum() {
this.answerCurrent = 0;
this.answerTarget = 0;
this.clickedSuccessArr = [];
const data = this.picArr[this.curPageIndex];
const options = data.options;
console.log('options: ', options);
for (let i = 0; i < options.length; i++) {
// console.log('options:', options[i]);
if (options[i].checked) {
this.answerTarget++;
}
}
}
gameEnd() {
this.playAudio('finish', true);
this.showEndPetal();
setTimeout(() => {
this.showPetalFlag = false;
}, 5000);
}
update() {
this.animationId = window.requestAnimationFrame(this.update.bind(this));
// 清除画布内容
this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
TWEEN.update();
this.updateArr(this.renderArr);
this.updateItem(this.particleLayer);
this.updateArr(this.endPageArr);
if (!this.isGaming) {
this.updateArr(this.coverPageArr);
}
if (this.isGaming && this.teachFlag) {
this.updateArr(this.teacherPageArr);
}
}
updateItem(item) {
if (item) {
item.update();
}
}
updateArr(arr) {
if (!arr) {
return;
}
for (let i = 0; i < arr.length; i++) {
arr[i].update(this);
}
}
initHotZone() {
let curBgRect;
if (this.bg) {
curBgRect = this.bg.getBoundingBox();
}
let oldBgRect = this.data.contentObj.bgItem.rect;
if (!oldBgRect) {
oldBgRect = curBgRect;
}
const rate = curBgRect.width / oldBgRect.width;
// this.imgArr = [];
// const arr = this.data.contentObj.imgItemArr;
this.hotZoneArr = [];
const arr = this.data.contentObj.hotZoneItemArr;
if (!arr) {
return;
}
for (let i = 0; i < arr.length; i++) {
const data = JSON.parse(JSON.stringify(arr[i]));
// const img = {pic_url: data.pic_url};
// 若无数据 则为预览模式 需要填充一些默认数据用来显示 data.rect.x *= rate;
this.initDefaultData(); data.rect.y *= rate;
data.rect.width *= rate;
data.rect.height *= rate;
// 初始化 音频资源 data.rect.x += curBgRect.x;
this.initAudio(); data.rect.y += curBgRect.y;
// 初始化 图片资源
this.initImg();
// 开始预加载资源
this.load();
}, this.saveKey); const hotZone = this.getHotZoneItem(data);
hotZone.alpha = 0;
this.hotZoneArr.push(hotZone);
} }
ngOnDestroy() {
window['curCtx'] = null;
window.cancelAnimationFrame(this.animationId);
} }
load() { getHotZoneItem(data) {
const saveRect = data.rect;
const item = new ShapeRect(this.ctx);
item.setSize(saveRect.width, saveRect.height);
item.x = saveRect.x;
item.y = saveRect.y;
item['data'] = data;
// 预加载资源 this.renderArr.push(item);
this.loadResources().then(() => {
window["air"].hideAirClassLoading(this.saveKey, this.data); return item;
this.init();
this.update();
});
} }
init() { showEndPetal() {
this.endPageArr = [];
this.showPetalFlag = true;
this.addPetal();
}
this.initCtx(); stopEndPetal() {
this.initData(); this.endPageArr = [];
this.initView(); this.showPetalFlag = false;
} }
initCtx() { addPetal() {
this.canvasWidth = this.wrap.nativeElement.clientWidth;
this.canvasHeight = this.wrap.nativeElement.clientHeight; if (!this.showPetalFlag) {
this.canvas.nativeElement.width = this.wrap.nativeElement.clientWidth; return;
this.canvas.nativeElement.height = this.wrap.nativeElement.clientHeight; }
const petal = this.getPetal();
this.endPageArr.push(petal);
this.ctx = this.canvas.nativeElement.getContext('2d'); moveItem(petal, petal.x, this.canvasHeight + petal.height * petal.scaleY, petal['time'], () => {
this.canvas.nativeElement.width = this.canvasWidth; removeItemFromArr(this.endPageArr, petal);
this.canvas.nativeElement.height = this.canvasHeight; });
window['curCtx'] = this.ctx; rotateItem(petal, petal['tr'], petal['time']);
}
setTimeout(() => {
this.addPetal();
}, 100);
}
getPetal() {
const petal = new MySprite(this.ctx);
updateItem(item) { const id = Math.ceil(Math.random() * 3);
if (item) { petal.init(this.images.get('petal_' + id));
item.update();
}
}
updateArr(arr) { const randomS = (Math.random() * 0.4 + 0.6) * this.mapScale;
if (!arr) { petal.setScaleXY(randomS);
return;
}
for (let i = 0; i < arr.length; i++) {
arr[i].update(this);
}
}
const randomR = Math.random() * 360;
petal.rotation = randomR;
const randomX = Math.random() * this.canvasWidth;
petal.x = randomX;
petal.y = -petal.height / 2 * petal.scaleY;
const randomT = 0.5 + Math.random() * 2.5;
petal['time'] = randomT;
let randomTR = 360 * Math.random(); // - 180;
if (Math.random() < 0.5) {
randomTR *= -1;
}
petal['tr'] = randomTR;
return petal;
}
initListener() { initListener() {
...@@ -209,6 +1328,7 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -209,6 +1328,7 @@ export class PlayComponent implements OnInit, OnDestroy {
firstTouch = false; firstTouch = false;
removeMouseListener(); removeMouseListener();
} }
console.log('touch down');
setMxMyByTouch(e); setMxMyByTouch(e);
this.mapDown(e); this.mapDown(e);
}; };
...@@ -226,6 +1346,7 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -226,6 +1346,7 @@ export class PlayComponent implements OnInit, OnDestroy {
firstTouch = false; firstTouch = false;
removeTouchListener(); removeTouchListener();
} }
console.log('mouse down');
setMxMyByMouse(e); setMxMyByMouse(e);
this.mapDown(e); this.mapDown(e);
}; };
...@@ -289,6 +1410,40 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -289,6 +1410,40 @@ export class PlayComponent implements OnInit, OnDestroy {
} }
showArr(arr) {
if (!arr) {
return;
}
for (let i = 0; i < arr.length; i++) {
arr[i].visible = true;
}
}
hideArr(arr) {
if (!arr) {
return;
}
for (let i = 0; i < arr.length; i++) {
arr[i].visible = false;
}
}
IsPC() {
if (window['ELECTRON']) {
return false; // 封装客户端标记
}
if (document.body.ontouchmove !== undefined && document.body.ontouchmove !== undefined) {
return false;
} else {
return true;
}
}
loadResources() { loadResources() {
const pr = []; const pr = [];
...@@ -303,7 +1458,7 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -303,7 +1458,7 @@ export class PlayComponent implements OnInit, OnDestroy {
pr.push(p); pr.push(p);
}); });
this.rawAudios.forEach((value, key) => {// 预加载音频 this.rawAudios.forEach((value, key) => {// 预加载图片
const a = this.preloadAudio(value) const a = this.preloadAudio(value)
.then(() => { .then(() => {
...@@ -348,9 +1503,6 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -348,9 +1503,6 @@ export class PlayComponent implements OnInit, OnDestroy {
} }
checkClickTarget(target) { checkClickTarget(target) {
const rect = target.getBoundingBox(); const rect = target.getBoundingBox();
...@@ -383,297 +1535,22 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -383,297 +1535,22 @@ export class PlayComponent implements OnInit, OnDestroy {
return false; return false;
} }
getPosByAngle(angle, len) {
const radian = angle * Math.PI / 180;
const x = Math.sin(radian) * len;
const y = Math.cos(radian) * len;
return {x, y};
addUrlToAudioObj(key, url = null, vlomue = 1, loop = false, callback = null) {
const audioObj = this.audioObj;
if (url == null) {
url = key;
}
this.rawAudios.set(key, url);
const audio = new Audio();
audio.src = url;
audio.load();
audio.loop = loop;
audio.volume = vlomue;
audioObj[key] = audio;
if (callback) {
audio.onended = () => {
callback();
};
}
}
addUrlToImages(url) {
this.rawImages.set(url, url);
}
// ======================================================编写区域==========================================================================
/**
* 添加默认数据 便于无数据时的展示
*/
initDefaultData() {
if (!this.data.pic_url) {
this.data.pic_url = 'assets/play/default/pic.jpg';
this.data.pic_url_2 = 'assets/play/default/pic.jpg';
}
}
/**
* 添加预加载图片
*/
initImg() {
this.addUrlToImages(this.data.pic_url);
this.addUrlToImages(this.data.pic_url_2);
}
/**
* 添加预加载音频
*/
initAudio() {
// 音频资源
this.addUrlToAudioObj(this.data.audio_url);
this.addUrlToAudioObj(this.data.audio_url_2);
// 音效
this.addUrlToAudioObj('click', this.rawAudios.get('click'), 0.3);
}
/**
* 初始化数据
*/
initData() {
const sx = this.canvasWidth / this.canvasBaseW;
const sy = this.canvasHeight / this.canvasBaseH;
const s = Math.min(sx, sy);
this.mapScale = s;
// this.mapScale = sx;
// this.mapScale = sy;
this.renderArr = [];
}
/**
* 初始化试图
*/
initView() {
this.initPic();
this.initBottomPart();
}
initBottomPart() {
const btnLeft = new MySprite();
btnLeft.init(this.images.get('btn_left'));
btnLeft.x = this.canvasWidth - 150 * this.mapScale;
btnLeft.y = this.canvasHeight - 100 * this.mapScale;
btnLeft.setScaleXY(this.mapScale);
this.renderArr.push(btnLeft);
this.btnLeft = btnLeft;
const btnRight = new MySprite();
btnRight.init(this.images.get('btn_right'));
btnRight.x = this.canvasWidth - 50 * this.mapScale;
btnRight.y = this.canvasHeight - 100 * this.mapScale;
btnRight.setScaleXY(this.mapScale);
this.renderArr.push(btnRight);
this.btnRight = btnRight;
}
initPic() {
const maxW = this.canvasWidth * 0.7;
const pic1 = new MySprite();
pic1.init(this.images.get(this.data.pic_url));
pic1.x = this.canvasWidth / 2;
pic1.y = this.canvasHeight / 2;
pic1.setScaleXY(maxW / pic1.width);
this.renderArr.push(pic1);
this.pic1 = pic1;
const label1 = new Label();
label1.text = this.data.text;
label1.textAlign = 'center';
label1.fontSize = 50;
label1.fontName = 'BRLNSDB';
label1.fontColor = '#ffffff';
pic1.addChild(label1);
const pic2 = new MySprite();
pic2.init(this.images.get(this.data.pic_url_2));
pic2.x = this.canvasWidth / 2 + this.canvasWidth;
pic2.y = this.canvasHeight / 2;
pic2.setScaleXY(maxW / pic2.width);
this.renderArr.push(pic2);
this.pic2 = pic2;
this.curPic = pic1;
}
btnLeftClicked() {
this.lastPage();
}
btnRightClicked() {
this.nextPage();
}
lastPage() {
if (this.curPic == this.pic1) {
return;
}
this.canTouch = false;
const moveLen = this.canvasWidth;
tweenChange(this.pic1, {x: this.pic1.x + moveLen}, 1);
tweenChange(this.pic2, {x: this.pic2.x + moveLen}, 1, () => {
this.canTouch = true;
this.curPic = this.pic1;
});
}
nextPage() {
if (this.curPic == this.pic2) {
return;
}
this.canTouch = false;
const moveLen = this.canvasWidth;
tweenChange(this.pic1, {x: this.pic1.x - moveLen}, 1);
tweenChange(this.pic2, {x: this.pic2.x - moveLen}, 1, () => {
this.canTouch = true;
this.curPic = this.pic2;
});
}
pic1Clicked() {
this.playAudio(this.data.audio_url);
}
pic2Clicked() {
this.playAudio(this.data.audio_url_2);
}
mapDown(event) {
if (!this.canTouch) {
return;
}
if ( this.checkClickTarget(this.btnLeft) ) {
this.btnLeftClicked();
return;
}
if ( this.checkClickTarget(this.btnRight) ) {
this.btnRightClicked();
return;
}
if ( this.checkClickTarget(this.pic1) ) {
this.pic1Clicked();
return;
}
if ( this.checkClickTarget(this.pic2) ) {
this.pic2Clicked();
return;
}
}
mapMove(event) {
}
mapUp(event) {
} }
getPosDistance(sx, sy, ex, ey) {
const _x = ex - sx;
update() { const _y = ey - sy;
const len = Math.sqrt(Math.pow(_x, 2) + Math.pow(_y, 2));
// ---------------------------------------------------------- return len;
this.animationId = window.requestAnimationFrame(this.update.bind(this));
// 清除画布内容
this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
// tween 更新动画
TWEEN.update();
// ----------------------------------------------------------
this.updateArr(this.renderArr);
} }
} }
...@@ -12,6 +12,8 @@ const res = [ ...@@ -12,6 +12,8 @@ const res = [
['petal_2', "assets/default/petal_2.png"], ['petal_2', "assets/default/petal_2.png"],
['petal_3', "assets/default/petal_3.png"], ['petal_3', "assets/default/petal_3.png"],
['t_right', "assets/play/teacher/right.png"],
['t_arrow', "assets/play/teacher/arrow.png"],
]; ];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment