Commit d446143c authored by liujiaxin's avatar liujiaxin

finish 1

parent 8a51c964
...@@ -30,7 +30,10 @@ ...@@ -30,7 +30,10 @@
], ],
"styles": [ "styles": [
"./node_modules/ng-zorro-antd/ng-zorro-antd.min.css", "./node_modules/ng-zorro-antd/ng-zorro-antd.min.css",
"src/styles.css" "./node_modules/font-awesome/css/font-awesome.css",
"./node_modules/bootstrap/dist/css/bootstrap.min.css",
"./node_modules/animate.css/animate.min.css",
"src/styles.scss"
], ],
"scripts": [] "scripts": []
}, },
......
@import '../style/common_mixin.css';
.model-content {
width: 100%;
height: 100%;
}
<div class="p-box" *ngFor="let word of item.contentObj.wordnum;index as num;">
<nz-card nzTitle="Word Spelling [{{num + 1}} / {{item.contentObj?.wordnum?.length}}]" [nzExtra]="extraTemplate">
<div>
<div class="spelling-box" *ngFor="let box of defaultBoxes; index as i">
<div class="model-content"> <div *ngIf="word.words[i]">
<div class="w-radio"
(click)="select(i,num)">
<div class="r-radio"
[class.green]="word.words[i].selected"></div>
</div>
<input class="p-letter-input" name="Input" type="text" maxlength="4" tabindex="0"
[(ngModel)]="word.words[i].value"
(blur)="inputSave($event)"
(keyup)="keyup($event,word.words[i].value,num);">
<div style="position: absolute; left: 200px; top: 100px; width: 800px;"> </div>
<input type="text" nz-input [(ngModel)]="item.text" (blur)="save()"> </div>
<span class="p-hint">
1. Type letters of word in left <br>
2. Press Enter to confirm <br>
3. Click round point to set 'Missing Letter'
</span>
</div>
<div class="mt-3">
<div class="show" *ngFor="let it of word.words">
<div *ngIf="it.selected" class="blank"><p></p></div>
<div *ngIf="!it.selected"><p>{{it.value}}</p></div>
</div>
</div>
<nz-divider></nz-divider>
<app-upload-image-with-preview
[picUrl]="item.pic_url"
(imageUploaded)="onImageUploadSuccess($event, 'pic_url')"
></app-upload-image-with-preview>
<app-audio-recorder <app-audio-recorder
[audioUrl]="item.audio_url" [audioUrl]="item.contentObj['audio_word']"
(audioUploaded)="onAudioUploadSuccess($event, 'audio_url')" (audioUploaded)="onVocabularyAudioUploadSuccess($event, 'audio_word')"
></app-audio-recorder> ></app-audio-recorder>
<app-custom-hot-zone></app-custom-hot-zone>
<app-upload-video></app-upload-video>
<app-lesson-title-config></app-lesson-title-config>
<!--<div class="p-media-box d-flex">-->
<!--<div>-->
<!--<app-upload-image-with-preview [picId]="word.pic_id"-->
<!--(imageUploaded)="onImageUploadSuccess($event, num)"-->
<!--&gt;</app-upload-image-with-preview>-->
<!--</div>-->
<!--<nz-divider nzType="vertical"></nz-divider>-->
<!--<div>-->
<!--<app-audio-recorder-->
<!--[audioId]="word.spelling_audio"-->
<!--(audioUploaded)="onVocabularyAudioUploadSuccess($event,num)"-->
<!--&gt;</app-audio-recorder>-->
<!--</div>-->
<!--</div>-->
</nz-card>
<ng-template #extraTemplate>
<!--<button nz-button nzType="danger" nz-popconfirm nzTitle="Are you sure ?" (nzOnConfirm)="DeletWord(num)">Delete-->
<!--</button>-->
</ng-template>
</div>
<div nz-row nzType="flex" nzJustify="start" nzAlign="top" >
<div nz-col nzSpan="12">
<div class="show" style="display: flex; flex-direction: column;"
*ngFor="let it of selectedArr; let i = index">
<div style="display: flex; align-items: center">
<p style="margin-left: 0.8rem; margin-right: 50px;">{{it.value}}: </p>
<app-audio-recorder
[audioUrl]="it.audio"
(audioUploaded)="onAudioUploadSuccessSelected($event, i)"
></app-audio-recorder>
</div>
</div>
<div style="display: flex; align-items: center" *ngFor="let it of options; let i = index">
<input class="p-letter-options" type="text" maxlength="4"
[(ngModel)]="options[i].value"
(keyup)="setWrongOptions($event, i)">
<app-audio-recorder
[audioUrl]="it.audio"
(audioUploaded)="onAudioUploadSuccessOptions($event, i)"
></app-audio-recorder>
</div>
</div>
<div nz-col nzSpan="10">
<app-upload-image-with-preview
[picUrl]="item.contentObj.pic_res_id"
(imageUploaded)="onHandleOptionItemImage($event)"
>
</app-upload-image-with-preview>
</div> </div>
</div> </div>
\ No newline at end of file <!--<button nz-button nzType="primary" (click)="AddWord()">-->
<!--+ Add Word-->
<!--</button>-->
p {
margin: 0;
}
.spelling-box {
// width: 2.5rem;
// height: 2.5rem;
display: inline-block;
margin: 0.2rem;
input {
width: 7rem;
height: 2.7rem;
text-align: center;
display: inline-block;
border: 0.1rem solid #888;
line-height: 2.7rem;
font-weight: 900;
font-size: 1.8rem;
}
.r-radio {
width: 0.5rem;
height: 0.5rem;
border: 1px solid #888;
border-radius: 50%;
}
.green {
background-color: #8dd897;
}
.w-radio {
width: 1rem;
height: 1rem;
margin: 20% auto;
border: 1px solid;
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
}
button {
margin-top: 2%;
margin-left: 5%;
}
.show {
display: inline-block;
div {
display: inline;
}
p {
display: block;
line-height: 2.5rem;
border-radius: 15%;
margin: 0 1px;
font-weight: 900;
font-size: 1.8rem;
}
.blank {
border: 2px solid;
margin: 0 3px;
display: inline-block;
width: 5rem;
height: 2.5rem;
border-radius: 10px;
vertical-align: bottom;
}
}
.p-box {
margin-bottom: 1.5rem;
nz-card {
border-radius: 0.5rem;
}
}
.p-letter-input:focus {
border-color: #1eb461 !important;
}
.p-media-box {
& > div:nth-child(1) {
width: 18rem;
}
nz-divider {
height: 10rem;
margin: 0 2rem;
}
}
.p-hint {
margin-left: 1rem;
color: #888;
font-size: 10px;
display: inline-block;
}
.p-letter-options {
display: inline-block;
margin: 0.2rem;
margin-right: 40px;
width: 7rem;
height: 2.7rem;
text-align: center;
border: 0.1rem solid #888;
line-height: 2.7rem;
font-weight: 900;
font-size: 1.8rem;
}
import {Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, ApplicationRef, ChangeDetectorRef} from '@angular/core'; import {Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, ApplicationRef, ChangeDetectorRef} from '@angular/core';
import * as _ from 'lodash';
@Component({ @Component({
selector: 'app-form', selector: 'app-form',
templateUrl: './form.component.html', templateUrl: './form.component.html',
styleUrls: ['./form.component.css'] styleUrls: ['./form.component.scss']
}) })
export class FormComponent implements OnInit, OnChanges, OnDestroy { export class FormComponent implements OnInit, OnChanges, OnDestroy {
// 储存数据用 // 储存数据用
saveKey = "test_0011"; saveKey = 'ww_diamond';
// 储存对象 // 储存对象
item; item;
// originContent;
defaultBoxes = new Array(8);
words = [];
bol: number;
inputs: any;
options = [];
selectedArr = [];
constructor(private appRef: ApplicationRef,private changeDetectorRef: ChangeDetectorRef) {
constructor(private appRef: ApplicationRef,
private changeDetectorRef: ChangeDetectorRef) {
this.bol = 0;
this.inputs = document.getElementsByName('Input');
} }
ngOnInit() { ngOnInit() {
this.item = {}; this.item = {
contentObj: {
}
};
// this.originContent = {...this.item.contentObj};
// 获取存储的数据 // 获取存储的数据
(<any> window).courseware.getData((data) => { (window as any).courseware.getData((data) => {
// this.originContent = {...data.contentObj};
if (data) { if (data) {
this.item = data; this.item = data;
} }
if (!this.item.contentObj.wordnum || !this.item.contentObj.wordnum.length) {
this.item.contentObj.wordnum = [];
this.AddWord();
}
this.init(); this.init();
this.changeDetectorRef.markForCheck(); this.changeDetectorRef.markForCheck();
this.changeDetectorRef.detectChanges(); this.changeDetectorRef.detectChanges();
...@@ -42,6 +58,7 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -42,6 +58,7 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
ngOnChanges() { ngOnChanges() {
} }
ngOnDestroy() { ngOnDestroy() {
...@@ -50,29 +67,30 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -50,29 +67,30 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
init() { init() {
this.options = this.item.contentObj.options || [{value: '', audio: ''}, {value: '', audio: ''}];
this.selectedArr = this.item.contentObj.selectedArr || this.initSelectedArr();
} }
/** // /**
* 储存图片数据 // * 储存图片数据
* @param e // * @param e
*/ // */
onImageUploadSuccess(e, key) { // onImageUploadSuccess(e, key) {
//
this.item[key] = e.url; // this.item[key] = e.url;
this.save(); // this.save();
} // }
/** // /**
* 储存音频数据 // * 储存音频数据
* @param e // * @param e
*/ // */
onAudioUploadSuccess(e, key) { // onAudioUploadSuccess(e, key) {
//
this.item[key] = e.url; // this.item[key] = e.url;
this.save(); // this.save();
} // }
...@@ -80,7 +98,7 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -80,7 +98,7 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
* 储存数据 * 储存数据
*/ */
save() { save() {
(<any> window).courseware.setData(this.item, null, this.saveKey); (window as any).courseware.setData(this.item, null, this.saveKey);
this.refresh(); this.refresh();
} }
...@@ -93,5 +111,163 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -93,5 +111,163 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
}, 1); }, 1);
} }
updateVocabulary() {
this.save();
}
onVocabularyAudioUploadSuccess(e, key) {
this.item.contentObj[key] = e.url;
this.updateVocabulary();
}
onAudioUploadSuccessSelected(e, i) {
this.selectedArr[i].audio = e.url;
this.item.contentObj.selectedArr = this.selectedArr;
this.updateVocabulary();
}
onAudioUploadSuccessOptions(e, i) {
this.options[i].audio = e.url;
this.updateVocabulary();
}
onImageUploadSuccess(e, num) {
this.item.contentObj.wordnum[num].pic_id = e.url;
this.updateVocabulary();
}
keyup(event, value, num) {
const word = _.get(this.item, `contentObj.wordnum[${num}]`);
console.log('event:', event);
if (event.keyCode === 13) {
this.updateVocabulary();
} else {
for (let i = 0; i < this.inputs.length; i++) {
if (event.path[0] === this.inputs[i]) {
if (value !== '' && event.keyCode <= 90 && event.keyCode >= 65) {
if (i === this.inputs.length - 1) {
} else {
if (this.inputs[i].value.length >= this.inputs[i].maxLength) {
this.inputs[i + 1].focus();
}
}
} else {
if (event.key === 'Backspace') {
if (i === 0) {
} else {
if (this.bol !== 1) {
this.bol++;
} else {
word.words[i].selected = false;
this.bol = 0;
this.inputs[i - 1].focus();
}
}
}
}
}
}
}
}
select(i, num) {
const word = _.get(this.item, `contentObj.wordnum[${num}].words[${i}]`);
if (word.value !== '') {
word.selected = !word.selected;
if (!word.selected) {
this.deleteSelectOne(i);
} else {
this.addSelectOne(word.value, i);
}
// this.initSelectedArr();
this.item.contentObj.selectedArr = this.selectedArr;
this.updateVocabulary();
}
}
deleteSelectOne(targetIndex) {
for (let i = 0; i < this.selectedArr.length; i++) {
if (this.selectedArr[i].index === targetIndex) {
this.selectedArr.splice(i, 1);
break;
}
}
}
addSelectOne(value, targetIndex) {
const data = {value, audio: '', index: targetIndex};
this.selectedArr.push(data);
this.selectedArr.sort((a, b) => {
return a.index - b.index;
});
}
initSelectedArr() {
this.selectedArr = [];
if (!this.item.contentObj.wordnum) {
return this.selectedArr;
}
const words = this.item.contentObj.wordnum[0].words;
for (let i = 0; i < words.length; i++) {
if (words[i].selected) {
this.selectedArr.push( {value: words[i].value, audio: '', index: i} );
}
}
this.item.contentObj.selectedArr = this.selectedArr;
return this.selectedArr;
}
AddWord() {
this.words = [];
for (let i = 0; i < 15; i++) {
this.words.push({
value: '',
selected: false
});
}
this.item.contentObj.wordnum.push({
words: this.words,
spelling_audio: '',
pic_id: ''
});
}
DeletWord(num) {
this.item.contentObj.wordnum.splice(num, 1);
this.updateVocabulary();
}
setWrongOptions(e, i) {
this.item.contentObj.options = this.options;
this.updateVocabulary();
}
onHandleOptionItemImage(e) {
this.item.contentObj.pic_res_id = e.url;
this.updateVocabulary();
}
inputSave(e) {
}
} }
...@@ -7,7 +7,7 @@ interface AirWindow extends Window { ...@@ -7,7 +7,7 @@ interface AirWindow extends Window {
} }
declare let window: AirWindow; declare let window: AirWindow;
class Sprite { export class Sprite {
x = 0; x = 0;
y = 0; y = 0;
color = ''; color = '';
......
export function tAngle(target, base) {
const radians = Math.atan2(base.y - target.y, target.x - base.x);
return radians * 180 / Math.PI; // degrees
}
export function circleCollide(c1, c2) {
const dx = Math.abs(c1.x - c2.x);
const dy = Math.abs(c1.y - c2.y);
const dist = Math.sqrt(dx * dx + dy * dy);
return dist < c1.radius + c2.radius;
}
export function shuffle(arr){
if (!arr) {
return [];
}
const temp = [...arr];
const result = [];
let random;
while(temp.length > 0){
random = Math.floor(Math.random() * temp.length);
result.push(temp[random]);
temp.splice(random, 1)
}
return result;
}
// export default {
// tAngle,
// circleCollide,
// shuffle
// }
.game-container { .game-container {
width: 100%; width: 100%;
height: 100%; height: 100%;
background: #ffffff; background-image: url("../../assets/diamond/bg.jpg");
//background: #00C0FF;
background-repeat: no-repeat;
background-size: cover; background-size: cover;
} }
#canvas { #canvas {
////background: #222222;
//width: 800px;
//height: 600px;
} }
@font-face @font-face
{ {
font-family: 'BRLNSDB'; font-family: 'RoundedBold';
src: url("../../assets/font/BRLNSDB.TTF") ; src: url("../../assets/font/Arial Rounded Bold.otf") format("opentype");
} }
...@@ -2,16 +2,344 @@ import {Component, ElementRef, ViewChild, OnInit, Input, OnDestroy, HostListener ...@@ -2,16 +2,344 @@ import {Component, ElementRef, ViewChild, OnInit, Input, OnDestroy, HostListener
import { import {
Label, Label,
MySprite, tweenChange, Sprite, tweenChange
} from './Unit'; } from './Unit';
import {res, resAudio} from './resources'; import res from './resources';
import {Subject} from 'rxjs'; import {Subject} from 'rxjs';
import {debounceTime} from 'rxjs/operators'; import {debounceTime} from 'rxjs/operators';
import TWEEN from '@tweenjs/tween.js'; import TWEEN from '@tweenjs/tween.js';
export class MySpriteBase extends Sprite {
width = 0;
height = 0;
_anchorX = 0;
_anchorY = 0;
_offX = 0;
_offY = 0;
scaleX = 1;
scaleY = 1;
alpha = 1;
rotation = 0;
visible = true;
children = [this];
img;
_z = 0;
init(imgObj = null, anchorX: number = 0.5, anchorY: number = 0.5) {
if (imgObj) {
this.img = imgObj;
this.width = this.img.width;
this.height = this.img.height;
}
this.anchorX = anchorX;
this.anchorY = anchorY;
}
update($event = null) {
if (!this.visible) { return; }
this.draw();
}
draw() {
this.ctx.save();
this.drawImage();
// this.drawOther();
this.ctx.restore();
}
drawImage() {
this.ctx.translate(this.x, this.y);
this.ctx.rotate(this.rotation * Math.PI / 180);
this.ctx.scale(this.scaleX, this.scaleY);
this.ctx.globalAlpha = this.alpha;
this.updateChildren();
// if (this.img) {
// this.ctx.drawImage(this.img, this._offX, this._offY);
// }
}
updateChildren() {
if (this.children.length <= 0) { return; }
for (let i = 0; i < this.children.length; i++) {
if (this.children[i] === this) {
if (this.img) {
this.ctx.drawImage(this.img, this._offX, this._offY);
}
} else {
this.children[i].update();
}
}
}
addChild(child, z = 1) {
if (this.children.indexOf(child) === -1) {
this.children.push(child);
child._z = z;
}
this.children.sort((a, b) => {
// if (a === this) {
// return b._z;
// } else if (b === this) {
// return a._z;
// }
return a._z - b._z;
});
}
removeChild(child) {
const index = this.children.indexOf(child);
if (index !== -1) {
this.children.splice(index, 1);
}
}
set scale(value) {
this.scaleX = this.scaleY = value;
}
get scale() {
return this.scaleX;
}
set anchorX(value) {
this._anchorX = value;
this.refreshAnchorOff();
}
get anchorX() {
return this._anchorX;
}
set anchorY(value) {
this._anchorY = value;
this.refreshAnchorOff();
}
get anchorY() {
return this._anchorY;
}
refreshAnchorOff() {
this._offX = -this.width * this.anchorX;
this._offY = -this.height * this.anchorY;
}
getBoundingBox() {
const x = this.x + this._offX * this.scaleX;
const y = this.y + this._offY * this.scaleY;
const width = this.width * this.scaleX;
const height = this.height * this.scaleY;
return {x, y, width, height};
}
// drawOther() {}
}
export class Diamond extends MySpriteBase {
text = '';
selected = true;
showText = false;
setData(data, showText = true) {
this.text = data.value;
this.selected = data.selected;
this.showText = showText;
}
drawText() {
if (!this.showText) {
return;
}
this.ctx.font = '32px RoundedBold';
this.ctx.textAlign = 'center';
this.ctx.textBaseline = 'middle';
this.ctx.fontWeight = 900;
this.ctx.strokeStyle = '#000000';
this.ctx.fillStyle = '#ffffff';
this.ctx.lineWidth = '5';
this.ctx.strokeText(this.text, 0, 0);
this.ctx.fillText(this.text, 0, 0);
}
drawImage() {
super.drawImage();
this.drawText();
}
// drawOther() {
// this.drawText();
// }
}
export class Lemon extends MySpriteBase {
text;
constructor(ctx, text) {
super(ctx);
this.text = text;
}
init(imgObj, anchorX: number = 0.5, anchorY: number = 0.5) {
super.init(imgObj, anchorX, anchorY);
}
drawText() {
//
this.ctx.font = '25px RoundedBold';
this.ctx.textAlign = 'center';
this.ctx.textBaseline = 'middle';
this.ctx.fontWeight = 900;
this.ctx.strokeStyle = '#ffffff';
this.ctx.lineWidth = '10';
const chr = this.text.split('');
let temp = '';
const row = [];
const w = this.width - 80;
const disH = 30;
for (let a = 0; a < chr.length; a++) {
if (this.ctx.measureText(temp).width < w && this.ctx.measureText(temp + (chr[a])).width <= w) {
temp += chr[a];
} else {
row.push(temp);
temp = chr[a];
}
}
row.push(temp);
const x = 0;
const y = -row.length * disH / 2 - 10;
for (let b = 0 ; b < row.length; b++) {
this.ctx.strokeText(row[b], x, y + ( b + 1 ) * disH ); // 每行字体y坐标间隔20
}
this.ctx.fillStyle = '#8b572a';
for (let b = 0 ; b < row.length; b++) {
this.ctx.fillText(row[b], x, y + ( b + 1 ) * disH ); // 每行字体y坐标间隔20
}
}
drawImage() {
super.drawImage();
this.drawText();
}
hideItem(callBack, t: number = 0.8) {
// console.log(' in hideItem ', this.alpha);
const tween = new TWEEN.Tween(this)
.to({ alpha: 0 }, t * 1000)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(function() {
if (callBack) {
callBack();
}
})
.start(); // Start the tween immediately.
// console.log('tween: ', tween);
}
}
export class Item extends MySpriteBase {
hideItem(callBack = null, t = 0.8) {
const tween = new TWEEN.Tween(this)
.to({ alpha: 0 }, t * 1000)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(function() {
if (callBack) {
callBack();
}
})
.start(); // Start the tween immediately.
}
showItem(callBack = null, t = 0.8) {
const tween = new TWEEN.Tween(this)
.to({ alpha: 1 }, t * 1000)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(function() {
if (callBack) {
callBack();
}
})
.start(); // Start the tween immediately.
}
}
...@@ -21,53 +349,95 @@ import TWEEN from '@tweenjs/tween.js'; ...@@ -21,53 +349,95 @@ import TWEEN from '@tweenjs/tween.js';
styleUrls: ['./play.component.css'] styleUrls: ['./play.component.css']
}) })
export class PlayComponent implements OnInit, OnDestroy { export class PlayComponent implements OnInit, OnDestroy {
saveKey = 'ww_diamond';
@ViewChild('canvas', {static: true }) canvas: ElementRef;
@ViewChild('wrap', {static: true }) wrap: ElementRef;
// 数据 // 数据
targets = [];
colors = [];
data; data;
ctx;
canvasWidth = 1280; // canvas实际宽度
canvasHeight = 720; // canvas实际高度
canvasBaseW = 1280; // canvas 资源预设宽度 @ViewChild('canvas', {static: true}) canvas: ElementRef;
canvasBaseH = 720; // canvas 资源预设高度 @ViewChild('wrap', {static: true}) wrap: ElementRef;
canvasWidth = 1280;
canvasHeight = 576;
canvasBaseW = 1280;
canvasBaseH = 576;
ctx;
fps = 0;
// lastFrameTime = 0;
frametime = 0; // 上一帧动画的时间, 两帧时间差
mx; // 点击x坐标 mx;
my; // 点击y坐标 my; // 点击坐标
// 资源 // 资源
rawImages = new Map(res); rawImages = new Map(res);
rawAudios = new Map(resAudio);
// 声音
bgAudio = new Audio();
successAudio = new Audio();
finishAudio = new Audio();
wrongAudio = new Audio();
images = new Map(); images = new Map();
animationId: any; animationId: any;
winResizeEventStream = new Subject(); winResizeEventStream = new Subject();
audioObj = {};
renderArr; audioObj = {};
mapScale = 1; mapScale = 1;
canvasLeft; canvasLeft;
canvasTop; canvasTop;
pcFlag = true;
renderArr;
saveKey = 'test_0011'; downFlag = false;
moveFlag = false;
btnLeft; DIAMOND_LEN = 110;
btnRight;
pic1;
pic2;
canTouch = true; posArr = [
[299, 506],
[554, 430],
[681, 433],
[765, 507],
[154, 499],
[521, 522]
];
curPic;
gameEndFlag = false;
options;
picFlag = true;
startPx;
startPy;
audioPlaying = false;
diamondColorArr = ['d-red', 'd-yellow', 'd-purple'];
slate;
diamondArr = [];
wordsArr = [];
curDiamond;
selectOptions;
optionsArr = [];
clickedDiamondFlag = false;
endSpr;
@HostListener('window:resize', ['$event']) @HostListener('window:resize', ['$event'])
onResize(event) { onResize(event) {
...@@ -76,602 +446,898 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -76,602 +446,898 @@ export class PlayComponent implements OnInit, OnDestroy {
ngOnInit() { ngOnInit() {
this.data = {}; this.data = {};
// 获取数据 // 获取数据
const getData = (<any> window).courseware.getData; const getData = (window as any).courseware.getData;
getData((data) => { getData((data) => {
if (data && typeof data == 'object') { if (data && typeof data === 'object') {
this.data = data; this.data = data;
} }
// console.log('data:' , data); // console.log('data:' , data);
this.initAudio();
// 初始化 各事件监听 this.initImg();
this.initListener(); this.initListener();
// 若无数据 则为预览模式 需要填充一些默认数据用来显示 }, this.saveKey);
this.initDefaultData();
// 初始化 音频资源
this.initAudio();
// 初始化 图片资源
this.initImg();
// 开始预加载资源
this.load();
}, this.saveKey);
}
ngOnDestroy() {
window['curCtx'] = null;
window.cancelAnimationFrame(this.animationId);
}
load() { }
ngOnDestroy() {
window.cancelAnimationFrame(this.animationId);
this.bgAudio.pause();
}
initData() {
this.canvasWidth = this.wrap.nativeElement.clientWidth;
this.canvasHeight = this.wrap.nativeElement.clientHeight;
this.mapScale = this.canvasHeight / this.canvasBaseH;
// this.itemLen = this.itemLenBase * this.mapScale;
this.renderArr = [];
this.gameEndFlag = false;
this.endSpr = null;
// console.log('this.data:', this.data);
this.selectOptions = [];
if (this.data.contentObj) {
const options = this.data.contentObj.options;
if (options) {
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < options.length; i++) {
// options[i].selected = false;
if (options[i].value) {
this.selectOptions.push(options[i]);
}
}
}
const selectedArr = this.data.contentObj.selectedArr;
if (selectedArr) {
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < selectedArr.length; i++) {
// selectedArr[i].selected = true;
this.selectOptions.push(selectedArr[i]);
}
}
}
if (this.data.contentObj.wordnum && this.data.contentObj.wordnum[0]) {
const words = this.data.contentObj.wordnum[0].words;
if (words) {
this.wordsArr = [];
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < words.length; i++) {
if (words[i].value) {
this.wordsArr.push(words[i]);
}
}
}
}
}
IsPC() {
if (document.body.ontouchstart !== undefined) {
return false;
} else {
return true;
}
}
initAudio() {
const contentObj = this.data.contentObj;
if (!contentObj) { return; }
let options = [];
if (this.data.contentObj && this.data.contentObj.options) {
options = this.data.contentObj.options;
}
let selectedArr = [];
if (this.data.contentObj && this.data.contentObj.selectedArr) {
selectedArr = this.data.contentObj.selectedArr;
}
const arr = options.concat(selectedArr);
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i <= arr.length; i++) {
if (arr[i]) {
const url = arr[i].audio;
if (url) {
const audio = new Audio();
audio.src = url;
// audio.src = contentObj[url];
audio.load();
this.audioObj[url] = audio;
}
}
}
const audioWordUrl = this.data.contentObj.audio_word;
if (audioWordUrl) {
const audio = new Audio();
audio.src = audioWordUrl;
audio.load();
this.audioObj[audioWordUrl] = audio;
}
this.bgAudio.src = 'assets/diamond/music/bg.mp3';
this.bgAudio.load();
this.bgAudio.loop = true;
this.bgAudio.volume = 0.6;
this.finishAudio.src = 'assets/diamond/music/finish.mp3';
this.finishAudio.load();
this.wrongAudio.src = 'assets/diamond/music/wrong.mp3';
this.wrongAudio.load();
this.successAudio.src = 'assets/diamond/music/success.mp3';
this.successAudio.load();
}
initImg() {
const contentObj = this.data.contentObj;
if (!contentObj) { return; }
const url = 'pic_res_id';
if (contentObj[url]) {
// console.log('contentObj[url]:', contentObj[url]);
this.picFlag = true;
this.rawImages.set(url, contentObj[url]);
} else {
this.picFlag = false;
}
// 预加载资源
this.loadResources().then(() => {
this.init();
// this.lastFrameTime = Date.now();
this.igniteLoop();
});
}
init() {
this.initData();
this.initCtx();
this.initItem();
}
initCtx() {
this.ctx = this.canvas.nativeElement.getContext('2d');
this.canvas.nativeElement.width = this.canvasWidth;
this.canvas.nativeElement.height = this.canvasHeight;
}
initItem() {
const paper = new MySpriteBase(this.ctx);
paper.init(this.images.get('paper'));
this.renderArr.push(paper);
paper.scale = this.mapScale * 0.8;
paper.x = this.canvasWidth / 2;
paper.y = 170 * this.mapScale;
if (this.picFlag) {
const pic = new MySpriteBase(this.ctx);
pic.init(this.images.get('pic_res_id'));
paper.addChild(pic);
pic.x = 2;
pic.scaleX = paper.width * 0.32 / pic.width;
pic.scaleY = paper.width * 0.32 / pic.height;
}
const slate = new MySpriteBase(this.ctx);
slate.init(this.images.get('slate'));
this.renderArr.push(slate);
slate.x = paper.x;
slate.y = 350 * this.mapScale;
this.slate = slate;
this.initDiamond();
this.initSelectOptions();
}
initDiamond() {
let curColor;
// let colorIndex = 1;
const len = this.DIAMOND_LEN;
const diamondW = 115;
const lehH = 49;
const words = this.wordsArr;
const offX = -(words.length * len / 2 - len / 2) * this.mapScale + this.canvasWidth / 2;
// console.log('offX:', offX);
const arr = [];
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < words.length; i++) {
curColor = this.getDiamondColor(curColor);
const diamond = new Diamond(this.ctx);
if (words[i].selected) {
diamond.init(this.images.get('question'));
diamond.setData(words[i], false);
this.addQuestionLight(diamond);
} else {
diamond.init(this.images.get(curColor));
diamond.setData(words[i]);
}
arr.push(diamond);
diamond.scale = len / diamondW * this.mapScale;
diamond.x = offX + i * len * this.mapScale;
diamond.y = this.slate.y - (lehH / 2) * this.mapScale;
// @ts-ignore
diamond.baseX = diamond.x;
// @ts-ignore
diamond.baseY = diamond.y;
// @ts-ignore
diamond.audio = this.audioObj[this.data.contentObj.audio_word];
}
this.diamondArr = arr;
}
addQuestionLight(diamond) {
const qLight = new MySpriteBase(this.ctx);
qLight.init(this.images.get('question_light'));
diamond.addChild(qLight);
qLight.visible = false;
diamond.qLight = qLight;
}
getDiamondColor(curColor) {
const colorArr = this.diamondColorArr;
const tmpArr = colorArr.concat();
if (curColor) {
const oldIndex = tmpArr.indexOf(curColor);
tmpArr.splice(oldIndex, 1);
}
const index = Math.floor( Math.random() * tmpArr.length );
return tmpArr[index];
}
initSelectOptions() {
let arr = this.selectOptions;
const tmpOptions = arr.concat();
const newArr = [];
while (tmpOptions.length > 0) {
const randomIndex = Math.floor(Math.random() * tmpOptions.length);
newArr.push(tmpOptions[randomIndex]);
tmpOptions.splice(randomIndex, 1);
}
arr = newArr;
let curColor;
this.optionsArr = [];
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < arr.length; i++) {
curColor = this.getDiamondColor(curColor);
if (this.posArr[i]) {
const diamond = new Diamond(this.ctx);
diamond.init(this.images.get(curColor));
diamond.setData(arr[i]);
this.optionsArr.push(diamond);
diamond.scale = this.DIAMOND_LEN / diamond.width * this.mapScale;
diamond.x = this.posArr[i][0] * this.mapScale;
diamond.y = this.posArr[i][1] * this.mapScale;
// @ts-ignore
diamond.baseX = diamond.x;
// @ts-ignore
diamond.baseY = diamond.y;
this.addDiamondLight(diamond);
if (arr[i].audio) {
// @ts-ignore
diamond.audio = this.audioObj[arr[i].audio];
}
}
// 预加载资源 }
this.loadResources().then(() => {
window["air"].hideAirClassLoading(this.saveKey, this.data);
this.init();
this.update();
});
}
init() {
this.initCtx();
this.initData();
this.initView();
} }
initCtx() { addDiamondLight(diamond) {
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;
this.ctx = this.canvas.nativeElement.getContext('2d'); const light = new MySpriteBase(this.ctx);
this.canvas.nativeElement.width = this.canvasWidth; light.init(this.images.get('light'));
this.canvas.nativeElement.height = this.canvasHeight; diamond.addChild(light, -2);
window['curCtx'] = this.ctx; light.visible = false;
diamond.light = light;
} }
checkTouchDiamond() {
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < this.diamondArr.length; i++) {
// if (!this.diamondArr[i].selected) {
if (this.checkClickTarget(this.diamondArr[i])) {
this.clickedDiamondFlag = true;
return this.diamondArr[i];
}
// }
updateItem(item) {
if (item) {
item.update();
} }
} // tslint:disable-next-line:prefer-for-of
for (let i = 0; i < this.optionsArr.length; i++) {
updateArr(arr) { if (this.checkClickTarget(this.optionsArr[i])) {
if (!arr) { this.clickedDiamondFlag = false;
return; return this.optionsArr[i];
} }
for (let i = 0; i < arr.length; i++) {
arr[i].update(this);
} }
}
return null;
}
checkClickTarget(target) {
const rect = target.getBoundingBox();
if (this.checkPointInRect(this.mx, this.my, rect)) {
return true;
}
return false;
}
initListener() {
this.winResizeEventStream
.pipe(debounceTime(500))
.subscribe(data => {
this.renderAfterResize();
});
hideAllLight() {
// --------------------------------------------- // tslint:disable-next-line:prefer-for-of
const setParentOffset = () => { for (let i = 0; i < this.diamondArr.length; i ++) {
const rect = this.canvas.nativeElement.getBoundingClientRect(); if (this.diamondArr[i].qLight) {
this.canvasLeft = rect.left; this.diamondArr[i].qLight.visible = false;
this.canvasTop = rect.top;
};
const setMxMyByTouch = (event) => {
if (event.touches.length <= 0) {
return;
} }
if (this.canvasLeft == null) { }
setParentOffset();
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < this.optionsArr.length; i ++) {
if (this.optionsArr[i].light) {
this.optionsArr[i].light.visible = false;
} }
this.mx = event.touches[0].pageX - this.canvasLeft; }
this.my = event.touches[0].pageY - this.canvasTop; }
};
const setMxMyByMouse = (event) => {
this.mx = event.offsetX;
this.my = event.offsetY;
};
// ---------------------------------------------
let firstTouch = true;
const touchDownFunc = (e) => {
if (firstTouch) {
firstTouch = false;
removeMouseListener();
}
setMxMyByTouch(e);
this.mapDown(e);
};
const touchMoveFunc = (e) => {
setMxMyByTouch(e);
this.mapMove(e);
};
const touchUpFunc = (e) => {
setMxMyByTouch(e);
this.mapUp(e);
};
const mouseDownFunc = (e) => {
if (firstTouch) {
firstTouch = false;
removeTouchListener();
}
setMxMyByMouse(e);
this.mapDown(e);
};
const mouseMoveFunc = (e) => {
setMxMyByMouse(e);
this.mapMove(e);
};
const mouseUpFunc = (e) => {
setMxMyByMouse(e);
this.mapUp(e);
};
mapDown(event) {
const element = this.canvas.nativeElement; // console.log(' in mapDown:', event);
if (this.gameEndFlag) { return; }
const addTouchListener = () => { this.downFlag = true;
element.addEventListener('touchstart', touchDownFunc);
element.addEventListener('touchmove', touchMoveFunc);
element.addEventListener('touchend', touchUpFunc);
element.addEventListener('touchcancel', touchUpFunc);
};
const removeTouchListener = () => {
element.removeEventListener('touchstart', touchDownFunc);
element.removeEventListener('touchmove', touchMoveFunc);
element.removeEventListener('touchend', touchUpFunc);
element.removeEventListener('touchcancel', touchUpFunc);
};
const addMouseListener = () => { // this.curDiamond = this.checkTouchDiamond();
element.addEventListener('mousedown', mouseDownFunc);
element.addEventListener('mousemove', mouseMoveFunc);
element.addEventListener('mouseup', mouseUpFunc);
};
const removeMouseListener = () => {
element.removeEventListener('mousedown', mouseDownFunc);
element.removeEventListener('mousemove', mouseMoveFunc);
element.removeEventListener('mouseup', mouseUpFunc);
};
addMouseListener(); this.startPx = this.mx;
addTouchListener(); this.startPy = this.my;
}
playAudio(key, now = false, callback = null) {
const audio = this.audioObj[key];
if (audio) {
if (now) {
audio.pause();
audio.currentTime = 0;
}
if (callback) { // --
audio.onended = () => {
callback();
};
}
audio.play();
}
}
loadResources() {
const pr = [];
this.rawImages.forEach((value, key) => {// 预加载图片
const p = this.preload(value) if (this.curDiamond) {
.then(img => { for (let i = 0; i < this.diamondArr.length; i++) {
this.images.set(key, img);
})
.catch(err => console.log(err));
pr.push(p); if (this.diamondArr[i].qLight && !this.diamondArr[i].putEnd) {
});
this.rawAudios.forEach((value, key) => {// 预加载音频 if (this.checkClickTarget(this.diamondArr[i])) {
const a = this.preloadAudio(value) if ( this.diamondArr[i].text === this.curDiamond.text ) {
.then(() => {
// this.images.set(key, img);
})
.catch(err => console.log(err));
pr.push(a); this.hideAllLight();
});
return Promise.all(pr);
}
preload(url) { this.putSuccess(this.diamondArr[i]);
return new Promise((resolve, reject) => {
const img = new Image();
// img.crossOrigin = "anonymous";
img.onload = () => resolve(img);
img.onerror = reject;
img.src = url;
});
}
preloadAudio(url) {
return new Promise((resolve, reject) => {
const audio = new Audio();
audio.oncanplay = (a) => {
resolve();
};
audio.onerror = () => {
reject();
};
audio.src = url;
audio.load();
});
}
} else {
renderAfterResize() { this.wrongAudio.play();
this.canvasWidth = this.wrap.nativeElement.clientWidth; }
this.canvasHeight = this.wrap.nativeElement.clientHeight;
this.init();
}
return;
// if (this.checkPutSuccess()) {
// return;
// }
}
}
}
}
this.hideAllLight();
checkClickTarget(target) {
const rect = target.getBoundingBox(); this.curDiamond = this.checkTouchDiamond();
if (this.checkPointInRect(this.mx, this.my, rect)) { if (this.curDiamond) {
return true; this.clickDiamond();
} }
return false;
// --
//
// if (!this.audioPlaying) {
// this.audioPlaying = true;
// this.bgAudio.play();
// }
}
mapMove(event) {
//
// if (!this.downFlag) { return; }
// if (!this.curDiamond) { return; }
//
// // console.log(' in mapMove');
//
// const len = this.getPosDistance(this.mx, this.my, this.startPx, this.startPy);
// if (!this.moveFlag && len >= 5) {
// this.moveFlag = true;
// }
//
//
// if (this.moveFlag && !this.clickedDiamondFlag) {
// this.curDiamond.x = this.mx;
// this.curDiamond.y = this.my;
// }
} }
getWorlRect(target) { mapUp(event) {
// if (this.curDiamond) {
//
// if (this.moveFlag) {
//
// if (!this.curDiamond.selected) {
// this.checkOnQuestionTarget();
// }
// } else {
//
// this.clickDiamond();
// }
// // console.log('x: ', this.curDiamond.x / this.mapScale);
// // console.log('y: ', this.curDiamond.y / this.mapScale);
// }
this.downFlag = false;
this.moveFlag = false;
// this.curDiamond = null;
let rect = target.getBoundingBox(); }
clickDiamond() {
if (this.curDiamond.audio) {
this.curDiamond.audio.play();
}
if (target.parent) {
const pRect = this.getWorlRect(target.parent); if (this.curDiamond.light) {
rect.x += pRect.x; this.curDiamond.light.visible = true;
rect.y += pRect.y; this.showQuestionLight();
} }
return rect;
} }
checkPointInRect(x, y, rect) { showQuestionLight() {
if (x >= rect.x && x <= rect.x + rect.width) { for (let i = 0; i < this.diamondArr.length; i ++) {
if (y >= rect.y && y <= rect.y + rect.height) {
return true; if (this.diamondArr[i].qLight && !this.diamondArr[i].putEnd) {
this.diamondArr[i].qLight.visible = true;
} }
} }
return false;
} }
checkOnQuestionTarget() {
let checkSuccess = false;
for (let i = 0; i < this.diamondArr.length; i++) {
if (this.diamondArr[i].selected && !this.diamondArr[i].putEnd) {
addUrlToAudioObj(key, url = null, vlomue = 1, loop = false, callback = null) {
const audioObj = this.audioObj; if (this.checkRectInRect(this.diamondArr[i].getBoundingBox(), this.curDiamond.getBoundingBox())) {
if (url == null) { checkSuccess = true;
url = key; if ( this.diamondArr[i].text === this.curDiamond.text ) {
}
this.putSuccess(this.diamondArr[i]);
return;
}
}
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) { if ( checkSuccess ) {
audio.onended = () => { this.checkPutFail();
callback(); } else {
}; this.backBasePos();
} }
}
addUrlToImages(url) {
this.rawImages.set(url, url);
} }
backBasePos() {
this.curDiamond.x = this.curDiamond.baseX;
this.curDiamond.y = this.curDiamond.baseY;
}
checkPutFail() {
this.wrongAudio.play();
this.backBasePos();
}
// ======================================================编写区域========================================================================== putSuccess(target) {
this.successAudio.play();
this.curDiamond.x = target.x;
this.curDiamond.y = target.y;
/** const index = this.optionsArr.indexOf(this.curDiamond);
* 添加默认数据 便于无数据时的展示 this.optionsArr.splice(index, 1);
*/
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';
}
}
this.diamondArr.push(this.curDiamond);
this.curDiamond.audio = this.diamondArr[0].audio;
/** this.curDiamond.putEnd = true;
* 添加预加载图片 target.putEnd = true;
*/
initImg() {
this.addUrlToImages(this.data.pic_url);
this.addUrlToImages(this.data.pic_url_2);
this.checkGameEnd();
} }
/**
* 添加预加载音频
*/
initAudio() {
// 音频资源 checkGameEnd() {
this.addUrlToAudioObj(this.data.audio_url);
this.addUrlToAudioObj(this.data.audio_url_2); const arr = this.diamondArr;
for (let i = 0; i < arr.length; i++) {
if (arr[i].selected && !arr[i].putEnd) {
return false;
}
}
this.gameEnd();
// 音效
this.addUrlToAudioObj('click', this.rawAudios.get('click'), 0.3);
} }
gameEnd() {
this.finishAudio.play();
/** // const endSpr = new EndSpr(this.ctx);
* 初始化数据 // endSpr.init(this.images.get('end'));
*/ // endSpr.x = this.canvasWidth / 2;
initData() { // endSpr.y = this.canvasHeight / 2;
// this.endSpr = endSpr;
//
// endSpr.show2(this.mapScale);
this.gameEndFlag = true;
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 = [];
igniteLoop() {
} this.fps = Math.round(1000 / this.frametime);
this.animationId = window.requestAnimationFrame(this.igniteLoop.bind(this));
// 清除画布内容
this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
for (let i = 0; i < this.renderArr.length; i++) {
this.renderArr[i].update(this);
}
/** for (let i = 0; i < this.diamondArr.length; i++) {
* 初始化试图 this.diamondArr[i].update(this);
*/ }
initView() {
for (let i = 0; i < this.optionsArr.length; i++) {
this.optionsArr[i].update(this);
}
this.initPic(); if (this.endSpr) {
this.endSpr.update(this);
}
this.initBottomPart();
TWEEN.update();
} }
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(); initListener() {
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.winResizeEventStream
.pipe(debounceTime(500))
.subscribe(data => {
this.renderAfterResize();
});
this.btnRight = btnRight;
}
initPic() { // this.pcFlag = this.IsPC();
const maxW = this.canvasWidth * 0.7;
const pic1 = new MySprite(); // if (this.pcFlag) {
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.canvas.nativeElement.addEventListener('mousedown', (event) => {
this.pic1 = pic1;
// console.log('mousedown ');
setMxMyByMouse(event);
this.mapDown(event);
});
const label1 = new Label(); this.canvas.nativeElement.addEventListener('mousemove', (event) => {
label1.text = this.data.text;
label1.textAlign = 'center';
label1.fontSize = 50;
label1.fontName = 'BRLNSDB';
label1.fontColor = '#ffffff';
pic1.addChild(label1); // console.log('mousemove ');
setMxMyByMouse(event);
this.mapMove(event);
});
this.canvas.nativeElement.addEventListener('mouseup', (event) => {
// console.log('mouseup ');
setMxMyByMouse(event);
this.mapUp(event);
});
const setMxMyByMouse = (event) => {
const pic2 = new MySprite(); // console.log(' in setMxMyByMouse', event);
pic2.init(this.images.get(this.data.pic_url_2)); this.mx = event.offsetX;
pic2.x = this.canvasWidth / 2 + this.canvasWidth; this.my = event.offsetY;
pic2.y = this.canvasHeight / 2; };
pic2.setScaleXY(maxW / pic2.width);
this.renderArr.push(pic2);
this.pic2 = pic2;
this.curPic = pic1;
}
// } else {
btnLeftClicked() { this.canvas.nativeElement.addEventListener('touchstart', (event) => {
this.lastPage(); // console.log('touchstart ');
} setMxMyByTouch(event);
this.mapDown(event);
});
btnRightClicked() { this.canvas.nativeElement.addEventListener('touchmove', (event) => {
this.nextPage(); // console.log('touchmove ');
} setMxMyByTouch(event);
this.mapMove(event);
});
lastPage() { this.canvas.nativeElement.addEventListener('touchend', (event) => {
if (this.curPic == this.pic1) { // console.log('touchend ');
return; setMxMyByTouch(event);
} this.mapUp(event);
});
this.canTouch = false; this.canvas.nativeElement.addEventListener('touchcancel', (event) => {
const moveLen = this.canvasWidth; // console.log('touchcancel ');
tweenChange(this.pic1, {x: this.pic1.x + moveLen}, 1); setMxMyByTouch(event);
tweenChange(this.pic2, {x: this.pic2.x + moveLen}, 1, () => { this.mapUp(event);
this.canTouch = true;
this.curPic = this.pic1;
}); });
}
nextPage() {
if (this.curPic == this.pic2) { const setMxMyByTouch = (event) => {
return;
}
this.canTouch = false; // console.log('in setMxMyByTouch', event);
if (event.touches.length <= 0) {
return;
}
const moveLen = this.canvasWidth; if (this.canvasLeft == null) {
tweenChange(this.pic1, {x: this.pic1.x - moveLen}, 1); setParentOffset();
tweenChange(this.pic2, {x: this.pic2.x - moveLen}, 1, () => { }
this.canTouch = true;
this.curPic = this.pic2;
});
}
pic1Clicked() { this.mx = event.touches[0].pageX - this.canvasLeft;
this.playAudio(this.data.audio_url); this.my = event.touches[0].pageY - this.canvasTop;
} };
pic2Clicked() {
this.playAudio(this.data.audio_url_2);
}
const setParentOffset = () => {
const rect = this.canvas.nativeElement.getBoundingClientRect();
this.canvasLeft = rect.left;
this.canvasTop = rect.top;
};
// }
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) ) { loadResources() {
this.pic1Clicked(); const pr = [];
return; this.rawImages.forEach((value, key) => {// 预加载图片
}
if ( this.checkClickTarget(this.pic2) ) { // console.log('value:', value);
this.pic2Clicked(); // console.log('key:', key);
return; const p = this.preload(value)
} // const p = this.preload( `/api/media-resource/${value}/file`)
.then(img => this.images.set(key, img))
.catch(err => console.log(err));
pr.push(p);
});
return Promise.all(pr);
}
preload(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = reject;
img.src = url;
});
} }
mapMove(event) {
renderAfterResize() {
this.canvasWidth = this.wrap.nativeElement.clientWidth;
this.canvasHeight = this.wrap.nativeElement.clientHeight;
this.init();
} }
mapUp(event) {
checkPointInRect(x, y, rect) {
if (x >= rect.x && x <= rect.x + rect.width) {
if (y >= rect.y && y <= rect.y + rect.height) {
return true;
}
}
return false;
} }
checkRectInRect(rect1, rect2) {
return !(rect1.x + rect1.width < rect2.x || rect1.y + rect1.height < rect2.y
|| rect2.x + rect2.width < rect1.x || rect2.y + rect2.height < rect1.y);
update() { }
// ---------------------------------------------------------- getPosByAngle(angle, len) {
this.animationId = window.requestAnimationFrame(this.update.bind(this));
// 清除画布内容
this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
// tween 更新动画
TWEEN.update();
// ----------------------------------------------------------
const radian = angle * Math.PI / 180;
const x = Math.sin(radian) * len;
const y = Math.cos(radian) * len;
return {x, y};
this.updateArr(this.renderArr); }
getPosDistance(sx, sy, ex, ey) {
const _x = ex - sx;
const _y = ey - sy;
const len = Math.sqrt( Math.pow(_x, 2) + Math.pow(_y, 2) );
return len;
} }
......
const res = [ const res = [
// ['bg', "assets/play/bg.jpg"], ['bg', "assets/diamond/bg.jpg"],
['btn_left', "assets/play/btn_left.png"], ['paper', "assets/diamond/paper.png"],
['btn_right', "assets/play/btn_right.png"], ['slate', "assets/diamond/slate.png"],
// ['text_bg', "assets/play/text_bg.png"], ['question', "assets/diamond/question.png"],
['d-red', "assets/diamond/red.png"],
['d-yellow', "assets/diamond/yellow.png"],
['d-purple', "assets/diamond/purple.png"],
['end', "assets/diamond/end.png"],
['light', "assets/diamond/light.png"],
['question_light', "assets/diamond/question_light.png"],
];
const resAudio = [
['click', "assets/play/music/click.mp3"],
]; ];
export {res, resAudio}; export default res;
@mixin hide-overflow-text {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
@mixin k-no-select {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
@mixin k-img-bg {
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}
/* You can add global styles to this file, and also import other style files */
/* You can add global styles to this file, and also import other style files */
/* You can add global styles to this file, and also import other style files */
html, body {
width: 100%;
height: 100%;
font-size: 16px;
}
body {
background-color: #f0f2f5 !important;
}
* {
outline: none;
}
@font-face {
font-family: ChalkboardSE-Regular;
src: url('/assets/font/ChalkboardSE-Regular.woff') format('WOFF');
}
.k-16-9 {
position: relative;
width: 100%;
height: fit-content;
&:before {
content: "";
display: block;
position: relative;
width: 100%;
height: 0;
padding-bottom: 56.25%;
}
}
.k-full-fill {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.k-flex-center {
display: flex;
align-items: center;
justify-content: center;
}
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