Commit d267b5f7 authored by 范雪寒's avatar 范雪寒

feat:over

parent 9f3a2900
......@@ -128,5 +128,8 @@
}
}
},
"defaultProject": "ng-template-generator"
"defaultProject": "ng-template-generator",
"cli": {
"analytics": false
}
}
\ No newline at end of file
<div class="d-flex">
<div class="p-btn-record d-flex">
<div class="btn-clear" style="cursor: pointer" (click)="onBtnClearAudio()" *ngIf="withRmBtn && (audioUrl || audioBlob)">
<div class="btn-clear" style="cursor: pointer" (click)="onBtnClearAudio()"
*ngIf="withRmBtn && (audioUrl || audioBlob)">
<fa-icon icon="times"></fa-icon>
</div>
<div class="btn-record" *ngIf="type===Type.RECORD && !isUploading"
[class.p-recording]="isRecording"
<div class="btn-record" *ngIf="type===Type.RECORD && !isUploading" [class.p-recording]="isRecording"
(click)="onBtnRecord()">
<fa-icon icon="microphone"></fa-icon>
Record Audio
</div>
<nz-upload
[nzAccept] = "'.mp3'"
[nzShowUploadList]="false"
[nzAction]="uploadUrl"
[nzData]="uploadData"
<nz-upload [nzAccept]="'.mp3'" [nzShowUploadList]="false" [nzAction]="uploadUrl" [nzData]="uploadData"
(nzChange)="handleChange($event)">
<div class="btn-upload" [ngClass]="{'has-clear': withRmBtn && (audioUrl || audioBlob)}" *ngIf="type===Type.UPLOAD && !isUploading">
<div class="btn-upload" [ngClass]="{'has-clear': withRmBtn && (audioUrl || audioBlob)}"
*ngIf="type===Type.UPLOAD && !isUploading">
<fa-icon icon="upload"></fa-icon>
Upload Audio
</div>
......@@ -32,10 +29,9 @@
<div *ngIf="audioUrl && needRemove; then truthyTemplate else falsyTemplate"></div>
<ng-template #truthyTemplate >
<ng-template #truthyTemplate>
<div class="btn-delete" (click)="onBtnDeleteAudio()">
<fa-icon icon="close"></fa-icon>
<fa-icon icon="times"></fa-icon>
</div>
</ng-template>
......@@ -52,10 +48,10 @@
</div>
<div class="p-progress ml-2" (click)="onBtnPlay()" *ngIf="audioUrl || audioBlob">
<nz-progress [nzPercent]="percent" [nzWidth]="30" [nzFormat]="progressText"
nzType="circle"></nz-progress>
<nz-progress [nzPercent]="percent" [nzWidth]="30" [nzFormat]="progressText" nzType="circle"></nz-progress>
<div class="p-btn-play" [style.left]="isPlaying?'8px':''">
<fa-icon [icon]="playIcon"></fa-icon>
</div>
</div>
</div>
\ No newline at end of file
import {Component, EventEmitter, Input, OnDestroy, OnInit, Output, NgZone, OnChanges} from '@angular/core';
import {NzMessageService, NzNotificationService, UploadFile} from 'ng-zorro-antd';
import {HttpClient, HttpEvent, HttpEventType, HttpRequest} from '@angular/common/http';
import {environment} from '../../../environments/environment';
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, NgZone, OnChanges } from '@angular/core';
import { NzMessageService, NzNotificationService, UploadFile } from 'ng-zorro-antd';
import { HttpClient, HttpEvent, HttpEventType, HttpRequest } from '@angular/common/http';
import { environment } from '../../../environments/environment';
declare var Recorder;
......@@ -26,7 +26,7 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
uploadData;
@Input()
needRemove = false;
needRemove = true;
@Input()
audioItem: any = null;
......@@ -54,9 +54,9 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
audioBlob: any;
constructor( private nzMessageService: NzMessageService ) {
this.uploadUrl = (<any> window).courseware.uploadUrl();
this.uploadData = (<any> window).courseware.uploadData();
constructor(private nzMessageService: NzMessageService) {
this.uploadUrl = (<any>window).courseware.uploadUrl();
this.uploadData = (<any>window).courseware.uploadData();
window['air'].getUploadCallback = (url, data) => {
this.uploadUrl = url;
......
......@@ -8,9 +8,7 @@
<div nz-row nzType="flex" nzAlign="middle">
<div nz-col nzSpan="5" nzOffset="1">
<h5> add background: </h5>
<h5> add background-1: </h5>
<div class="bg-box">
<app-upload-image-with-preview
[picUrl]="bgItem?.url"
......@@ -19,6 +17,16 @@
</div>
</div>
<div nz-col nzSpan="5" nzOffset="1">
<h5> add background-2: </h5>
<div class="bg-box">
<app-upload-image-with-preview
[picUrl]="bgItem2?.url"
(imageUploaded)="onBackground_2_UploadSuccess($event)">
</app-upload-image-with-preview>
</div>
</div>
<div nz-col nzSpan="5" nzOffset="1" class="img-box"
*ngFor="let it of hotZoneArr; let i = index">
......
......@@ -10,12 +10,12 @@ import {
Output,
ViewChild
} from '@angular/core';
import {Subject} from 'rxjs';
import {debounceTime} from 'rxjs/operators';
import {EditorItem, HotZoneImg, HotZoneItem, HotZoneLabel, Label, MySprite, removeItemFromArr} from './Unit';
import { Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import { EditorItem, HotZoneImg, HotZoneItem, HotZoneLabel, Label, MySprite, removeItemFromArr } from './Unit';
import TWEEN from '@tweenjs/tween.js';
import {getMinScale} from "../../play/Unit";
import {tar} from "compressing";
import { getMinScale } from "../../play/Unit";
import { tar } from "compressing";
@Component({
......@@ -34,15 +34,15 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
hotZoneArr = null;
@Output()
save = new EventEmitter();
@ViewChild('canvas', {static: true}) canvas: ElementRef;
@ViewChild('wrap', {static: true}) wrap: ElementRef;
@ViewChild('canvas', { static: true }) canvas: ElementRef;
@ViewChild('wrap', { static: true }) wrap: ElementRef;
@Input()
isHasRect = true;
@Input()
isHasPic = true;
isHasPic = false;
@Input()
isHasText = true;
isHasText = false;
@Input()
hotZoneFontObj = {
size: 50,
......@@ -50,7 +50,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
color: '#8f3758'
}
@Input()
defaultItemType = 'text';
defaultItemType = 'rect';
@Input()
hotZoneImgSize = 190;
......@@ -83,6 +83,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
radioValue;
curItem;
bg: MySprite;
bg2: MySprite;
changeSizeFlag = false;
changeTopSizeFlag = false;
changeRightSizeFlag = false;
......@@ -99,8 +100,15 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
@Input()
set bgItem(v) {
this._bgItem = v;
}
this.init();
_bgItem2 = null;
get bgItem2() {
return this._bgItem2;
}
@Input()
set bgItem2(v) {
this._bgItem2 = v;
}
onResize(event) {
......@@ -112,7 +120,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
this.initListener();
// this.init();
this.init();
this.update();
}
......@@ -133,6 +141,12 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
this.refreshBackground();
}
onBackground_2_UploadSuccess(e) {
console.log('e: ', e);
this.bgItem2.url = e.url;
this.refreshBackground();
}
onItemImgUploadSuccess(e, item) {
item.pic_url = e.url;
this.loadHotZonePic(item.pic, e.url);
......@@ -144,14 +158,37 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
refreshBackground(callBack = null) {
let bg1Loaded = false;
let bg2Loaded = false;
this.loadBg1(() => {
bg1Loaded = true;
if (bg1Loaded && bg2Loaded) {
if (callBack) {
callBack();
}
}
});
this.loadBg2(() => {
bg2Loaded = true;
if (bg1Loaded && bg2Loaded) {
if (callBack) {
callBack();
}
}
})
}
loadBg1(callBack) {
if (!this.bg) {
this.bg = new MySprite(this.ctx);
this.renderArr.push(this.bg);
}
const bg = this.bg;
if (this.bgItem.url) {
if (!this.bgItem.url) {
callBack();
}
bg.load(this.bgItem.url).then(() => {
const rate1 = this.canvasWidth / bg.width;
......@@ -160,18 +197,39 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
const rate = Math.min(rate1, rate2);
bg.setScaleXY(rate);
bg.x = this.canvasWidth / 2;
bg.y = this.canvasHeight / 2;
if (callBack) {
callBack();
}
});
}
loadBg2(callBack) {
if (!this.bg2) {
this.bg2 = new MySprite(this.ctx);
this.renderArr.push(this.bg2);
}
const bg2 = this.bg2;
if (!this.bgItem2.url) {
callBack();
}
bg2.load(this.bgItem2.url).then(() => {
const rate1 = this.canvasWidth / bg2.width;
const rate2 = this.canvasHeight / bg2.height;
const rate = Math.min(rate1, rate2);
bg2.setScaleXY(rate);
bg2.alpha = 0.5;
bg2.x = this.canvasWidth / 2;
bg2.y = this.canvasHeight / 2;
callBack();
});
}
addBtnClick() {
// this.imgArr.push({});
......@@ -374,7 +432,6 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
init() {
this.initData();
this.initCtx();
......@@ -384,28 +441,19 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
initItem() {
if (!this.bgItem) {
this.bgItem = {};
} else {
}
if (!this.bgItem2) {
this.bgItem2 = {};
}
this.refreshBackground(() => {
// if (!this.imgItemArr) {
// this.imgItemArr = [];
// } else {
// this.initImgArr();
// }
// console.log('aaaaa');
if (!this.hotZoneItemArr) {
this.hotZoneItemArr = [];
} else {
this.initHotZoneArr();
}
});
}
}
initHotZoneArr() {
// console.log('this.hotZoneArr: ', this.hotZoneArr);
......@@ -413,7 +461,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
if (this.bg) {
curBgRect = this.bg.getBoundingBox();
} else {
curBgRect = {x: 0, y: 0, width: this.canvasWidth, height: this.canvasHeight};
curBgRect = { x: 0, y: 0, width: this.canvasWidth, height: this.canvasHeight };
}
let oldBgRect = this.bgItem.rect;
......@@ -470,7 +518,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
if (this.bg) {
curBgRect = this.bg.getBoundingBox();
} else {
curBgRect = {x: 0, y: 0, width: this.canvasWidth, height: this.canvasHeight};
curBgRect = { x: 0, y: 0, width: this.canvasWidth, height: this.canvasHeight };
}
let oldBgRect = this.bgItem.rect;
......@@ -487,7 +535,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
for (let i = 0; i < arr.length; i++) {
const data = JSON.parse(JSON.stringify(arr[i]));
const img = {pic_url: data.pic_url};
const img = { pic_url: data.pic_url };
data.rect.x *= rate;
data.rect.y *= rate;
......@@ -526,7 +574,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
mapDown(event) {
this.oldPos = {x: this.mx, y: this.my};
this.oldPos = { x: this.mx, y: this.my };
for (let i = 0; i < this.hotZoneArr.length; i++) {
......@@ -580,7 +628,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
this.curItem.y += addY;
}
this.oldPos = {x: this.mx, y: this.my};
this.oldPos = { x: this.mx, y: this.my };
this.saveDisabled = true;
......@@ -864,6 +912,18 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
};
}
const bgItem2 = this.bgItem2;
if (this.bg2) {
bgItem2['rect'] = this.bg2.getBoundingBox();
} else {
bgItem2['rect'] = {
x: 0,
y: 0,
width: Math.round(this.canvasWidth * 100) / 100,
height: Math.round(this.canvasHeight * 100) / 100
};
}
const hotZoneItemArr = [];
const hotZoneArr = this.hotZoneArr;
......@@ -894,7 +954,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
console.log('hotZoneItemArr: ', hotZoneItemArr);
this.save.emit({bgItem, hotZoneItemArr});
this.save.emit({ bgItem, bgItem2, hotZoneItemArr });
}
private updatePos() {
......
......@@ -6,3 +6,10 @@
height: 100%;
}
.border {
border-radius: 20px;
border-style: dashed;
padding: 20px;
margin: 20px;
}
\ No newline at end of file
<div class="model-content">
<div style="position: absolute; left: 200px; top: 100px; width: 800px;">
<input type="text" nz-input [(ngModel)]="item.text" (blur)="save()">
<app-upload-image-with-preview
[picUrl]="item.pic_url"
(imageUploaded)="onImageUploadSuccess($event, 'pic_url')"
></app-upload-image-with-preview>
<app-audio-recorder
[audioUrl]="item.audio_url"
(audioUploaded)="onAudioUploadSuccess($event, 'audio_url')"
></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="border" style="width: 750px; height: 190px;">
<span style="float: left; height: 30px; font-size: 18px;">标题字母:</span>
<input style="float: left; width: 50px;" type="text" nz-input [(ngModel)]="item.titleLetter" (blur)="save()">
<span style="float: left;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span style="float: left; height: 30px; font-size: 18px;">字母音频:</span>
<app-audio-recorder style="float: left;" [audioUrl]="item.titleLetterAudio"
(audioUploaded)="onTitleLetterAudioUploadSuccess($event)">
</app-audio-recorder>
<br><br>
<span style="float: left; height: 30px; font-size: 18px;">标题:</span>
<input style="float: left; width: 250px;" type="text" nz-input [(ngModel)]="item.title" (blur)="save()">
<span style="float: left;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span style="float: left; height: 30px; font-size: 18px;">标题音频:</span>
<app-audio-recorder style="float: left;" [audioUrl]="item.titleAudio"
(audioUploaded)="onTitleAudioUploadSuccess($event)">
</app-audio-recorder>
<br><br>
<span style="float: left; height: 30px; font-size: 18px;">整体音频:</span>
<app-audio-recorder style="float: left;" [audioUrl]="item.totalAudio"
(audioUploaded)="onTotalAudioUploadSuccess($event)">
</app-audio-recorder>
</div>
<app-custom-hot-zone
[bgItem]="item.popUpPosition.bgItem"
[bgItem2]="item.popUpPosition.bgItem2"
[hotZoneItemArr]="item.popUpPosition.hotZoneItemArr"
(save)="onPopUpPositionHotZoneSave(item.popUpPosition, $event)">
</app-custom-hot-zone>
</div>
\ No newline at end of file
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';
......@@ -10,27 +10,36 @@ import {Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, Ap
export class FormComponent implements OnInit, OnChanges, OnDestroy {
// 储存数据用
saveKey = "test_0011";
saveKey = "YM_L5_27";
// 储存对象
item;
constructor(private appRef: ApplicationRef,private changeDetectorRef: ChangeDetectorRef) {
constructor(private appRef: ApplicationRef, private changeDetectorRef: ChangeDetectorRef) {
}
ngOnInit() {
this.item = {};
this.item = {
title: '',
titleAudio: '',
titleLetter: '',
titleLetterAudio: '',
totalAudio: '',
popUpPosition: {},
};
// 获取存储的数据
(<any> window).courseware.getData((data) => {
(<any>window).courseware.getData((data) => {
if (data) {
this.item = data;
}
console.log('this.item = ' + JSON.stringify(this.item));
this.init();
this.changeDetectorRef.markForCheck();
this.changeDetectorRef.detectChanges();
......@@ -74,13 +83,40 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
this.save();
}
onTitleLetterAudioUploadSuccess(event) {
this.item.titleLetterAudio = event.url;
this.save();
}
onTitleAudioUploadSuccess(event) {
this.item.titleAudio = event.url;
this.save();
}
onTotalAudioUploadSuccess(event) {
this.item.totalAudio = event.url;
this.save();
}
onPopUpPositionHotZoneSave(data, event) {
const { bgItem, bgItem2, hotZoneItemArr } = event;
data.bgItem = bgItem;
data.bgItem2 = bgItem2;
data.hotZoneItemArr = hotZoneItemArr;
this.item.popUpPosition.bgItem = bgItem;
this.item.popUpPosition.bgItem2 = bgItem2;
this.item.popUpPosition.hotZoneItemArr = hotZoneItemArr;
this.save();
}
/**
* 储存数据
*/
save() {
(<any> window).courseware.setData(this.item, null, this.saveKey);
(<any>window).courseware.setData(this.item, null, this.saveKey);
console.log('this.item = ' + JSON.stringify(this.item));
this.refresh();
}
......
......@@ -1640,9 +1640,15 @@ export function jelly(item, time = 0.7) {
TWEEN.remove(item.jellyTween);
}
const t = time / 9;
const baseSX = item.scaleX;
const baseSY = item.scaleY;
const t = time / 8;
if (!item.baseSX) {
item.baseSX = item.scaleX;
}
if (!item.baseSY) {
item.baseSY = item.scaleY;
}
let index = 0;
const run = () => {
......@@ -1651,19 +1657,19 @@ export function jelly(item, time = 0.7) {
return;
}
const data = arr[index];
const t = tweenChange(item, {scaleX: data[0], scaleY: data[1]}, data[2], () => {
index ++;
const t = tweenChange(item, { scaleX: data[0], scaleY: data[1] }, data[2], () => {
index++;
run();
}, TWEEN.Easing.Sinusoidal.InOut);
item.jellyTween = t;
};
const arr = [
[baseSX * 1.1, baseSY * 0.9, t],
[baseSX * 0.98, baseSY * 1.02, t * 2],
[baseSX * 1.02, baseSY * 0.98, t * 2],
[baseSX * 0.99, baseSY * 1.01, t * 2],
[baseSX * 1.0, baseSY * 1.0, t * 2],
[item.baseSX * 1.1, item.baseSY * 0.9, t],
[item.baseSX * 0.98, item.baseSY * 1.02, t * 2],
[item.baseSX * 1.02, item.baseSY * 0.98, t * 2],
[item.baseSX * 0.99, item.baseSY * 1.01, t * 2],
[item.baseSX * 1.0, item.baseSY * 1.0, t],
];
......
export const defaultData = {
"title": "asdf asd fa asdf",
"titleAudio": "http://staging-teach.cdn.ireadabc.com/23376490a9ba0f4a3fe0618fc1c935e1.mp3",
"titleLetter": "F",
"titleLetterAudio": "http://staging-teach.cdn.ireadabc.com/dfb27b510e121a1045a3b7613a530e43.mp3",
}
\ No newline at end of file
import {
MySprite,
Label,
removeItemFromArr,
hideItem,
showItem,
moveItem,
tweenChange,
} from '../Unit';
import TWEEN from '@tweenjs/tween.js';
export class Game {
_parent = null;
_z = 0;
children: any = [this];
constructor(parent) {
this._parent = parent;
}
initData(data) {
}
_initView() {
this._checkFonts(() => {
this.initView();
});
}
_fontNameList = [];
_checkFonts(cb) {
let unloaded = false;
document['fonts'].forEach((font) => {
if (font.status === 'unloaded') {
unloaded = true;
}
});
if (unloaded) {
setTimeout(() => this._checkFonts(cb), 100);
return;
}
cb();
}
initView() {
}
_currentPlayingAudioName;
_currentPlayingAudioCallback;
playAudio(key, now = true, callback = null) {
if (key == '') {
return;
}
if (this._currentPlayingAudioName != '') {
const audio = this._parent.audioObj[this._currentPlayingAudioName];
if (audio) {
if (now) {
if (!audio.paused) {
audio.pause();
if (this._currentPlayingAudioCallback) {
this._currentPlayingAudioCallback();
this._currentPlayingAudioCallback = null;
}
// audio.currentTime = 0;
}
}
}
}
this._currentPlayingAudioName = key;
this._currentPlayingAudioCallback = callback;
this._parent.playAudio(key, now, () => {
this._currentPlayingAudioName = '';
if (callback) {
callback();
}
});
}
getAudioObj(key) {
return this._parent.audioObj[key];
}
_editMode = false;
setEditMode(flg) {
this._editMode = flg;
}
isEditMode() {
return this._editMode;
}
_save;
setSaveFunc(save) {
this._save = save;
}
addChild(node, z = 1) {
this._parent.renderArr.push(node);
if (this.children.indexOf(node) === -1) {
this.children.push(node);
node._z = z;
}
this.children.sort((a, b) => {
return a._z - b._z;
});
}
removeChildren() {
for (let i = 0; i < this.children.length; i++) {
if (this.children[i]) {
if (this.children[i] !== this) {
let child = this.children.splice(i, 1);
removeItemFromArr(this._parent.renderArr, child);
i--;
}
}
}
}
removeChild(child) {
const index = this.children.indexOf(child);
if (index !== -1) {
this.children.splice(index, 1);
}
removeItemFromArr(this._parent.renderArr, child);
}
_checkHitPosition(node, pos) {
let rightNode = null;
if (node.visible && node.alpha > 0 && node._touchEnabled && node._checkHitPosition(pos)) {
rightNode = node;
}
if (node.children.length > 1) {
for (var i = 1; i < node.children.length; ++i) {
if (node.children[i] != node) {
let result = this._checkHitPosition(node.children[i], pos);
if (result != null) {
rightNode = result;
}
}
}
}
return rightNode;
}
_currentTouchSprite = null;
_onTouchBegan(pos) {
let result = this._checkHitPosition(this, pos);
if (result == null) {
return;
}
if (result._onTouchBeganListener &&
typeof (result._onTouchBeganListener) == 'function') {
result._onTouchBeganListener(pos);
}
this._currentTouchSprite = result;
}
_onTouchMove(pos) {
if (this._currentTouchSprite == null) {
return;
}
if (this._currentTouchSprite._onTouchMoveListener &&
typeof (this._currentTouchSprite._onTouchMoveListener) == 'function') {
this._currentTouchSprite._onTouchMoveListener(pos);
}
}
_onTouchEnd(pos) {
if (this._currentTouchSprite == null) {
return;
}
if (this._currentTouchSprite._checkHitPosition(pos)) {
if (this._currentTouchSprite._onTouchEndListener &&
typeof (this._currentTouchSprite._onTouchEndListener) == 'function') {
this._currentTouchSprite._onTouchEndListener(pos);
}
this._currentTouchSprite = null;
} else {
if (this._currentTouchSprite._onTouchCancelListener &&
typeof (this._currentTouchSprite._onTouchCancelListener) == 'function') {
this._currentTouchSprite._onTouchCancelListener(pos);
}
this._currentTouchSprite = null;
}
}
getChildByName(name) {
for (var i = 1; i < this.children.length; ++i) {
let node = this.children[i];
if (node.getName() == name) {
return node;
}
}
return null;
}
seekChildByName(name) {
let result = this.getChildByName(name);
if (result == null) {
for (var i = 1; i < this.children.length; ++i) {
let node = this.children[i];
if (typeof (node.seekChildByName) == 'function') {
result = node.seekChildByName(name);
if (result != null) {
return result;
}
}
}
}
return result;
}
getScreenSize() {
return {
width: this._parent.canvasWidth,
height: this._parent.canvasHeight
};
}
getDefaultScreenSize() {
return {
width: this._parent.canvasBaseW,
height: this._parent.canvasBaseH
};
}
getFullScaleXY() {
let screenSize = this.getScreenSize();
let defaultSize = this.getDefaultScreenSize();
return Math.max(screenSize.height / defaultSize.height, screenSize.width / defaultSize.width);
}
_showMode = false;
showModeOn() {
this._showMode = true;
}
showModeOff() {
this._showMode = false;
}
isShowMode() {
return this._showMode;
}
}
// 节点名
class Nameable {
_parent = null;
constructor(parent) {
this._parent = parent;
}
_name = 'name';
setName(name) {
this._name = name;
}
getName() {
return this._name;
}
getChildByName(name) {
for (var i = 1; i < this._parent.children.length; ++i) {
let node = this._parent.children[i];
if (node.getName() == name) {
return node;
}
}
return null;
}
seekChildByName(name) {
let result = this.getChildByName(name);
if (result == null) {
for (var i = 1; i < this._parent.children.length; ++i) {
let node = this._parent.children[i];
if (typeof (node.seekChildByName) == 'function') {
result = node.seekChildByName(name);
if (result != null) {
return result;
}
}
}
}
return result;
}
}
class UserData {
// 用户自定义数据
userData = {};
get(key) {
return this.userData[key];
}
set(key, value) {
this.userData[key] = value;
}
}
export class MyLabel extends Label {
_nameable = new Nameable(this);
setName(name) {
this._nameable.setName(name);
}
getName() {
return this._nameable.getName();
}
getChildByName(name) {
return this._nameable.getChildByName(name);
}
seekChildByName(name) {
return this._nameable.seekChildByName(name);
}
// 位置
setPosition(x: any = 0, y = undefined) {
if (y !== undefined) {
this.x = x;
this.y = y;
} else {
this.x = x.x;
this.y = x.y;
}
}
setPositionX(x = 0) {
this.x = x;
}
setPositionY(y = 0) {
this.y = y;
}
_userData = new UserData();
get(key) {
return this._userData.get(key);
}
set(key, value) {
this._userData.set(key, value);
}
_touchEnabled = false;
// _swallowTouches = false; // TODO:多重触摸以后用到了再说
_onTouchBeganListener = null;
_onTouchMoveListener = null;
_onTouchEndListener = null;
_onTouchCancelListener = null;
addTouchBeganListener(func) {
this._touchEnabled = true;
this._onTouchBeganListener = func;
}
addTouchMoveListener(func) {
this._touchEnabled = true;
this._onTouchMoveListener = func;
}
addTouchEndListener(func) {
this._touchEnabled = true;
this._onTouchEndListener = func;
}
addTouchCancelListener(func) {
this._touchEnabled = true;
this._onTouchCancelListener = func;
}
_checkHitPosition(pos) {
const rect = this.getBoundingBox();
if (this._checkPointInRect(pos.x, pos.y, rect)) {
return true;
}
return false;
}
_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;
}
drawText() {
if (!this.text) {
return;
}
this.ctx.font = `${this.fontSize}px ${this.fontName}`;
this.ctx.textAlign = this.textAlign;
this.ctx.textBaseline = 'middle';
this.ctx.fontWeight = this.fontWeight;
let x = -(this.anchorX) * this._width;
let y = 0;
if (this._outlineFlag) {
this.ctx.lineWidth = this._outLineWidth;
this.ctx.strokeStyle = this._outLineColor;
this.ctx.strokeText(this.text, x, y);
}
this.ctx.fillStyle = this.fontColor;
if (this.outline > 0) {
this.ctx.lineWidth = this.outline;
this.ctx.strokeStyle = this.outlineColor;
this.ctx.strokeText(this.text, x, y);
}
this.ctx.fillText(this.text, x, y);
// console.log('汪汪汪: ' + this.scaleX * this.anchorX);
// console.log('汪汪汪: ' + this._width);
}
}
export class TouchSprite extends MySprite {
_nameable = new Nameable(this);
setName(name) {
this._nameable.setName(name);
}
getName() {
return this._nameable.getName();
}
getChildByName(name) {
return this._nameable.getChildByName(name);
}
seekChildByName(name) {
return this._nameable.seekChildByName(name);
}
_touchEnabled = false;
// _swallowTouches = false; // TODO:多重触摸以后用到了再说
_onTouchBeganListener = null;
_onTouchMoveListener = null;
_onTouchEndListener = null;
_onTouchCancelListener = null;
addTouchBeganListener(func) {
this._touchEnabled = true;
this._onTouchBeganListener = func;
}
addTouchMoveListener(func) {
this._touchEnabled = true;
this._onTouchMoveListener = func;
}
addTouchEndListener(func) {
this._touchEnabled = true;
this._onTouchEndListener = func;
}
addTouchCancelListener(func) {
this._touchEnabled = true;
this._onTouchCancelListener = func;
}
_checkHitPosition(pos) {
const rect = this.getBoundingBox();
if (this._checkPointInRect(pos.x, pos.y, rect)) {
return true;
}
return false;
}
_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;
}
// 位置
setPosition(x: any = 0, y = undefined) {
if (y !== undefined) {
this.x = x;
this.y = y;
} else {
this.x = x.x;
this.y = x.y;
}
}
setPositionX(x = 0) {
this.x = x;
}
setPositionY(y = 0) {
this.y = y;
}
// 用户自定义数据
_userData = new UserData();
get(key) {
return this._userData.get(key);
}
set(key, value) {
this._userData.set(key, value);
}
}
export function blinkItem(item: TouchSprite, time = 0.7) {
let interval = item.get('_blinkInterval');
if (interval) {
clearInterval(interval);
}
interval = setInterval(() => {
showItem(item, time, () => {
hideItem(item, time);
});
}, time * 2 * 1000);
item.set('_blinkInterval', interval);
}
export function stopBlinkItem(item: TouchSprite) {
let interval = item.get('_blinkInterval');
if (interval) {
clearInterval(interval);
}
item.set('_blinkInterval', null);
item.alpha = 0;
}
export function RandomInt(a, b = 0) {
let max = Math.max(a, b);
let min = Math.min(a, b);
return Math.floor(Math.random() * (max - min) + min);
}
export function Between(a, b, c) {
let max = Math.max(a, b, c);
let min = Math.min(a, b, c);
return [a, b, c].find((number) => number != max && number != min);
}
export function shake(item, time = 0.5, rate = 1) {
let shakeSelf = function (item, time, callback, rate) {
const offX = 15 * item.scaleX * rate;
const offY = 15 * item.scaleX * rate;
const baseX = item.x;
const baseY = item.y;
const easing = TWEEN.Easing.Sinusoidal.InOut;
const move2 = () => {
moveItem(item, baseX, baseY, time * 9 / 16, () => {
if (callback) {
callback();
}
}, easing);
};
const move1 = () => {
moveItem(item, baseX + offX, baseY + offY, time * 7 / 16, () => {
move2();
}, easing);
};
move1();
}
shakeSelf(item, time, shake.bind(this, item, time, rate), rate);
}
export async function asyncDelayTime(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(123);
}, time * 1000);
})
}
export async function asyncTweenChange(node, obj, time, easing = null) {
return new Promise((resolve, reject) => {
tweenChange(node, obj, time, () => {
resolve(0);
}, easing);
});
}
\ No newline at end of file
import {
Game,
TouchSprite,
MyLabel,
asyncTweenChange,
} from './Game';
import {
jelly, tweenChange,
} from './../Unit';
import { defaultData } from './DefaultData';
export class MyGame extends Game {
images = null;
data = null;
status = null;
initData(data) {
this.images = data.images;
this.status = {};
if (!data.data || Object.is(data.data, {})) {
this.data = defaultData;
} else {
this.data = data.data;
}
let imgUrlList = [];
let audioUrlList = [];
imgUrlList.push(this.data.popUpPosition.bgItem.url);
imgUrlList.push(this.data.popUpPosition.bgItem2.url);
// audioUrlList.push(this.data.titleLetterAudio);
this.data.popUpPosition.hotZoneItemArr.forEach(data => {
audioUrlList.push(data.audio_url);
});
imgUrlList = imgUrlList.filter((data) => data != null && data != '');
audioUrlList = audioUrlList.filter((data) => data != null && data != '');
this.preLoadData(imgUrlList, audioUrlList);
}
preLoadData(imgUrlList, audioUrlList) {
imgUrlList.forEach((data) => {
this._parent.addUrlToImages(data);
});
audioUrlList.forEach((data) => {
this._parent.addUrlToAudioObj(data);
});
}
mapScale;
initView() {
this.mapScale = this._parent.mapScale;
// 初始化背景
this.initBg();
// 初始化标题
this.initTittle();
// 初始化中间部分
this.initMiddle();
this.initButton();
}
bg;
initBg() {
const bgBig = new TouchSprite();
bgBig.init(this.images.get('img_white_bg'));
bgBig.x = this._parent.canvasWidth / 2;
bgBig.y = this._parent.canvasHeight / 2;
bgBig.setScaleXY(this._parent.mapScaleBig);
this.addChild(bgBig);
const bg = new TouchSprite();
bg.init(this.images.get('img_white_bg'));
bg.x = this._parent.canvasWidth / 2;
bg.y = this._parent.canvasHeight / 2;
bg.setScaleXY(this.mapScale);
this.addChild(bg);
this.bg = bg;
}
initTittle() {
const titleBg = new TouchSprite();
titleBg.init(this.images.get('img_title_bg'));
titleBg.x = titleBg.width / 2 * this.mapScale;
titleBg.y = titleBg.height / 2 * this.mapScale;
titleBg.setScaleXY(this.mapScale);
this.addChild(titleBg);
const titleLetter = new MyLabel();
titleLetter.x = titleBg.width * 1 / 8;
titleLetter.y = 0;
titleLetter.fontSize = 48;
titleLetter.fontColor = "#facf46";
titleLetter.fontName = 'BerlinSansFBDemi';
titleLetter.anchorX = 0;
titleLetter.anchorY = 0.5;
titleLetter.text = this.data.titleLetter;
titleLetter.refreshSize();
titleLetter.addTouchBeganListener(() => {
this.playAudio(this.data.titleLetterAudio);
});
titleBg.addChild(titleLetter);
const titleLabel = new MyLabel();
titleLabel.x = titleBg.width * 5 / 8;
titleLabel.y = 0;
titleLabel.fontSize = 36;
titleLabel.fontColor = "#000000";
titleLabel.fontName = 'FuturaStd';
titleLabel.anchorX = 0;
titleLabel.anchorY = 0.5;
titleLabel.text = this.data.title;
titleLabel.refreshSize();
titleLabel.addTouchBeganListener(() => {
this.playAudio(this.data.titleAudio);
});
titleBg.addChild(titleLabel);
}
middleBg1;
middleBg2;
initMiddle() {
const bgItem = this.data.popUpPosition.bgItem;
const bgItem2 = this.data.popUpPosition.bgItem2;
const bg = this.initMiddleBg(bgItem);
this.middleBg1 = bg;
console.log('bgItem2 = ' + JSON.stringify(bgItem2));
const bg2 = this.initMiddleBg(bgItem2);
bg2.alpha = 0;
this.middleBg2 = bg2;
const bgItemScale = bg.width / bgItem.rect.width;
this.data.popUpPosition.hotZoneItemArr.forEach(data => {
const rect = new TouchSprite();
rect.init(this.images.get('img_title_bg2'));
rect.anchorX = 0;
rect.anchorY = 0;
rect.scaleX = (data.rect.width * bgItemScale) / rect.width;
rect.scaleY = (data.rect.height * bgItemScale) / rect.height;
rect.x = -bg.width / 2 + data.rect.x * bgItemScale;
rect.y = -bg.height / 2 + data.rect.y * bgItemScale;
bg.addChild(rect);
// console.log('data = ' + JSON.stringify(data));
rect.addTouchBeganListener(() => {
// console.log('data.audio_url = ' + data.audio_url);
if (data.audio_url) {
this.playAudio(data.audio_url);
}
});
});
}
initMiddleBg(bgItem) {
const bg = new TouchSprite();
bg.init(this.images.get(bgItem.url));
bg.x = this._parent.canvasWidth / 2;
bg.y = this._parent.canvasHeight / 2 + 35 * this.mapScale;
const maxScaleX = (this._parent.canvasWidth - 30 * this.mapScale) / bg.width;
const maxScaleY = (this._parent.canvasHeight - 70 * this.mapScale) / bg.height;
bg.setScaleXY(Math.min(maxScaleX, maxScaleY));
this.addChild(bg);
return bg;
}
eyeOpen = true;
initButton() {
const btn = new TouchSprite();
btn.init(this.images.get('btn_eye_open'));
btn.x = this._parent.canvasWidth - 60 * this.mapScale;
btn.y = this._parent.canvasHeight - 60 * this.mapScale;
btn.setScaleXY(this.mapScale);
btn.addTouchBeganListener(() => {
jelly(btn);
if (this.eyeOpen) {
btn.init(this.images.get('btn_eye_close'));
tweenChange(this.middleBg1, { alpha: 0 }, 0.2);
tweenChange(this.middleBg2, { alpha: 1 }, 0.2);
} else {
btn.init(this.images.get('btn_eye_open'));
tweenChange(this.middleBg1, { alpha: 1 }, 0.2);
tweenChange(this.middleBg2, { alpha: 0 }, 0.2);
}
this.eyeOpen = !this.eyeOpen;
});
this.addChild(btn);
}
}
......@@ -9,11 +9,27 @@
}
@font-face
{
font-family: 'BerlinSansFBDemi';
src: url("../../assets/font/BerlinSansFBDemi-Bold.TTF") ;
}
@font-face
{
font-family: 'FuturaStd';
src: url("../../assets/font/FuturaStd-Medium.otf") ;
}
@font-face
{
font-family: 'GOTHICB';
src: url("../../assets/font/GOTHICB_1.TTF") ;
}
@font-face
{
font-family: 'BRLNSDB';
src: url("../../assets/font/BRLNSDB.TTF") ;
font-family: 'ahronbd';
src: url("../../assets/font/ahronbd-1.ttf") ;
}
<div class="game-container" #wrap>
<canvas id="canvas" #canvas></canvas>
</div>
<span style="position: absolute; top: 0px; font-family: BerlinSansFBDemi">&nbsp;</span>
<span style="position: absolute; top: 0px; font-family: FuturaStd">&nbsp;</span>
<span style="position: absolute; top: 0px; font-family: GOTHICB">&nbsp;</span>
<span style="position: absolute; top: 0px; font-family: ahronbd">&nbsp;</span>
\ No newline at end of file
import {Component, ElementRef, ViewChild, OnInit, Input, OnDestroy, HostListener} from '@angular/core';
import { Component, ElementRef, ViewChild, OnInit, Input, OnDestroy, HostListener } from '@angular/core';
import {
Label,
MySprite, tweenChange,
} from './Unit';
import {res, resAudio} from './resources';
import { res, resAudio } from './resources';
import {Subject} from 'rxjs';
import {debounceTime} from 'rxjs/operators';
import { Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import TWEEN from '@tweenjs/tween.js';
import { MyGame } from "./game/MyGame";
......@@ -22,8 +23,8 @@ import TWEEN from '@tweenjs/tween.js';
})
export class PlayComponent implements OnInit, OnDestroy {
@ViewChild('canvas', {static: true }) canvas: ElementRef;
@ViewChild('wrap', {static: true }) wrap: ElementRef;
@ViewChild('canvas', { static: true }) canvas: ElementRef;
@ViewChild('wrap', { static: true }) wrap: ElementRef;
// 数据
data;
......@@ -39,7 +40,6 @@ export class PlayComponent implements OnInit, OnDestroy {
mx; // 点击x坐标
my; // 点击y坐标
// 资源
rawImages = new Map(res);
rawAudios = new Map(resAudio);
......@@ -53,11 +53,12 @@ export class PlayComponent implements OnInit, OnDestroy {
renderArr;
mapScale = 1;
mapScaleBig = 1;
canvasLeft;
canvasTop;
saveKey = 'test_0011';
saveKey = 'YM_L5_27';
btnLeft;
......@@ -69,6 +70,8 @@ export class PlayComponent implements OnInit, OnDestroy {
curPic;
game;
@HostListener('window:resize', ['$event'])
onResize(event) {
this.winResizeEventStream.next();
......@@ -80,13 +83,19 @@ export class PlayComponent implements OnInit, OnDestroy {
this.data = {};
// 获取数据
const getData = (<any> window).courseware.getData;
const getData = (<any>window).courseware.getData;
getData((data) => {
if (data && typeof data == 'object') {
this.data = data;
}
// console.log('data:' , data);
this.game = new MyGame(this);
this.game.initData({
images: this.images,
data: this.data,
});
// 初始化 各事件监听
this.initListener();
......@@ -108,16 +117,6 @@ export class PlayComponent implements OnInit, OnDestroy {
ngOnDestroy() {
window['curCtx'] = null;
window.cancelAnimationFrame(this.animationId);
this.cleanAudio();
}
cleanAudio() {
if (this.audioObj) {
for (const key in this.audioObj) {
this.audioObj[key].pause();
}
}
}
......@@ -125,9 +124,27 @@ export class PlayComponent implements OnInit, OnDestroy {
// 预加载资源
this.loadResources().then(() => {
this.addServerListener();
window["air"].hideAirClassLoading(this.saveKey, this.data);
});
}
start() {
console.log(' in start');
this.init();
this.update();
}
addServerListener() {
const c = (<any>window).courseware;
if (!c || !c.onEvent) {
return;
}
c.onEvent('course-in-screen', (data, next) => { // 学生端 初始化时调用
this.start();
next();
});
}
......@@ -151,7 +168,6 @@ export class PlayComponent implements OnInit, OnDestroy {
this.canvas.nativeElement.height = this.canvasHeight;
window['curCtx'] = this.ctx;
window['curImages'] = this.images;
}
......@@ -340,8 +356,9 @@ export class PlayComponent implements OnInit, OnDestroy {
preloadAudio(url) {
return new Promise((resolve, reject) => {
const audio = new Audio();
resolve({})
audio.oncanplay = (a) => {
resolve();
//resolve();
};
audio.onerror = () => {
reject();
......@@ -443,10 +460,10 @@ export class PlayComponent implements OnInit, OnDestroy {
*/
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';
}
// if (!this.data.pic_url) {
// this.data.pic_url = 'assets/play/default/pic.jpg';
// this.data.pic_url_2 = 'assets/play/default/pic.jpg';
// }
}
......@@ -455,8 +472,8 @@ export class PlayComponent implements OnInit, OnDestroy {
*/
initImg() {
this.addUrlToImages(this.data.pic_url);
this.addUrlToImages(this.data.pic_url_2);
// this.addUrlToImages(this.data.pic_url);
// this.addUrlToImages(this.data.pic_url_2);
}
......@@ -466,11 +483,15 @@ export class PlayComponent implements OnInit, OnDestroy {
initAudio() {
// 音频资源
this.addUrlToAudioObj(this.data.audio_url);
this.addUrlToAudioObj(this.data.audio_url_2);
// this.addUrlToAudioObj(this.data.audio_url);
// this.addUrlToAudioObj(this.data.audio_url_2);
for (let item of this.rawAudios) {
if (item[0] != item[1]) {
// 音效
this.addUrlToAudioObj('click', this.rawAudios.get('click'), 0.3);
this.addUrlToAudioObj(item[0], this.rawAudios.get(item[0]), 0.3);
}
}
}
......@@ -483,8 +504,8 @@ export class PlayComponent implements OnInit, OnDestroy {
const sx = this.canvasWidth / this.canvasBaseW;
const sy = this.canvasHeight / this.canvasBaseH;
const s = Math.min(sx, sy);
this.mapScale = s;
this.mapScale = Math.min(sx, sy);
this.mapScaleBig = Math.max(sx, sy);
// this.mapScale = sx;
// this.mapScale = sy;
......@@ -502,88 +523,7 @@ export class PlayComponent implements OnInit, OnDestroy {
* 初始化试图
*/
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();
this.game._initView();
}
lastPage() {
......@@ -595,8 +535,8 @@ export class PlayComponent implements OnInit, OnDestroy {
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, () => {
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;
});
......@@ -611,8 +551,8 @@ export class PlayComponent implements OnInit, OnDestroy {
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, () => {
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;
});
......@@ -631,39 +571,15 @@ export class PlayComponent implements OnInit, OnDestroy {
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;
}
this.game._onTouchBegan({ x: this.mx, y: this.my });
}
mapMove(event) {
this.game._onTouchMove({ x: this.mx, y: this.my });
}
mapUp(event) {
this.game._onTouchEnd({ x: this.mx, y: this.my });
}
......
const res = [
// ['bg', "assets/play/bg.jpg"],
['btn_left', "assets/play/btn_left.png"],
['btn_right', "assets/play/btn_right.png"],
// ['text_bg', "assets/play/text_bg.png"],
['Img_point', "assets/play/Img_point.png"],
['btn_pause', "assets/play/btn_pause.png"],
['btn_switch', "assets/play/btn_switch.png"],
['img_group_bg_1', "assets/play/img_group_bg_1.png"],
['img_line_black', "assets/play/img_line_black.png"],
['img_line_purple', "assets/play/img_line_purple.png"],
['img_oval_bg', "assets/play/img_oval_bg.png"],
['img_white_bg', "assets/play/img_white_bg.png"],
['btn_close', "assets/play/btn_close.png"],
['btn_play', "assets/play/btn_play.png"],
['img_grey_bg', "assets/play/img_grey_bg.png"],
['img_group_bg_2', "assets/play/img_group_bg_2.png"],
['img_line_grey', "assets/play/img_line_grey.png"],
['img_line_red', "assets/play/img_line_red.png"],
['img_title_bg', "assets/play/img_title_bg.png"],
['img_title_bg2', "assets/play/img_title_bg2.png"],
['img_win_bg', "assets/play/img_win_bg.png"],
['btn_eye_open', "assets/play/btn_eye_open.png"],
['btn_eye_close', "assets/play/btn_eye_close.png"],
];
const resAudio = [
['click', "assets/play/music/click.mp3"],
// ['click', "assets/play/music/click.mp3"],
];
export {res, resAudio};
export { res, resAudio };
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