Commit ecbbe282 authored by Li MingZhe's avatar Li MingZhe

feat: 首次提交

parent 9f3a2900
...@@ -24,6 +24,8 @@ import {AudioRecorderComponent} from './common/audio-recorder/audio-recorder.com ...@@ -24,6 +24,8 @@ import {AudioRecorderComponent} from './common/audio-recorder/audio-recorder.com
import { FontAwesomeModule, FaIconLibrary } from '@fortawesome/angular-fontawesome'; import { FontAwesomeModule, FaIconLibrary } from '@fortawesome/angular-fontawesome';
import { fas } from '@fortawesome/free-solid-svg-icons'; import { fas } from '@fortawesome/free-solid-svg-icons';
import { far } from '@fortawesome/free-regular-svg-icons'; import { far } from '@fortawesome/free-regular-svg-icons';
import { CustomActionComponent } from './common/custom-action/custom-action.component';
import { UploadDragonBoneComponent } from './common/upload-dragon-bone/upload-dragon-bone.component';
registerLocaleData(zh); registerLocaleData(zh);
...@@ -41,7 +43,9 @@ registerLocaleData(zh); ...@@ -41,7 +43,9 @@ registerLocaleData(zh);
UploadVideoComponent, UploadVideoComponent,
CustomHotZoneComponent, CustomHotZoneComponent,
PlayerContentWrapperComponent PlayerContentWrapperComponent,
CustomActionComponent,
UploadDragonBoneComponent
], ],
imports: [ imports: [
......
...@@ -35,7 +35,8 @@ ...@@ -35,7 +35,8 @@
<ng-template #truthyTemplate > <ng-template #truthyTemplate >
<div class="btn-delete" (click)="onBtnDeleteAudio()"> <div class="btn-delete" (click)="onBtnDeleteAudio()">
<fa-icon icon="close"></fa-icon> <!-- <fa-icon icon="close"></fa-icon> -->
<i nz-icon nzType="close" nzTheme="outline"></i>
</div> </div>
</ng-template> </ng-template>
......
...@@ -26,7 +26,7 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy { ...@@ -26,7 +26,7 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
uploadData; uploadData;
@Input() @Input()
needRemove = false; needRemove = true;
@Input() @Input()
audioItem: any = null; audioItem: any = null;
...@@ -62,8 +62,25 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy { ...@@ -62,8 +62,25 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
this.uploadUrl = url; this.uploadUrl = url;
this.uploadData = data; this.uploadData = data;
}; };
this.setUploadUrl();
} }
setUploadUrl() {
if (!this.uploadUrl) {
this.uploadUrl = (<any> window).courseware.uploadUrl();
this.uploadData = (<any> window).courseware.uploadData();
setTimeout(() => {
this.setUploadUrl();
}, 500);
}
}
init() { init() {
this.playIcon = 'play'; this.playIcon = 'play';
this.isPlaying = false; this.isPlaying = false;
...@@ -157,6 +174,7 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy { ...@@ -157,6 +174,7 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
onBtnDeleteAudio() { onBtnDeleteAudio() {
this.audioUrl = null; this.audioUrl = null;
this.audioUploaded.emit({});
this.audioRemoved.emit(); this.audioRemoved.emit();
} }
......
<div class="position-relative">
<button nz-button (click)="setAnimaBtnClick()" style=" border-radius: 0.5rem; border: 1px solid #ddd;" >
<i nz-icon nzType="tool" nzTheme="outline"></i>
{{btnName}}
</button>
<!--配置龙骨面板-->
<nz-modal [(nzVisible)]="panelVisible" (nzAfterClose)="closePanel()" [nzTitle]="btnName" (nzOnCancel)="panelCancel()" (nzOnOk)="panelOk()" nzOkText="保存">
<div>
<h4>基础内容:</h4>
<div style="margin-bottom: 10px; width: 80%; margin: auto;">
<!-- <nz-radio-group [ngModel]="item.type" (ngModelChange)="radioChange($event)">
<label nz-radio nzValue="pic">图片</label>
<label nz-radio nzValue="text">文本</label>
</nz-radio-group> -->
<div *ngIf="item.type == 'pic'">
<app-upload-image-with-preview
[picUrl]="item?.pic_url"
(imageUploaded)="onItemImgUploadSuccess($event, item)">
</app-upload-image-with-preview>
</div>
<div *ngIf="item.type == 'text'">
<input type="text" nz-input [(ngModel)]="item.text" (blur)="saveText(item)">
</div>
<div *ngIf="item.type == 'anima'" style="margin-left: 100px;">
<app-upload-dragon-bone
[skeJsonData]=item.skeJsonData
[texJsonData]=item.texJsonData
[texPngData]=item.texPngData
(save)="saveAnima($event)"
>
</app-upload-dragon-bone>
</div>
</div>
<nz-divider style="margin-top: 10px;"></nz-divider>
<h4>状态设置:</h4>
<div style="display: flex; justify-content: space-around;">
<div style="width: 30%; display: flex; align-items: center; flex-direction: column;">
<h5> 开始状态 </h5>
<div *ngFor="let op of item.changeOption; let i = index" style="margin-bottom: 5px; ">
<div style="display: flex; align-items: center; justify-content: center;">
<span>{{op[0]}}: </span> <input type="text" nz-input [(ngModel)]="op[1]" (blur)="saveText(op)" style="margin-left: 5px;">
</div>
</div>
</div>
<div style="width: 30%; display: flex; align-items: center; flex-direction: column; ">
<h5> 切换时间 </h5>
<div style="display: flex; width: 100%; align-items: center; justify-content: center;">
<span>time: </span> <input type="text" nz-input [(ngModel)]="item.changeTime" (blur)="saveText(item.changeTime)" style="width: 80px; margin-left: 5px;">
</div>
</div>
<div style="width: 30%; display: flex; align-items: center; flex-direction: column;">
<h5> 结束状态 </h5>
<div *ngFor="let op of item.changeOption; let i = index" style="margin-bottom: 5px; ">
<div style="display: flex; align-items: center; justify-content: center;">
<span>{{op[0]}}: </span> <input [disabled]="op[2] == null" type="text" nz-input [(ngModel)]="op[2]" (blur)="saveText(op)" style="margin-left: 5px;">
</div>
</div>
</div>
</div>
<div style="display: flex; align-items: center; justify-content: center; margin-top: 10px;">
<button style="margin-left: 20px; margin-top: -5px" nz-button (click)="copyChangeData()"> 复制数据 </button>
<div style="margin-left: 20px; margin-top: -5px" >
<span>粘贴数据: </span>
<input style="width: 100px;" type="text" nz-input [(ngModel)]="pasteData" >
<button style="margin-left: 5px;" nz-button [disabled]="pasteData==''" nzType="primary" (click)="importData()">导入</button>
</div>
</div>
<nz-divider style="margin-top: 10px;"></nz-divider>
<h4> 音频设置 </h4>
<app-audio-recorder
style="margin: auto"
[audioUrl]="item?.audio_url"
(audioUploaded)="onItemAudioUploadSuccess($event, item)"
></app-audio-recorder>
</div>
<!--
<div class="anima-upload-btn">
<span style="margin-right: 10px">上传 ske_json 文件: </span>
<nz-upload [nzShowUploadList]="false"
nzAccept="application/json"
[nzAction]="uploadUrl"
[nzData]="uploadData"
(nzChange)="skeJsonHandleChange($event)">
<button nz-button><i nz-icon nzType="upload"></i><span>Upload</span></button>
</nz-upload>
<i *ngIf="isSkeJsonLoading" style="margin-left: 10px;" nz-icon [nzType]="'loading'"></i>
<span *ngIf="skeJsonData && skeJsonData['name']" style="margin-left: 10px"><u> {{skeJsonData['name']}} </u></span>
</div>
<div class="anima-upload-btn">
<span style="margin-right: 10px">上传 tex_json 文件: </span>
<nz-upload [nzShowUploadList]="false"
nzAccept="application/json"
[nzAction]="uploadUrl"
[nzData]="uploadData"
(nzChange)="texJsonHandleChange($event)">
<button nz-button><i nz-icon nzType="upload"></i><span>Upload</span></button>
</nz-upload>
<i *ngIf="isTexJsonLoading" style="margin-left: 10px;" nz-icon [nzType]="'loading'"></i>
<span *ngIf="texJsonData && texJsonData['name']" style="margin-left: 10px"><u> {{texJsonData['name']}} </u></span>
</div>
<div class="anima-upload-btn">
<span style="margin-right: 10px">上传 tex_png 文件: </span>
<nz-upload [nzShowUploadList]="false"
nzAccept = "image/*"
[nzAction]="uploadUrl"
[nzData]="uploadData"
(nzChange)="texPngHandleChange($event)">
<button nz-button><i nz-icon nzType="upload"></i><span>Upload</span></button>
</nz-upload>
<i *ngIf="isTexPngLoading" style="margin-left: 10px;" nz-icon [nzType]="'loading'"></i>
<span *ngIf="texPngData && texPngData['name']" style="margin-left: 10px"><u> {{texPngData['name']}} </u></span>
</div>
<div class="anima-upload-btn" *ngIf="animaNames && animaNames.length > 0">
提示:需包含动画: {{animaNames.toString()}}.
</div> -->
</nz-modal>
</div>
@import '../../style/common_mixin.css';
.p-image-uploader {
position: relative;
display: block;
width: 100%;
height: 0;
padding-bottom: 56.25%;
.p-box {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
border: 2px dashed #ddd;
border-radius: 0.5rem;
background-color: #fafafa;
text-align: center;
color: #aaa;
.p-upload-icon {
text-align: center;
margin: auto;
.anticon-upload {
color: #888;
font-size: 5rem;
}
.p-progress-bar {
position: relative;
width: 20rem;
height: 1.5rem;
border: 1px solid #ccc;
border-radius: 1rem;
.p-progress-bg {
background-color: #1890ff;
border-radius: 1rem;
height: 100%;
}
.p-progress-value {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
text-shadow: 0 0 4px #000;
color: white;
text-align: center;
font-size: 0.9rem;
line-height: 1.5rem;
}
}
}
.p-preview {
width: 100%;
height: 100%;
background-size: contain;
background-repeat: no-repeat;
background-position: 50% 50%;
//background-image: url("https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png");
}
}
.d-flex{
display: flex;
}
}
.p-btn-delete {
position: absolute;
right: -0.5rem;
top: -0.5rem;
width: 2rem;
height: 2rem;
border: 0.2rem solid white;
border-radius: 50%;
font-size: 1.2rem;
background-color: #fb781a;
color: white;
text-align: center;
}
.p-upload-progress-bg {
position: absolute;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
& .i-text {
position: absolute;
text-align: center;
color: white;
text-shadow: 0 0 2px rgba(0, 0, 0, .85);
}
& .i-bg {
position: absolute;
left: 0;
top: 0;
height: 100%;
background-color: #27b43f;
border-radius: 0.5rem;
}
}
.anima-upload-btn {
padding: 10px;
}
:host ::ng-deep .ant-upload {
display: block;
}
import {ApplicationRef, Component, EventEmitter, Input, OnChanges, OnDestroy, Output} from '@angular/core';
import { NzMessageService, UploadXHRArgs, UploadFile } from 'ng-zorro-antd';
@Component({
selector: 'app-custom-action',
templateUrl: './custom-action.component.html',
styleUrls: ['./custom-action.component.scss']
})
export class CustomActionComponent implements OnDestroy, OnChanges {
uploading = false;
progress = 0;
@Input()
btnName = '配置变化状态';
@Input()
option = []
@Input()
item;
@Input()
type = 'text'
@Output()
save = new EventEmitter();
@Output()
refreshEmitter = new EventEmitter();
uploadUrl;
uploadData;
panelVisible = false;
pasteData = '';
constructor(private appRef: ApplicationRef, private nzMessageService: NzMessageService) {
window['air'].getUploadCallback = (url, data) => {
this.uploadUrl = url;
this.uploadData = data;
};
const tmpId = setInterval(() => {
console.log(' in setInterval')
this.uploadUrl = (<any> window).courseware.uploadUrl();
this.uploadData = (<any> window).courseware.uploadData();
if (this.uploadUrl) {
clearInterval(tmpId);
}
}, 500)
}
ngOnInit() {
this.initItem();
}
ngOnChanges() {
}
initItem() {
console.log('```this.item: ', this.item);
if (!this.item) {
this.item = {
type: this.type,
skeJsonData: {},
texJsonData: {},
texPngData: {},
changeStart: [
],
changeEnd: [
],
changeTime: 0.3
};
if (this.option) {
this.item.changeOption = JSON.parse(JSON.stringify(this.option));
}
}
console.log('initItem', this.item);
}
setAnimaBtnClick() {
this.panelVisible = true;
this.refresh();
}
panelCancel() {
this.panelVisible = false;
this.refresh();
}
panelOk() {
// this.sendItemDragonBoneData();
this.panelVisible = false;
this.refresh();
this.save.emit(this.item);
}
saveText(t) {
}
radioChange(e) {
this.item.type = e;
console.log('e: ', e);
}
onItemImgUploadSuccess(e, item) {
item.pic_url = e.url;
this.refresh();
}
onItemAudioUploadSuccess(e, item) {
item.audio_url = e.url;
this.refresh();
}
saveAnima(e) {
console.log("~ e: ", e);
}
copyChangeData() {
console.log('this.item: ', this.item);
const jsonData = {
changeOption: this.item.changeOption,
changeTime : this.item.changeTime
// bgItem,
// hotZoneItemArr,
// isHasRect: this.isHasRect,
// isHasPic: this.isHasPic,
// isHasText: this.isHasText,
// isHasAudio: this.isHasAudio,
// isHasAnima: this.isHasAnima,
// hotZoneFontObj: this.hotZoneFontObj,
// defaultItemType: this.defaultItemType,
// hotZoneImgSize: this.hotZoneImgSize,
};
const oInput = document.createElement('input');
oInput.value = JSON.stringify(jsonData);
document.body.appendChild(oInput);
oInput.select(); // 选择对象
document.execCommand('Copy'); // 执行浏览器复制命令
document.body.removeChild(oInput);
this.nzMessageService.success('复制成功');
}
importData() {
if (!this.pasteData) {
return;
}
try {
const data = JSON.parse(this.pasteData);
console.log('data:', data);
const {
changeOption,
changeTime
} = data;
this.item.changeOption = changeOption;
this.item.changeTime = changeTime;
this.pasteData = '';
} catch (e) {
console.log('err: ', e);
this.nzMessageService.error('导入失败');
}
}
/**
* 刷新 渲染页面
*/
refresh() {
// this.refreshEmitter.emit();
setTimeout(() => {
this.appRef.tick();
}, 1);
}
closePanel() {
console.log(' in closePanel ');
this.refresh();
}
ngOnDestroy() {
}
}
...@@ -329,6 +329,7 @@ export class MySprite extends Sprite { ...@@ -329,6 +329,7 @@ export class MySprite extends Sprite {
this.scaleX = this.scaleY = value; this.scaleX = this.scaleY = value;
} }
getBoundingBox() { getBoundingBox() {
const getParentData = (item) => { const getParentData = (item) => {
...@@ -1956,6 +1957,10 @@ export class HotZoneItem extends MySprite { ...@@ -1956,6 +1957,10 @@ export class HotZoneItem extends MySprite {
audio_url; audio_url;
pic_url; pic_url;
text; text;
gIdx;
isAnimaStyle = false;
private _itemType; private _itemType;
private shapeRect: ShapeRect; private shapeRect: ShapeRect;
...@@ -2056,7 +2061,10 @@ export class HotZoneItem extends MySprite { ...@@ -2056,7 +2061,10 @@ export class HotZoneItem extends MySprite {
this.hideLabel(); this.hideLabel();
} }
setAnimaStyle(isAnimaStyle) {
this.isAnimaStyle = isAnimaStyle;
console.log('in setAnimaStyle ')
}
drawArrow() { drawArrow() {
if (!this.arrow) { return; } if (!this.arrow) { return; }
...@@ -2068,6 +2076,7 @@ export class HotZoneItem extends MySprite { ...@@ -2068,6 +2076,7 @@ export class HotZoneItem extends MySprite {
this.arrow.update(); this.arrow.update();
if (!this.isAnimaStyle) {
this.arrowTop.x = rect.x + rect.width / 2; this.arrowTop.x = rect.x + rect.width / 2;
this.arrowTop.y = rect.y; this.arrowTop.y = rect.y;
this.arrowTop.update(); this.arrowTop.update();
...@@ -2077,6 +2086,8 @@ export class HotZoneItem extends MySprite { ...@@ -2077,6 +2086,8 @@ export class HotZoneItem extends MySprite {
this.arrowRight.update(); this.arrowRight.update();
} }
}
drawFrame() { drawFrame() {
...@@ -2197,8 +2208,26 @@ export class HotZoneLabel extends Label { ...@@ -2197,8 +2208,26 @@ export class HotZoneLabel extends Label {
this.drawFrame(); this.drawFrame();
} }
getLabelRect() {
const rect = this.getBoundingBox();
const width = rect.width / this.scaleX;
const height = this.height * this.scaleY;
const x = this.x - width / 2;
const y = this.y - height / 2;
return {width, height, x, y};
}
} }
export class HotZoneAction extends MySprite {
}
...@@ -2208,6 +2237,8 @@ export class EditorItem extends MySprite { ...@@ -2208,6 +2237,8 @@ export class EditorItem extends MySprite {
arrow: MySprite; arrow: MySprite;
label: Label; label: Label;
text; text;
arrowTop;
arrowRight;
showLabel(text = null) { showLabel(text = null) {
...@@ -2246,6 +2277,13 @@ export class EditorItem extends MySprite { ...@@ -2246,6 +2277,13 @@ export class EditorItem extends MySprite {
this.arrow.load('assets/common/arrow.png', 1, 0); this.arrow.load('assets/common/arrow.png', 1, 0);
this.arrow.setScaleXY(0.06); this.arrow.setScaleXY(0.06);
this.arrowTop = new MySprite(this.ctx);
this.arrowTop.load('assets/common/arrow_top.png', 0.5, 0);
this.arrowTop.setScaleXY(0.06);
this.arrowRight = new MySprite(this.ctx);
this.arrowRight.load('assets/common/arrow_right.png', 1, 0.5);
this.arrowRight.setScaleXY(0.06);
} }
this.showLabel(); this.showLabel();
...@@ -2262,16 +2300,25 @@ export class EditorItem extends MySprite { ...@@ -2262,16 +2300,25 @@ export class EditorItem extends MySprite {
this.hideLabel(); this.hideLabel();
} }
refreshLabelScale() {}
drawArrow() { drawArrow() {
if (!this.arrow) { return; } if (!this.arrow) { return; }
const rect = this.getBoundingBox(); const rect = this.getBoundingBox();
this.arrow.x = rect.x + rect.width; this.arrow.x = rect.x + rect.width;
this.arrow.y = rect.y; this.arrow.y = rect.y;
this.arrow.update(); this.arrow.update();
this.arrowTop.x = rect.x + rect.width / 2;
this.arrowTop.y = rect.y;
this.arrowTop.update();
this.arrowRight.x = rect.x + rect.width;
this.arrowRight.y = rect.y + rect.height / 2;
this.arrowRight.update();
} }
drawFrame() { drawFrame() {
...@@ -2326,783 +2373,73 @@ export class EditorItem extends MySprite { ...@@ -2326,783 +2373,73 @@ export class EditorItem extends MySprite {
//
// export class HotZonePoint extends HotZoneItem {
// import TWEEN from '@tweenjs/tween.js';
// strokeColor = "#000000"
// fillColor = "#00ff00"
// class Sprite { constructor(ctx = null) {
// x = 0; super(ctx);
// y = 0;
// color = '';
// radius = 0; this.radius = 15;
// alive = false;
// margin = 0; this.width = this.radius * 2;
// angle = 0; this.height = this.radius * 2;
// ctx; this.anchorX = this.anchorY = 0.5;
// }
// constructor(ctx) {
// this.ctx = ctx; drawFrame() {
// }
// update($event) { this.ctx.save();
// this.draw();
// } // const rect = this.getBoundingBox();
// draw() { // const w = rect.width / this.scaleX;
// // const h = this.height * this.scaleY;
// } // const x = this.x;
// // const y = this.y;
// }
// // this.ctx.setLineDash([5, 5]);
// this.ctx.lineWidth = 2 * this.scaleX;
// this.ctx.strokeStyle = this.strokeColor;
//
// // this.ctx.beginPath();
// export class MySprite extends Sprite { // this.ctx.moveTo( x - w / 2, y - h / 2);
// // this.ctx.lineTo(x + w / 2, y - h / 2);
// width = 0; // this.ctx.lineTo(x + w / 2, y + h / 2);
// height = 0; // this.ctx.lineTo(x - w / 2, y + h / 2);
// _anchorX = 0; // this.ctx.lineTo(x - w / 2, y - h / 2);
// _anchorY = 0;
// _offX = 0;
// _offY = 0; this.ctx.setLineDash([3, 3]);
// scaleX = 1;
// scaleY = 1; this.ctx.beginPath();
// alpha = 1; this.ctx.fillStyle = this.fillColor;
// rotation = 0; this.ctx.arc(this.x, this.y, this.radius * this.scaleX, 0, angleToRadian(360));
// visible = true; this.ctx.fill();
//
// children = [this]; // this.ctx.fill();
// this.ctx.stroke();
// img;
// _z = 0; this.ctx.restore();
// }
//
// init(imgObj = null, anchorX:number = 0.5, anchorY:number = 0.5) { draw() {
// super.draw();
// if (imgObj) {
// this.drawFrame();
// this.img = imgObj; }
//
// this.width = this.img.width;
// this.height = this.img.height; getLabelRect() {
// }
//
// this.anchorX = anchorX; const rect = this.getBoundingBox();
// this.anchorY = anchorY; const width = rect.width / this.scaleX;
// } const height = this.height * this.scaleY;
// const x = this.x - width / 2;
// const y = this.y - height / 2;
//
// update($event = null) { return {width, height, x, y};
// if (this.visible) { }
// this.draw(); }
// }
// }
// draw() {
//
// this.ctx.save();
//
// this.drawInit();
//
// this.updateChildren();
//
// this.ctx.restore();
// }
//
// drawInit() {
//
// 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;
//
// }
//
// drawSelf() {
// 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) {
//
// this.drawSelf();
// } else {
//
// this.children[i].update();
// }
// }
// }
//
//
// load(url, anchorX = 0.5, anchorY = 0.5) {
//
// return new Promise((resolve, reject) => {
// const img = new Image();
// img.onload = () => resolve(img);
// img.onerror = reject;
// img.src = url;
// }).then(img => {
//
// this.init(img, anchorX, anchorY);
// return img;
// });
// }
//
// addChild(child, z = 1) {
// if (this.children.indexOf(child) === -1) {
// this.children.push(child);
// child._z = z;
// child.parent = this;
// }
//
// this.children.sort((a, b) => {
// return a._z - b._z;
// });
//
// }
// removeChild(child) {
// const index = this.children.indexOf(child);
// if (index !== -1) {
// this.children.splice(index, 1);
// }
// }
//
// 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;
// }
//
// setScaleXY(value) {
// this.scaleX = this.scaleY = value;
// }
//
// 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};
// }
//
// }
//
//
//
//
//
// export class Item extends MySprite {
//
// baseX;
//
// move(targetY, callBack) {
//
// const self = this;
//
// const tween = new TWEEN.Tween(this)
// .to({ y: targetY }, 2500)
// .easing(TWEEN.Easing.Quintic.Out)
// .onComplete(function() {
//
// self.hide(callBack);
// // if (callBack) {
// // callBack();
// // }
// })
// .start();
//
// }
//
// show(callBack = null) {
//
// const tween = new TWEEN.Tween(this)
// .to({ alpha: 1 }, 800)
// // .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
// .onComplete(function() {
// if (callBack) {
// callBack();
// }
// })
// .start(); // Start the tween immediately.
//
// }
//
// hide(callBack = null) {
//
// const tween = new TWEEN.Tween(this)
// .to({ alpha: 0 }, 800)
// // .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
// .onComplete(function() {
// if (callBack) {
// callBack();
// }
// })
// .start(); // Start the tween immediately.
// }
//
//
// shake(id) {
//
//
// if (!this.baseX) {
// this.baseX = this.x;
// }
//
// const baseX = this.baseX;
// const baseTime = 50;
// const sequence = [
// {target: {x: baseX + 40 * id}, time: baseTime - 25},
// {target: {x: baseX - 20 * id}, time: baseTime},
// {target: {x: baseX + 10 * id}, time: baseTime},
// {target: {x: baseX - 5 * id}, time: baseTime},
// {target: {x: baseX + 2 * id}, time: baseTime},
// {target: {x: baseX - 1 * id}, time: baseTime},
// {target: {x: baseX}, time: baseTime},
//
// ];
//
//
// const self = this;
//
// function runSequence() {
//
// if (self['shakeTween']) {
// self['shakeTween'].stop();
// }
//
// const tween = new TWEEN.Tween(self);
//
// if (sequence.length > 0) {
// // console.log('sequence.length: ', sequence.length);
// const action = sequence.shift();
// tween.to(action['target'], action['time']);
// tween.onComplete( () => {
// runSequence();
// });
// tween.start();
//
// self['shakeTween'] = tween;
// }
// }
//
// runSequence();
//
// }
//
//
//
// drop(targetY, callBack = null) {
//
// const self = this;
//
// const time = Math.abs(targetY - this.y) * 2.4;
//
// this.alpha = 1;
//
// const tween = new TWEEN.Tween(this)
// .to({ y: targetY }, time)
// .easing(TWEEN.Easing.Cubic.In)
// .onComplete(function() {
//
// // self.hideItem(callBack);
// if (callBack) {
// callBack();
// }
// })
// .start();
//
//
// }
//
//
// }
//
//
// export class EndSpr extends MySprite {
//
// show(s) {
//
// this.scaleX = this.scaleY = 0;
// this.alpha = 0;
//
// const tween = new TWEEN.Tween(this)
// .to({ alpha: 1, scaleX: s, scaleY: s }, 800)
// .easing(TWEEN.Easing.Elastic.Out) // Use an easing function to make the animation smooth.
// .onComplete(function() {
//
// })
// .start(); // Start the tween immediately.
//
// }
// }
//
//
//
// export class ShapeRect extends MySprite {
//
// fillColor = '#FF0000';
//
// setSize(w, h) {
// this.width = w;
// this.height = h;
//
// console.log('w:', w);
// console.log('h:', h);
// }
//
// drawShape() {
//
// this.ctx.fillStyle = this.fillColor;
// this.ctx.fillRect(this._offX, this._offY, this.width, this.height);
//
// }
//
//
// drawSelf() {
// super.drawSelf();
// this.drawShape();
// }
// }
//
//
// export class HotZoneItem extends MySprite {
//
//
// lineDashFlag = false;
// arrow: MySprite;
// label: Label;
// title;
//
// arrowTop;
// arrowRight;
//
// audio_url;
// pic_url;
// text;
// private _itemType;
// private shapeRect: ShapeRect;
//
// get itemType() {
// return this._itemType;
// }
// set itemType(value) {
// this._itemType = value;
// }
//
// setSize(w, h) {
// this.width = w;
// this.height = h;
//
//
// const rect = new ShapeRect(this.ctx);
// rect.x = -w / 2;
// rect.y = -h / 2;
// rect.setSize(w, h);
// rect.fillColor = '#ffffff';
// rect.alpha = 0.2;
// this.addChild(rect);
// }
//
// showLabel(text = null) {
//
//
// if (!this.label) {
// this.label = new Label(this.ctx);
// this.label.anchorY = 0;
// this.label.fontSize = '40px';
// this.label.textAlign = 'center';
// this.addChild(this.label);
// // this.label.scaleX = 1 / this.scaleX;
// // this.label.scaleY = 1 / this.scaleY;
//
// this.refreshLabelScale();
//
// }
//
// if (text) {
// this.label.text = text;
// } else if (this.title) {
// this.label.text = this.title;
// }
// this.label.visible = true;
//
// }
//
// hideLabel() {
// if (!this.label) { return; }
//
// this.label.visible = false;
// }
//
// refreshLabelScale() {
// if (this.scaleX == this.scaleY) {
// this.label.setScaleXY(1);
// }
//
// if (this.scaleX > this.scaleY) {
// this.label.scaleX = this.scaleY / this.scaleX;
// } else {
// this.label.scaleY = this.scaleX / this.scaleY;
// }
// }
//
// showLineDash() {
// this.lineDashFlag = true;
//
// if (this.arrow) {
// this.arrow.visible = true;
// } else {
// this.arrow = new MySprite(this.ctx);
// this.arrow.load('assets/common/arrow.png', 1, 0);
// this.arrow.setScaleXY(0.06);
//
// this.arrowTop = new MySprite(this.ctx);
// this.arrowTop.load('assets/common/arrow_top.png', 0.5, 0);
// this.arrowTop.setScaleXY(0.06);
//
// this.arrowRight = new MySprite(this.ctx);
// this.arrowRight.load('assets/common/arrow_right.png', 1, 0.5);
// this.arrowRight.setScaleXY(0.06);
// }
//
// this.showLabel();
// }
//
// hideLineDash() {
//
// this.lineDashFlag = false;
//
// if (this.arrow) {
// this.arrow.visible = false;
// }
//
// this.hideLabel();
// }
//
//
//
// drawArrow() {
// if (!this.arrow) { return; }
//
// const rect = this.getBoundingBox();
// this.arrow.x = rect.x + rect.width;
// this.arrow.y = rect.y;
//
// this.arrow.update();
//
//
// this.arrowTop.x = rect.x + rect.width / 2;
// this.arrowTop.y = rect.y;
// this.arrowTop.update();
//
// this.arrowRight.x = rect.x + rect.width;
// this.arrowRight.y = rect.y + rect.height / 2;
// this.arrowRight.update();
// }
//
// drawFrame() {
//
//
// this.ctx.save();
//
//
// const rect = this.getBoundingBox();
//
// const w = rect.width;
// const h = rect.height;
// const x = rect.x + w / 2;
// const y = rect.y + h / 2;
//
// this.ctx.setLineDash([5, 5]);
// this.ctx.lineWidth = 2;
// this.ctx.strokeStyle = '#1bfff7';
// // this.ctx.fillStyle = '#ffffff';
//
// this.ctx.beginPath();
//
// this.ctx.moveTo( x - w / 2, y - h / 2);
//
// this.ctx.lineTo(x + w / 2, y - h / 2);
//
// this.ctx.lineTo(x + w / 2, y + h / 2);
//
// this.ctx.lineTo(x - w / 2, y + h / 2);
//
// this.ctx.lineTo(x - w / 2, y - h / 2);
//
// // this.ctx.fill();
// this.ctx.stroke();
//
//
//
//
// this.ctx.restore();
//
// }
//
// draw() {
// super.draw();
//
// if (this.lineDashFlag) {
// this.drawFrame();
// this.drawArrow();
// }
// }
// }
//
//
// export class EditorItem extends MySprite {
//
// lineDashFlag = false;
// arrow: MySprite;
// label:Label;
// text;
//
// showLabel(text = null) {
//
//
// if (!this.label) {
// this.label = new Label(this.ctx);
// this.label.anchorY = 0;
// this.label.fontSize = '50px';
// this.label.textAlign = 'center';
// this.addChild(this.label);
// this.label.setScaleXY(1 / this.scaleX);
// }
//
// if (text) {
// this.label.text = text;
// } else if (this.text) {
// this.label.text = this.text;
// }
// this.label.visible = true;
//
// }
//
// hideLabel() {
// if (!this.label) { return; }
//
// this.label.visible = false;
// }
//
// showLineDash() {
// this.lineDashFlag = true;
//
// if (this.arrow) {
// this.arrow.visible = true;
// } else {
// this.arrow = new MySprite(this.ctx);
// this.arrow.load('assets/common/arrow.png', 1, 0);
// this.arrow.setScaleXY(0.06);
//
// }
//
// this.showLabel();
// }
//
// hideLineDash() {
//
// this.lineDashFlag = false;
//
// if (this.arrow) {
// this.arrow.visible = false;
// }
//
// this.hideLabel();
// }
//
//
//
// drawArrow() {
// if (!this.arrow) { return; }
//
// const rect = this.getBoundingBox();
// this.arrow.x = rect.x + rect.width;
// this.arrow.y = rect.y;
//
// this.arrow.update();
// }
//
// drawFrame() {
//
//
// this.ctx.save();
//
//
// const rect = this.getBoundingBox();
//
// const w = rect.width;
// const h = rect.height;
// const x = rect.x + w / 2;
// const y = rect.y + h / 2;
//
// this.ctx.setLineDash([5, 5]);
// this.ctx.lineWidth = 2;
// this.ctx.strokeStyle = '#1bfff7';
// // this.ctx.fillStyle = '#ffffff';
//
// this.ctx.beginPath();
//
// this.ctx.moveTo( x - w / 2, y - h / 2);
//
// this.ctx.lineTo(x + w / 2, y - h / 2);
//
// this.ctx.lineTo(x + w / 2, y + h / 2);
//
// this.ctx.lineTo(x - w / 2, y + h / 2);
//
// this.ctx.lineTo(x - w / 2, y - h / 2);
//
// // this.ctx.fill();
// this.ctx.stroke();
//
//
//
//
// this.ctx.restore();
//
// }
//
// draw() {
// super.draw();
//
// if (this.lineDashFlag) {
// this.drawFrame();
// this.drawArrow();
// }
// }
// }
//
//
//
// export class Label extends MySprite {
//
// text:String;
// fontSize:String = '40px';
// fontName:String = 'Verdana';
// textAlign:String = 'left';
//
//
// constructor(ctx) {
// super(ctx);
// this.init();
// }
//
// drawText() {
//
// // console.log('in drawText', this.text);
//
// if (!this.text) { return; }
//
// this.ctx.font = `${this.fontSize} ${this.fontName}`;
// this.ctx.textAlign = this.textAlign;
// this.ctx.textBaseline = 'middle';
// this.ctx.fontWeight = 900;
//
// this.ctx.lineWidth = 5;
// this.ctx.strokeStyle = '#ffffff';
// this.ctx.strokeText(this.text, 0, 0);
//
// this.ctx.fillStyle = '#000000';
// this.ctx.fillText(this.text, 0, 0);
//
//
// }
//
//
// drawSelf() {
// super.drawSelf();
// this.drawText();
// }
//
// }
//
//
//
// export function getPosByAngle(angle, len) {
//
// const radian = angle * Math.PI / 180;
// const x = Math.sin(radian) * len;
// const y = Math.cos(radian) * len;
//
// return {x, y};
//
// }
//
// export function getAngleByPos(px, py, mx, my) {
//
// // const _x = p2x - p1x;
// // const _y = p2y - p1y;
// // const tan = _y / _x;
// //
// // const radina = Math.atan(tan); // 用反三角函数求弧度
// // const angle = Math.floor(180 / (Math.PI / radina)); //
// //
// // console.log('r: ' , angle);
// // return angle;
// //
//
//
//
// const x = Math.abs(px - mx);
// const y = Math.abs(py - my);
// // const x = Math.abs(mx - px);
// // const y = Math.abs(my - py);
// const z = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
// const cos = y / z;
// const radina = Math.acos(cos); // 用反三角函数求弧度
// let angle = Math.floor(180 / (Math.PI / radina) * 100) / 100; // 将弧度转换成角度
//
// if(mx > px && my > py) {// 鼠标在第四象限
// angle = 180 - angle;
// }
//
// if(mx === px && my > py) {// 鼠标在y轴负方向上
// angle = 180;
// }
//
// if(mx > px && my === py) {// 鼠标在x轴正方向上
// angle = 90;
// }
//
// if(mx < px && my > py) {// 鼠标在第三象限
// angle = 180 + angle;
// }
//
// if(mx < px && my === py) {// 鼠标在x轴负方向
// angle = 270;
// }
//
// if(mx < px && my < py) {// 鼠标在第二象限
// angle = 360 - angle;
// }
//
// // console.log('angle: ', angle);
// return angle;
//
// }
...@@ -32,15 +32,80 @@ ...@@ -32,15 +32,80 @@
<nz-divider style="margin-top: 10px;"></nz-divider> <nz-divider style="margin-top: 10px;"></nz-divider>
<div style="margin-top: -20px; margin-bottom: 5px; width: 100%;">
<div *ngIf="customTypeGroupArr">
<nz-radio-group [ngModel]="it.gIdx" (ngModelChange)="customRadioChange($event, it)" style="display: flex; align-items: center; justify-content: center; flex-wrap: wrap;">
<div *ngFor="let group of customTypeGroupArr; let gIdx = index" style="display: flex; ">
<label nz-radio nzValue="{{gIdx}}">{{group.name}}</label>
</div>
</nz-radio-group>
</div>
<!-- <div *ngIf="!customTypeGroupArr">
<nz-radio-group [ngModel]="it.itemType" (ngModelChange)="radioChange($event, it)" style="display: flex; align-items: center; justify-content: center">
<div style="margin-top: -20px; margin-bottom: 5px">
<nz-radio-group [ngModel]="it.itemType" (ngModelChange)="radioChange($event, it)">
<label *ngIf="isHasRect" nz-radio nzValue="rect">矩形</label> <label *ngIf="isHasRect" nz-radio nzValue="rect">矩形</label>
<label *ngIf="isHasPic" nz-radio nzValue="pic">图片</label> <label *ngIf="isHasPic" nz-radio nzValue="pic">图片</label>
<label *ngIf="isHasText" nz-radio nzValue="text">文本</label> <label *ngIf="isHasText" nz-radio nzValue="text">文本</label>
</nz-radio-group> </nz-radio-group>
</div> -->
</div>
<div *ngIf="customTypeGroupArr && customTypeGroupArr[it.gIdx]">
<div *ngIf="customTypeGroupArr[it.gIdx].pic">
<app-upload-image-with-preview
[picUrl]="it?.pic_url"
(imageUploaded)="onItemImgUploadSuccess($event, it)">
</app-upload-image-with-preview>
</div>
<div *ngIf="customTypeGroupArr[it.gIdx].text" style="margin-top: 5px">
<input type="text" nz-input [(ngModel)]="it.text" (blur)="saveText(it)">
</div>
<div *ngIf="customTypeGroupArr[it.gIdx].anima" align="center" style="margin-top: 5px">
<button nz-button (click)="setAnimaBtnClick(i)" >
<i nz-icon nzType="tool" nzTheme="outline"></i>
配置龙骨动画
</button>
</div>
<div *ngIf="customTypeGroupArr[it.gIdx].animaSmall" align="center" style="margin-top: 5px">
<button nz-button (click)="setAnimaSmallBtnClick(i)" >
<i nz-icon nzType="tool" nzTheme="outline"></i>
配置龙骨动画(小)
</button>
</div>
<div *ngIf="customTypeGroupArr[it.gIdx].audio" style="display: flex;align-items: center; margin-top: 5px">
<app-audio-recorder
style="margin: auto"
[audioUrl]="it.audio_url"
(audioUploaded)="onItemAudioUploadSuccess($event, it)"
></app-audio-recorder>
</div> </div>
<div *ngIf="customTypeGroupArr[it.gIdx]?.action" style="display: flex;align-items: center; margin-top: 5px">
<app-custom-action
style="margin: auto"
[item]="it ? it['actionData_' + it.gIdx] : {}"
[type]="customTypeGroupArr[it.gIdx].action.type"
[option]="customTypeGroupArr[it.gIdx].action.option"
(save)="onSaveCustomAction($event, it)">
></app-custom-action>
</div>
</div>
<!-- <div *ngIf="!customTypeGroupArr">
<div *ngIf="it.itemType == 'pic'"> <div *ngIf="it.itemType == 'pic'">
<app-upload-image-with-preview <app-upload-image-with-preview
[picUrl]="it?.pic_url" [picUrl]="it?.pic_url"
...@@ -52,13 +117,26 @@ ...@@ -52,13 +117,26 @@
<input type="text" nz-input [(ngModel)]="it.text" (blur)="saveText(it)"> <input type="text" nz-input [(ngModel)]="it.text" (blur)="saveText(it)">
</div> </div>
<div style="width: 100%; margin-top: 5px;"> <div *ngIf="isHasAudio"
style="width: 100%; margin-top: 5px; display: flex; align-items: center; justify-items: center;">
<app-audio-recorder <app-audio-recorder
style="margin: auto"
[audioUrl]="it.audio_url" [audioUrl]="it.audio_url"
(audioUploaded)="onItemAudioUploadSuccess($event, it)" (audioUploaded)="onItemAudioUploadSuccess($event, it)"
></app-audio-recorder> ></app-audio-recorder>
</div> </div>
<div *ngIf="it.itemType == 'rect' && isHasAnima" align="center" style="margin-bottom: 5px">
<button nz-button (click)="setAnimaBtnClick(i)" >
<i nz-icon nzType="tool" nzTheme="outline"></i>
配置龙骨动画
</button>
</div>
</div> -->
</div> </div>
</div> </div>
...@@ -83,12 +161,29 @@ ...@@ -83,12 +161,29 @@
<div class="save-box"> <div class="save-box">
<button class="save-btn" nz-button nzType="primary" [nzSize]="'large'" nzShape="round" <button style="margin-left: 200px" class="save-btn" nz-button nzType="primary" [nzSize]="'large'" nzShape="round"
(click)="saveClick()" > (click)="saveClick()" >
<i nz-icon nzType="save"></i> <i nz-icon nzType="save"></i>
Save Save
</button> </button>
<div *ngIf="isCopyData" style="height: 40px; display: flex; justify-items: center;" >
<label style="margin-left: 40px" nz-checkbox [(ngModel)]="bgItem.isShowDebugLine">显示辅助框</label>
<button style="margin-left: 20px; margin-top: -5px" nz-button (click)="copyHotZoneData()"> 复制基础数据 </button>
<div style="margin-left: 10px; margin-top: -5px" >
<span>粘贴数据: </span>
<input style="width: 100px;" type="text" nz-input [(ngModel)]="pasteData" >
<button style="margin-left: 5px;" nz-button [disabled]="pasteData==''" nzType="primary" (click)="importData()">导入</button>
</div>
</div>
</div> </div>
...@@ -98,3 +193,52 @@ ...@@ -98,3 +193,52 @@
<label style="opacity: 0; position: absolute; top: 0px; font-family: 'BRLNSR_1'">1</label> <label style="opacity: 0; position: absolute; top: 0px; font-family: 'BRLNSR_1'">1</label>
<!--龙骨面板-->
<nz-modal [(nzVisible)]="animaPanelVisible" nzTitle="配置资源文件" (nzAfterClose)="closeAfterPanel()" (nzOnCancel)="animaPanelCancel()" (nzOnOk)="animaPanelOk()" nzOkText="保存">
<div class="anima-upload-btn">
<span style="margin-right: 10px">上传 ske_json 文件: </span>
<nz-upload [nzShowUploadList]="false"
nzAccept="application/json"
[nzAction]="uploadUrl"
[nzData]="uploadData"
(nzChange)="skeJsonHandleChange($event)">
<button nz-button><i nz-icon nzType="upload"></i><span>Upload</span></button>
</nz-upload>
<i *ngIf="isSkeJsonLoading" style="margin-left: 10px;" nz-icon [nzType]="'loading'"></i>
<span *ngIf="skeJsonData['name']" style="margin-left: 10px"><u> {{skeJsonData['name']}} </u></span>
</div>
<div class="anima-upload-btn">
<span style="margin-right: 10px">上传 tex_json 文件: </span>
<nz-upload [nzShowUploadList]="false"
nzAccept="application/json"
[nzAction]="uploadUrl"
[nzData]="uploadData"
(nzChange)="texJsonHandleChange($event)">
<button nz-button><i nz-icon nzType="upload"></i><span>Upload</span></button>
</nz-upload>
<i *ngIf="isTexJsonLoading" style="margin-left: 10px;" nz-icon [nzType]="'loading'"></i>
<span *ngIf="texJsonData['name']" style="margin-left: 10px"><u> {{texJsonData['name']}} </u></span>
</div>
<div class="anima-upload-btn">
<span style="margin-right: 10px">上传 tex_png 文件: </span>
<nz-upload [nzShowUploadList]="false"
nzAccept = "image/*"
[nzAction]="uploadUrl"
[nzData]="uploadData"
(nzChange)="texPngHandleChange($event)">
<button nz-button><i nz-icon nzType="upload"></i><span>Upload</span></button>
</nz-upload>
<i *ngIf="isTexPngLoading" style="margin-left: 10px;" nz-icon [nzType]="'loading'"></i>
<span *ngIf="texPngData['name']" style="margin-left: 10px"><u> {{texPngData['name']}} </u></span>
</div>
<div class="anima-upload-btn" *ngIf="customTypeGroupArr && customTypeGroupArr[curDragonBoneGIdx] && customTypeGroupArr[curDragonBoneGIdx].animaNames">
提示:需包含以下动画: {{customTypeGroupArr[curDragonBoneGIdx].animaNames.toString()}}
</div>
</nz-modal>
...@@ -81,19 +81,21 @@ ...@@ -81,19 +81,21 @@
} }
} }
h5 { .anima-upload-btn {
margin-top: 1rem; padding: 10px;
} }
h5 {
margin-top: 1rem;
@font-face
{
font-family: 'BRLNSR_1';
src: url("/assets/font/BRLNSR_1.TTF") ;
} }
//
//@font-face
//{
// font-family: 'BRLNSR_1';
// src: url("/assets/font/BRLNSR_1.TTF") ;
//}
...@@ -107,104 +109,3 @@ h5 { ...@@ -107,104 +109,3 @@ h5 {
//@import '../../../style/common_mixin';
//
//.p-image-uploader {
// position: relative;
// display: block;
// width: 100%;
// height: 0;
// padding-bottom: 56.25%;
// .p-box {
// position: absolute;
// left: 0;
// top: 0;
// right: 0;
// bottom: 0;
// border: 2px dashed #ddd;
// border-radius: 0.5rem;
// background-color: #fafafa;
// text-align: center;
// color: #aaa;
// .p-upload-icon {
// text-align: center;
// margin: auto;
// .anticon-upload {
// color: #888;
// font-size: 5rem;
// }
// .p-progress-bar {
// position: relative;
// width: 20rem;
// height: 1.5rem;
// border: 1px solid #ccc;
// border-radius: 1rem;
// .p-progress-bg {
// background-color: #1890ff;
// border-radius: 1rem;
// height: 100%;
// }
// .p-progress-value {
// position: absolute;
// top: 0;
// left: 0;
// width: 100%;
// height: 100%;
// text-shadow: 0 0 4px #000;
// color: white;
// text-align: center;
// font-size: 0.9rem;
// line-height: 1.5rem;
// }
// }
// }
// .p-preview {
// width: 100%;
// height: 100%;
// //background-image: url("https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png");
// @include k-img-bg();
// }
// }
//}
//
//.p-btn-delete {
// position: absolute;
// right: -0.5rem;
// top: -0.5rem;
// width: 2rem;
// height: 2rem;
// border: 0.2rem solid white;
// border-radius: 50%;
// font-size: 1.2rem;
// background-color: #fb781a;
// color: white;
// text-align: center;
//}
//
//.p-upload-progress-bg {
// position: absolute;
// width: 100%;
// height: 100%;
// display: flex;
// align-items: center;
// justify-content: center;
// & .i-text {
// position: absolute;
// text-align: center;
// color: white;
// text-shadow: 0 0 2px rgba(0, 0, 0, .85);
// }
// & .i-bg {
// position: absolute;
// left: 0;
// top: 0;
// height: 100%;
// background-color: #27b43f;
// border-radius: 0.5rem;
// }
//}
//
//
//:host ::ng-deep .ant-upload {
// display: block;
//}
import { import {
ApplicationRef,
ChangeDetectorRef,
Component, Component,
ElementRef, ElementRef,
EventEmitter, EventEmitter,
...@@ -12,10 +14,11 @@ import { ...@@ -12,10 +14,11 @@ import {
} from '@angular/core'; } from '@angular/core';
import {Subject} from 'rxjs'; import {Subject} from 'rxjs';
import {debounceTime} from 'rxjs/operators'; import {debounceTime} from 'rxjs/operators';
import {EditorItem, HotZoneImg, HotZoneItem, HotZoneLabel, Label, MySprite, removeItemFromArr} from './Unit'; import {EditorItem, HotZoneImg, HotZoneItem, HotZoneLabel, HotZonePoint, Label, MySprite, removeItemFromArr, ShapeRect, ShapeRectNew} from './Unit';
import TWEEN from '@tweenjs/tween.js'; import TWEEN from '@tweenjs/tween.js';
import {getMinScale} from "../../play/Unit"; import {getMinScale} from '../../play/Unit';
import {tar} from "compressing"; import {tar} from 'compressing';
import {NzMessageService} from 'ng-zorro-antd';
@Component({ @Component({
...@@ -25,18 +28,14 @@ import {tar} from "compressing"; ...@@ -25,18 +28,14 @@ import {tar} from "compressing";
}) })
export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
@ViewChild('canvas', {static: true}) canvas: ElementRef;
@ViewChild('wrap', {static: true}) wrap: ElementRef;
@Input()
imgItemArr = null;
@Input() @Input()
hotZoneItemArr = null; hotZoneItemArr = null;
@Input() @Input()
hotZoneArr = null; hotZoneArr = null;
@Output()
save = new EventEmitter();
@ViewChild('canvas', {static: true}) canvas: ElementRef;
@ViewChild('wrap', {static: true}) wrap: ElementRef;
@Input() @Input()
isHasRect = true; isHasRect = true;
@Input() @Input()
...@@ -44,16 +43,30 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -44,16 +43,30 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
@Input() @Input()
isHasText = true; isHasText = true;
@Input() @Input()
hotZoneFontObj = { isHasAudio = true;
size: 50,
name: 'BRLNSR_1',
color: '#8f3758'
}
@Input() @Input()
defaultItemType = 'text'; isHasAnima = false;
@Input()
customTypeGroupArr; // [{name:string, rect:boolean, pic:boolean, text:boolean, audio:boolean, anima:boolean, animaNames:['name1', ..]}, ...]
@Input()
hotZoneFontObj;
@Input()
isCopyData = false;
// hotZoneFontObj = {
// size: 50,
// name: 'BRLNSR_1',
// color: '#8f3758'
// }
@Input() @Input()
hotZoneImgSize = 190; defaultItemType = 'text';
@Input()
hotZoneImgSize = 0;
@Output()
save = new EventEmitter();
saveDisabled = true; saveDisabled = true;
...@@ -86,8 +99,33 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -86,8 +99,33 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
changeSizeFlag = false; changeSizeFlag = false;
changeTopSizeFlag = false; changeTopSizeFlag = false;
changeRightSizeFlag = false; changeRightSizeFlag = false;
animaPanelVisible = false;
uploadUrl;
uploadData;
skeJsonData = {};
texJsonData = {};
texPngData = {};
animaName = '';
curDragonBoneIndex;
curDragonBoneGIdx;
pasteData = '';
isSkeJsonLoading = false;
isTexJsonLoading = false;
isTexPngLoading = false;
constructor() { isAnimaSmall = false;
constructor(private nzMessageService: NzMessageService, private appRef: ApplicationRef, private changeDetectorRef: ChangeDetectorRef) {
this.uploadUrl = (<any> window).courseware.uploadUrl();
this.uploadData = (<any> window).courseware.uploadData();
window['air'].getUploadCallback = (url, data) => {
this.uploadUrl = url;
this.uploadData = data;
};
} }
_bgItem = null; _bgItem = null;
...@@ -110,11 +148,14 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -110,11 +148,14 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
ngOnInit() { ngOnInit() {
this.initListener(); this.initListener();
// this.init(); // this.init();
this.update(); this.update();
this.refresh();
} }
ngOnDestroy() { ngOnDestroy() {
...@@ -136,10 +177,12 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -136,10 +177,12 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
onItemImgUploadSuccess(e, item) { onItemImgUploadSuccess(e, item) {
item.pic_url = e.url; item.pic_url = e.url;
this.loadHotZonePic(item.pic, e.url); this.loadHotZonePic(item.pic, e.url);
this.refresh();
} }
onItemAudioUploadSuccess(e, item) { onItemAudioUploadSuccess(e, item) {
item.audio_url = e.url; item.audio_url = e.url;
this.refresh();
} }
...@@ -150,8 +193,12 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -150,8 +193,12 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
this.renderArr.push(this.bg); this.renderArr.push(this.bg);
} }
if (!this.bgItem.url) {
this.bgItem.url = 'http://teach.cdn.ireadabc.com/8ebb1858564340ea0936b83e3280ad7d.jpg';
}
const bg = this.bg; const bg = this.bg;
if (this.bgItem.url) { // if (this.bgItem.url) {
bg.load(this.bgItem.url).then(() => { bg.load(this.bgItem.url).then(() => {
const rate1 = this.canvasWidth / bg.width; const rate1 = this.canvasWidth / bg.width;
...@@ -167,8 +214,11 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -167,8 +214,11 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
if (callBack) { if (callBack) {
callBack(); callBack();
} }
this.refresh();
}); });
} // }
} }
...@@ -191,6 +241,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -191,6 +241,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
const item = this.hotZoneArr.splice(index, 1)[0]; const item = this.hotZoneArr.splice(index, 1)[0];
removeItemFromArr(this.renderArr, item.pic); removeItemFromArr(this.renderArr, item.pic);
removeItemFromArr(this.renderArr, item.textLabel); removeItemFromArr(this.renderArr, item.textLabel);
removeItemFromArr(this.renderArr, item.point);
this.refreshHotZoneId(); this.refreshHotZoneId();
...@@ -199,6 +250,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -199,6 +250,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
onImgUploadSuccessByImg(e, img) { onImgUploadSuccessByImg(e, img) {
img.pic_url = e.url; img.pic_url = e.url;
this.refreshImage(img); this.refreshImage(img);
this.refresh();
} }
refreshImage(img) { refreshImage(img) {
...@@ -221,6 +273,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -221,6 +273,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
} }
} }
this.refresh();
} }
...@@ -245,10 +298,17 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -245,10 +298,17 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
item.anchorX = 0.5; item.anchorX = 0.5;
item.anchorY = 0.5; item.anchorY = 0.5;
item.x = this.canvasWidth / 2; item.x = this.canvasWidth / 2;
item.y = this.canvasHeight / 2; item.y = this.canvasHeight / 2;
item.itemType = this.defaultItemType; item.itemType = this.getDefaultItemType();
item.gIdx = '0';
item['id'] = new Date().getTime().toString();
item['data'] = saveData;
console.log('item.x: ', item.x);
if (saveData) { if (saveData) {
...@@ -257,41 +317,183 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -257,41 +317,183 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
item.scaleY = saveRect.height / item.height; item.scaleY = saveRect.height / item.height;
item.x = saveRect.x + saveRect.width / 2; item.x = saveRect.x + saveRect.width / 2;
item.y = saveRect.y + saveRect.height / 2; item.y = saveRect.y + saveRect.height / 2;
item.gIdx = saveData.gIdx;
item['id'] = saveData.id;
item['skeJsonData'] = saveData.skeJsonData;
item['texJsonData'] = saveData.texJsonData;
item['texPngData'] = saveData.texPngData;
item['actionData_' + item.gIdx] = saveData['actionData_' + item.gIdx];
} }
console.log('item.x:~~ ', item.x);
item.showLineDash(); item.showLineDash();
const pic = new HotZoneImg(this.ctx); // const pic = new HotZoneImg(this.ctx);
this.setItemPic(item, saveData);
this.setItemLabel(item, saveData);
this.setItemAnima(item, saveData);
this.setItemPoint(item, saveData);
return item;
}
setItemPic(item, saveData) {
console.log('in setItemPic ', saveData);
const pic = new EditorItem(this.ctx);
pic.visible = false; pic.visible = false;
item['pic'] = pic; item['pic'] = pic;
if (saveData && saveData.pic_url) { if (saveData) {
this.loadHotZonePic(pic, saveData.pic_url);
let picUrl = saveData.pic_url;
const actionData = saveData['actionData_' + item.gIdx];
if (actionData && actionData.type == 'pic') {
picUrl = actionData.pic_url;
}
console.log('saveData: ', saveData);
console.log('picUrl: ', picUrl);
if (picUrl) {
this.loadHotZonePic(pic, picUrl, saveData);
}
} }
pic.x = item.x; pic.x = item.x;
pic.y = item.y; pic.y = item.y;
this.renderArr.push(pic); this.renderArr.push(pic);
}
setItemAnima(item, saveData) {
console.log('in setItemAnima ', saveData);
// const pic = new EditorItem(this.ctx);
// pic.visible = false;
// item['pic'] = pic;
// if (saveData) {
// let picUrl = saveData.pic_url;
// const actionData = saveData['actionData_' + item.gIdx];
// if (actionData && actionData.type == 'pic') {
// picUrl = actionData.pic_url;
// }
// console.log('saveData: ', saveData);
// console.log('picUrl: ', picUrl);
// if (picUrl) {
// this.loadHotZonePic(pic, picUrl, saveData.imgScale);
// }
// }
// pic.x = item.x;
// pic.y = item.y;
// this.renderArr.push(pic);
}
setItemPoint(item, saveData) {
console.log('in setItemPoint ', saveData);
const point = new HotZonePoint(this.ctx);
point.visible = false;
item['point'] = point;
item.width = point.width;
item.height = point.height;
// const pic = new EditorItem(this.ctx);
// pic.visible = false;
// item['pic'] = pic;
// if (saveData) {
// let picUrl = saveData.pic_url;
// const actionData = saveData['actionData_' + item.gIdx];
// if (actionData && actionData.type == 'pic') {
// picUrl = actionData.pic_url;
// }
// console.log('saveData: ', saveData);
// console.log('picUrl: ', picUrl);
// if (picUrl) {
// this.loadHotZonePic(pic, picUrl, saveData);
// }
// }
console.log('item.x: ', item.x);
point.setScaleXY(this.mapScale);
console.log('point.scaleX: ', point.scaleX)
point.x = item.x;
point.y = item.y;
this.renderArr.push(point);
}
setItemLabel(item, saveData) {
const textLabel = new HotZoneLabel(this.ctx); const textLabel = new HotZoneLabel(this.ctx);
if (this.hotZoneFontObj) {
textLabel.fontSize = this.hotZoneFontObj.size; textLabel.fontSize = this.hotZoneFontObj.size;
textLabel.fontName = this.hotZoneFontObj.name; textLabel.fontName = this.hotZoneFontObj.name;
textLabel.fontColor = this.hotZoneFontObj.color; textLabel.fontColor = this.hotZoneFontObj.color;
}
textLabel.textAlign = 'center'; textLabel.textAlign = 'center';
// textLabel.setOutline(); // textLabel.setOutline();
// console.log('saveData:', saveData);
item['textLabel'] = textLabel; item['textLabel'] = textLabel;
textLabel.setScaleXY(this.mapScale); textLabel.setScaleXY(this.mapScale);
if (saveData && saveData.text) { if (saveData) {
textLabel.text = saveData.text;
if (saveData.text && this.hotZoneFontObj) {
textLabel.text = saveData.text
}
this.setActionFont(textLabel, saveData['actionData_' + item.gIdx]);
textLabel.refreshSize(); textLabel.refreshSize();
} }
textLabel.x = item.x; textLabel.x = item.x;
textLabel.y = item.y; textLabel.y = item.y;
this.renderArr.push(textLabel); this.renderArr.push(textLabel);
}
return item; setActionFont(textLabel, actionData) {
if (actionData && actionData.type == 'text') {
textLabel.text = actionData.text;
for (let i=0; i<actionData.changeOption.length; i++) {
const op = actionData.changeOption[i];
textLabel[op[0]] = op[1];
}
}
} }
getDefaultItemType() {
if (this.customTypeGroupArr) {
const group = this.customTypeGroupArr[0];
if (group.rect) {
return 'rect';
}
if (group.pic) {
return 'pic';
}
if (group.text) {
return 'text';
}
if (group.point) {
return 'point';
}
} else {
return this.defaultItemType;
}
}
getPicItem(img, saveData = null) { getPicItem(img, saveData = null) {
...@@ -327,9 +529,11 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -327,9 +529,11 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
item.y = saveRect.y + saveRect.height / 2; item.y = saveRect.y + saveRect.height / 2;
} else { } else {
item.showLineDash(); // item.showLineDash();
} }
item.showLineDash();
console.log('aaa');
}); });
return item; return item;
} }
...@@ -337,6 +541,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -337,6 +541,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
onAudioUploadSuccessByImg(e, img) { onAudioUploadSuccessByImg(e, img) {
img.audio_url = e.url; img.audio_url = e.url;
this.refresh();
} }
deleteItem(e, i) { deleteItem(e, i) {
...@@ -345,15 +550,118 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -345,15 +550,118 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
this.hotZoneArr.splice(i, 1); this.hotZoneArr.splice(i, 1);
this.refreshHotZoneId(); this.refreshHotZoneId();
this.refresh();
} }
radioChange(e, item) {
item.itemType = e;
this.refreshItem(item); // radioChange(e, item) {
// item.itemType = e;
// this.refreshItem(item);
// this.refresh();
// // console.log(' in radioChange e: ', e);
// }
customRadioChange(e, item) {
console.log('in customRadioChange', e);
item.gIdx = -1;
setTimeout(() => {
item.gIdx = e;
this.refreshCustomItem(item);
this.refresh();
}, 1);
// const curGroup = this.customTypeGroupArr[e];
}
refreshCustomItem(item) {
this.hideHotZoneItem(item);
const group = this.customTypeGroupArr[item.gIdx];
if (!group) {
return;
}
if (group.text) {
this.showItemLabel(item);
}
if (group.rect) {
this.showItemRect(item);
}
if (group.pic && !group.anima) {
this.showItemPic(item);
}
if (group.point) {
this.showItemPoint(item);
}
if (group.action) {
if (group.action.type == 'pic') {
this.showItemPic(item);
}
if (group.action.type == 'text') {
this.showItemLabel(item);
}
if (group.action.type == 'anima') {
this.showItemRect(item);
}
}
item.setAnimaStyle(group.animaSmall)
}
setItemIsAnimaStyle(item, isAnimal) {
}
showItemPic(item) {
item.pic.visible = true;
item.itemType = 'pic';
this.showArrowTop(item, item.data.isShowArrowAll)
}
showItemLabel(item) {
item.textLabel.visible = true;
item.itemType = 'text';
this.showArrowTop(item, item.data.isShowArrowAll)
}
showItemRect(item) {
item.visible = true;
item.itemType = 'rect';
const isShowArrowAll = item.data.isShowArrowAll == false ? false : true;
this.showArrowTop(item, isShowArrowAll)
}
showItemPoint(item) {
item.point.visible = true;
item.itemType = 'point';
this.showArrowTop(item, false)
}
// console.log(' in radioChange e: ', e); showArrowTop(item, isShowArrowTop = false) {
if (isShowArrowTop) {
item.arrowTop.visible = true;
item.arrowRight.visible = true;
} else {
item.arrowTop.visible = false;
item.arrowRight.visible = false;
}
}
hideHotZoneItem(item) {
item.visible = false;
item.pic.visible = false;
item.textLabel.visible = false;
} }
refreshItem(item) { refreshItem(item) {
...@@ -367,14 +675,18 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -367,14 +675,18 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
case 'text': case 'text':
this.setTextState(item); this.setTextState(item);
break; break;
case 'point':
this.setPointState(item);
break;
default: default:
this.setNoneState(item);
} }
} }
init() { init() {
console.log('init');
this.initData(); this.initData();
this.initCtx(); this.initCtx();
...@@ -382,18 +694,15 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -382,18 +694,15 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
} }
initItem() { initItem() {
this.changeDetectorRef.markForCheck();
this.changeDetectorRef.detectChanges();
if (!this.bgItem) { if (!this.bgItem) {
this.bgItem = {}; this.bgItem = {};
} else { } else {
this.refreshBackground(() => { this.refreshBackground(() => {
// if (!this.imgItemArr) {
// this.imgItemArr = [];
// } else {
// this.initImgArr();
// }
// console.log('aaaaa');
if (!this.hotZoneItemArr) { if (!this.hotZoneItemArr) {
this.hotZoneItemArr = []; this.hotZoneItemArr = [];
...@@ -404,6 +713,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -404,6 +713,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
}); });
} }
this.refresh();
} }
initHotZoneArr() { initHotZoneArr() {
...@@ -427,6 +737,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -427,6 +737,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
this.hotZoneArr = []; this.hotZoneArr = [];
const arr = this.hotZoneItemArr.concat(); const arr = this.hotZoneItemArr.concat();
console.log('this.hotZoneItemArr: ', this.hotZoneItemArr);
for (let i = 0; i < arr.length; i++) { for (let i = 0; i < arr.length; i++) {
const data = JSON.parse(JSON.stringify(arr[i])); const data = JSON.parse(JSON.stringify(arr[i]));
...@@ -449,9 +760,15 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -449,9 +760,15 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
item.pic_url = data.pic_url; item.pic_url = data.pic_url;
item.text = data.text; item.text = data.text;
item.itemType = data.itemType; item.itemType = data.itemType;
if (this.customTypeGroupArr) {
this.refreshCustomItem(item);
} else {
this.refreshItem(item); this.refreshItem(item);
}
console.log('item: ', item); console.log('1 item: ', item);
this.hotZoneArr.push(item); this.hotZoneArr.push(item);
} }
...@@ -463,48 +780,6 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -463,48 +780,6 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
} }
initImgArr() {
console.log('this.imgItemArr: ', this.imgItemArr);
let curBgRect;
if (this.bg) {
curBgRect = this.bg.getBoundingBox();
} else {
curBgRect = {x: 0, y: 0, width: this.canvasWidth, height: this.canvasHeight};
}
let oldBgRect = this.bgItem.rect;
if (!oldBgRect) {
oldBgRect = curBgRect;
}
const rate = curBgRect.width / oldBgRect.width;
console.log('rate: ', rate);
this.imgArr = [];
const arr = this.imgItemArr.concat();
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;
data.rect.y *= rate;
data.rect.width *= rate;
data.rect.height *= rate;
data.rect.x += curBgRect.x;
data.rect.y += curBgRect.y;
img['picItem'] = this.getPicItem(img, data);
img['audio_url'] = arr[i].audio_url;
this.imgArr.push(img);
}
this.refreshImageId();
}
initData() { initData() {
this.canvasWidth = this.wrap.nativeElement.clientWidth; this.canvasWidth = this.wrap.nativeElement.clientWidth;
...@@ -528,9 +803,10 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -528,9 +803,10 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
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++) { for (let i = this.hotZoneArr.length - 1; i >= 0; i--) {
const item = this.hotZoneArr[i]; const item = this.hotZoneArr[i];
console.log('mapDown item: ', item);
let callback; let callback;
let target; let target;
switch (item.itemType) { switch (item.itemType) {
...@@ -546,9 +822,13 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -546,9 +822,13 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
target = item.textLabel; target = item.textLabel;
callback = this.clickedHotZoneText.bind(this); callback = this.clickedHotZoneText.bind(this);
break; break;
case 'point':
target = item.point;
callback = this.clickedHotZonePoint.bind(this);
break;
} }
if (this.checkClickTarget(target)) { if (target && this.checkClickTarget(target)) {
callback(target); callback(target);
return; return;
} }
...@@ -582,7 +862,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -582,7 +862,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
this.oldPos = {x: this.mx, y: this.my}; this.oldPos = {x: this.mx, y: this.my};
this.saveDisabled = true; // this.saveDisabled = false;
} }
...@@ -723,7 +1003,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -723,7 +1003,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
// } // }
this.updateArr(this.hotZoneArr); this.updateArr(this.hotZoneArr);
this.updatePos() this.updatePos();
TWEEN.update(); TWEEN.update();
...@@ -833,7 +1113,9 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -833,7 +1113,9 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
checkClickTarget(target) { checkClickTarget(target) {
if (!target || !target.visible) {
return;
}
const rect = target.getBoundingBox(); const rect = target.getBoundingBox();
if (this.checkPointInRect(this.mx, this.my, rect)) { if (this.checkPointInRect(this.mx, this.my, rect)) {
return true; return true;
...@@ -852,9 +1134,21 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -852,9 +1134,21 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
saveClick() { saveClick() {
const sendData = this.getSendData();
this.save.emit(sendData);
}
getSendData() {
const bgItem = this.bgItem; const bgItem = this.bgItem;
if (this.bg) { if (this.bg) {
bgItem['rect'] = this.bg.getBoundingBox(); const rect = this.bg.getBoundingBox();
bgItem['rect'] = rect;
rect.x = Math.round(rect.x * 100) / 100;
rect.y = Math.round(rect.y * 100) / 100;
rect.width = Math.round(rect.width * 100) / 100;
rect.height = Math.round(rect.height * 100) / 100;
} else { } else {
bgItem['rect'] = { bgItem['rect'] = {
x: 0, x: 0,
...@@ -870,19 +1164,43 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -870,19 +1164,43 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
for (let i = 0; i < hotZoneArr.length; i++) { for (let i = 0; i < hotZoneArr.length; i++) {
const hotZoneItem = { const hotZoneItem = {
id: hotZoneArr[i].id,
index: hotZoneArr[i].index, index: hotZoneArr[i].index,
pic_url: hotZoneArr[i].pic_url, pic_url: hotZoneArr[i].pic_url,
text: hotZoneArr[i].text, text: hotZoneArr[i].text,
audio_url: hotZoneArr[i].audio_url, audio_url: hotZoneArr[i].audio_url,
itemType: hotZoneArr[i].itemType, itemType: hotZoneArr[i].itemType,
fontSize: this.hotZoneFontObj.size,
fontName: this.hotZoneFontObj.name,
fontColor: this.hotZoneFontObj.color,
fontScale: hotZoneArr[i].textLabel ? hotZoneArr[i].textLabel.scaleX : 1, fontScale: hotZoneArr[i].textLabel ? hotZoneArr[i].textLabel.scaleX : 1,
imgScale: hotZoneArr[i].pic ? hotZoneArr[i].pic.scaleX : 1, imgScale: hotZoneArr[i].pic ? hotZoneArr[i].pic.scaleX : 1,
mapScale: this.mapScale mapScale: this.mapScale,
skeJsonData: hotZoneArr[i].skeJsonData,
texJsonData: hotZoneArr[i].texJsonData,
texPngData: hotZoneArr[i].texPngData,
gIdx: hotZoneArr[i].gIdx
}; };
hotZoneItem['actionData_' + hotZoneItem.gIdx] = hotZoneArr[i]['actionData_' + hotZoneArr[i].gIdx]
if (this.hotZoneFontObj) {
hotZoneItem['fontSize'] = this.hotZoneFontObj.size;
hotZoneItem['fontName'] = this.hotZoneFontObj.name;
hotZoneItem['ontColor'] = this.hotZoneFontObj.color;
}
if (hotZoneArr[i].itemType == 'pic') {
hotZoneItem['rect'] = hotZoneArr[i].pic.getBoundingBox();
} else if (hotZoneArr[i].itemType == 'text') {
hotZoneArr[i].textLabel.refreshSize();
hotZoneItem['rect'] = hotZoneArr[i].textLabel.getLabelRect();
// hotZoneItem['rect'].width = hotZoneItem['rect'].width / hotZoneArr[i].textLabel.scaleX;
// hotZoneItem['rect'].height = hotZoneArr[i].textLabel.height * hotZoneArr[i].textLabel.scaleY;
} else {
hotZoneItem['rect'] = hotZoneArr[i].getBoundingBox(); hotZoneItem['rect'] = hotZoneArr[i].getBoundingBox();
}
// hotZoneItem['rect'] = hotZoneArr[i].getBoundingBox();
hotZoneItem['rect'].x = Math.round((hotZoneItem['rect'].x - bgItem['rect'].x) * 100) / 100; hotZoneItem['rect'].x = Math.round((hotZoneItem['rect'].x - bgItem['rect'].x) * 100) / 100;
hotZoneItem['rect'].y = Math.round((hotZoneItem['rect'].y - bgItem['rect'].y) * 100) / 100; hotZoneItem['rect'].y = Math.round((hotZoneItem['rect'].y - bgItem['rect'].y) * 100) / 100;
hotZoneItem['rect'].width = Math.round((hotZoneItem['rect'].width) * 100) / 100; hotZoneItem['rect'].width = Math.round((hotZoneItem['rect'].width) * 100) / 100;
...@@ -894,7 +1212,275 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -894,7 +1212,275 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
console.log('hotZoneItemArr: ', hotZoneItemArr); console.log('hotZoneItemArr: ', hotZoneItemArr);
this.save.emit({bgItem, hotZoneItemArr}); return {bgItem, hotZoneItemArr};
}
saveText(item) {
if (item.itemType == 'text') {
item.textLabel.text = item.text;
}
}
onSaveCustomAction(e, item) {
const data = e;
item['actionData_' + item.gIdx] = data;
if (data.type == 'pic') {
let picUrl = data.pic_url;
if (picUrl) {
this.loadHotZonePic(item.pic, picUrl);
}
}
if (data.type == 'text') {
this.setActionFont(item.textLabel, data);
item.textLabel.refreshSize();
}
// if (data.type == 'anima') {
// this.setActionAnima(item.anima, data);
// }
// this.loadHotZonePic(item.pic, e.url);
this.refresh()
}
setActionAnima() {
}
setAnimaBtnClick(index) {
console.log('aaaa')
this.isAnimaSmall = false;
this.setCurDragonBone(index);
// this.curDragonBoneIndex = index;
// this.curDragonBoneGIdx = Number(this.hotZoneArr[index].gIdx);
// const {skeJsonData, texJsonData, texPngData} = this.hotZoneArr[index];
// this.skeJsonData = skeJsonData || {};
// this.texJsonData = texJsonData || {};
// this.texPngData = texPngData || {};
// this.animaPanelVisible = true;
// this.refresh();
}
setAnimaSmallBtnClick(index) {
console.log('bbb')
this.isAnimaSmall = true;
this.setCurDragonBone(index);
}
setCurDragonBone(index) {
this.curDragonBoneIndex = index;
this.curDragonBoneGIdx = Number(this.hotZoneArr[index].gIdx);
const {skeJsonData, texJsonData, texPngData} = this.hotZoneArr[index];
this.skeJsonData = skeJsonData || {};
this.texJsonData = texJsonData || {};
this.texPngData = texPngData || {};
this.animaPanelVisible = true;
this.refresh();
}
setItemSizeByAnima(jsonData, item) {
console.log('json: ', jsonData);
const request = new XMLHttpRequest();
//通过url获取文件,第二个选项是文件所在的具体地址
request.open('GET', jsonData.url, true);
request.send(null);
request.onreadystatechange = ()=> {
if (request.readyState === 4 && request.status === 200) {
var type = request.getResponseHeader('Content-Type');
if (type.indexOf("text") !== 1) {
//返回一个文件内容的对象
const data = JSON.parse(request.responseText);
console.log('request.responseText;', data)
const animaSize = data.armature[0].canvas;
item.width = animaSize.width;
item.height = animaSize.height;
// return request.responseText;
}
}
}
}
animaPanelCancel() {
this.animaPanelVisible = false;
this.refresh();
}
animaPanelOk() {
this.setItemDragonBoneData(this.hotZoneArr[this.curDragonBoneIndex]);
console.log('this.hotZoneArr: ', this.hotZoneArr);
this.animaPanelVisible = false;
if (this.isAnimaSmall) {
this.setItemSizeByAnima(this.skeJsonData, this.hotZoneArr[this.curDragonBoneIndex]);
}
this.refresh();
}
setItemDragonBoneData(item) {
item['skeJsonData'] = this.skeJsonData;
item['texJsonData'] = this.texJsonData;
item['texPngData'] = this.texPngData;
}
skeJsonHandleChange(e) {
console.log('e: ', e);
switch (e.type) {
case 'start':
this.isSkeJsonLoading = true;
break;
case 'success':
this.skeJsonData['url'] = e.file.response.url;
this.skeJsonData['name'] = e.file.name;
this.nzMessageService.success('上传成功');
this.isSkeJsonLoading = false;
break;
case 'progress':
break;
}
}
texJsonHandleChange(e) {
console.log('e: ', e);
switch (e.type) {
case 'start':
this.isTexJsonLoading = true;
break;
case 'success':
this.texJsonData['url'] = e.file.response.url;
this.texJsonData['name'] = e.file.name;
this.nzMessageService.success('上传成功');
this.isTexJsonLoading = false;
break;
case 'progress':
break;
}
}
texPngHandleChange(e) {
console.log('e: ', e);
switch (e.type) {
case 'start':
this.isTexPngLoading = true;
break;
case 'success':
this.texPngData['url'] = e.file.response.url;
this.texPngData['name'] = e.file.name;
this.nzMessageService.success('上传成功');
this.isTexPngLoading = false;
break;
case 'progress':
break;
}
}
copyHotZoneData() {
const {bgItem, hotZoneItemArr} = this.getSendData();
// const hotZoneItemArrNew = [];
// const tmpArr = JSON.parse(JSON.stringify(hotZoneItemArr));
// tmpArr.forEach((item) => {
// if (item.gIdx === '0') {
// hotZoneItemArr.push(item);
// }
// })
const jsonData = {
bgItem,
hotZoneItemArr,
isHasRect: this.isHasRect,
isHasPic: this.isHasPic,
isHasText: this.isHasText,
isHasAudio: this.isHasAudio,
isHasAnima: this.isHasAnima,
hotZoneFontObj: this.hotZoneFontObj,
defaultItemType: this.defaultItemType,
hotZoneImgSize: this.hotZoneImgSize,
};
const oInput = document.createElement('input');
oInput.value = JSON.stringify(jsonData);
document.body.appendChild(oInput);
oInput.select(); // 选择对象
document.execCommand('Copy'); // 执行浏览器复制命令
document.body.removeChild(oInput);
this.nzMessageService.success('复制成功');
// alert('复制成功');
}
importData() {
if (!this.pasteData) {
return;
}
try {
const data = JSON.parse(this.pasteData);
console.log('data:', data);
const {
bgItem,
hotZoneItemArr,
isHasRect,
isHasPic,
isHasText,
isHasAudio,
isHasAnima,
hotZoneFontObj,
defaultItemType,
hotZoneImgSize,
} = data;
this.hotZoneItemArr = hotZoneItemArr;
this.isHasRect = isHasRect;
this.isHasPic = isHasPic;
this.isHasText = isHasText;
this.isHasAudio = isHasAudio;
this.isHasAnima = isHasAnima;
this.hotZoneFontObj = hotZoneFontObj;
this.defaultItemType = defaultItemType;
this.hotZoneImgSize = hotZoneImgSize;
this.bgItem = bgItem;
this.pasteData = '';
} catch (e) {
console.log('err: ', e);
this.nzMessageService.error('导入失败');
}
} }
private updatePos() { private updatePos() {
...@@ -915,33 +1501,59 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -915,33 +1501,59 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
x = item.textLabel.x; x = item.textLabel.x;
y = item.textLabel.y; y = item.textLabel.y;
break; break;
case 'point':
x = item.point.x;
y = item.point.y;
break;
} }
if (x != undefined && y != undefined) {
item.x = x; item.x = x;
item.y = y; item.y = y;
item.pic.x = x; item.pic.x = x;
item.pic.y = y; item.pic.y = y;
item.textLabel.x = x; item.textLabel.x = x;
item.textLabel.y = y; item.textLabel.y = y;
}
}); });
} }
private setPicState(item: any) { private setPicState(item: any) {
item.visible = false; item.visible = false;
item.textLabel.visible = false;
item.pic.visible = true; item.pic.visible = true;
item.textLabel.visible = false;
item.point.visible = false;
} }
private setRectState(item: any) { private setRectState(item: any) {
item.visible = true; item.visible = true;
item.textLabel.visible = false;
item.pic.visible = false; item.pic.visible = false;
item.textLabel.visible = false;
item.point.visible = false;
} }
private setTextState(item: any) { private setTextState(item: any) {
item.visible = false; item.visible = false;
item.pic.visible = false; item.pic.visible = false;
item.textLabel.visible = true; item.textLabel.visible = true;
item.point.visible = false;
}
private setNoneState(item: any) {
item.visible = false;
item.pic.visible = false;
item.textLabel.visible = false;
item.point.visible = false;
}
private setPointState(item) {
item.visible = false;
item.pic.visible = false;
item.textLabel.visible = false;
item.point.visible = true;
} }
private clickedHotZoneRect(item: any) { private clickedHotZoneRect(item: any) {
...@@ -962,6 +1574,17 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -962,6 +1574,17 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
private clickedHotZonePic(item: any) { private clickedHotZonePic(item: any) {
if (this.checkClickTarget(item)) { if (this.checkClickTarget(item)) {
if (item.lineDashFlag && this.checkClickTarget(item.arrow)) {
this.changeItemSize(item);
} else if (item.lineDashFlag && this.checkClickTarget(item.arrowTop)) {
this.changeItemTopSize(item);
} else if (item.lineDashFlag && this.checkClickTarget(item.arrowRight)) {
this.changeItemRightSize(item);
} else {
this.changeCurItem(item);
}
this.curItem = item; this.curItem = item;
} }
} }
...@@ -972,15 +1595,51 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -972,15 +1595,51 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
} }
} }
saveText(item) { private clickedHotZonePoint(item) {
item.textLabel.text = item.text; if (this.checkClickTarget(item)) {
this.curItem = item;
}
}
private loadHotZonePic(pic: HotZoneImg, url, saveData = null) {
let baseLen;
if (this.hotZoneImgSize) {
baseLen = this.hotZoneImgSize * this.mapScale;
} }
private loadHotZonePic(pic: HotZoneImg, url) { console.log('saveData: ', saveData);
const baseLen = this.hotZoneImgSize * this.mapScale;
pic.load(url).then(() => { pic.load(url).then(() => {
const s = getMinScale(pic, baseLen);
pic.setScaleXY(s); if (!saveData) {
let scale = this.bg.scaleX;
if (baseLen) {
scale = getMinScale(pic, baseLen);
}
pic.setScaleXY(scale);
} else {
const targetW = saveData.rect.width /// saveData.imgScale;
const targetH = saveData.rect.height /// saveData.imgScale;
pic.scaleX = targetW / pic.width;
pic.scaleY = targetH / pic.height;
}
}); });
} }
closeAfterPanel() {
this.refresh();
}
/**
* 刷新 渲染页面
*/
refresh() {
setTimeout(() => {
this.appRef.tick();
}, 1);
}
} }
<div class="position-relative">
<button nz-button (click)="setAnimaBtnClick()" style=" border-radius: 0.5rem; border: 1px solid #ddd;">
<i nz-icon nzType="tool" nzTheme="outline"></i>
{{btnName}}
</button>
<!--配置龙骨面板-->
<nz-modal [(nzVisible)]="animaPanelVisible" (nzAfterClose)="closePanel()" nzTitle="配置资源文件"
(nzOnCancel)="animaPanelCancel()" (nzOnOk)="animaPanelOk()" nzOkText="保存">
<div class="anima-upload-btn">
<span style="margin-right: 10px">上传 ske_json 文件: </span>
<nz-upload [nzShowUploadList]="false" nzAccept="application/json" [nzAction]="uploadUrl" [nzData]="uploadData"
(nzChange)="skeJsonHandleChange($event)">
<button nz-button><i nz-icon nzType="upload"></i><span>Upload</span></button>
</nz-upload>
<i *ngIf="isSkeJsonLoading" style="margin-left: 10px;" nz-icon [nzType]="'loading'"></i>
<span *ngIf="skeJsonData && skeJsonData['name']" style="margin-left: 10px"><u> {{skeJsonData['name']}} </u></span>
</div>
<div class="anima-upload-btn">
<span style="margin-right: 10px">上传 tex_json 文件: </span>
<nz-upload [nzShowUploadList]="false" nzAccept="application/json" [nzAction]="uploadUrl" [nzData]="uploadData"
(nzChange)="texJsonHandleChange($event)">
<button nz-button><i nz-icon nzType="upload"></i><span>Upload</span></button>
</nz-upload>
<i *ngIf="isTexJsonLoading" style="margin-left: 10px;" nz-icon [nzType]="'loading'"></i>
<span *ngIf="texJsonData && texJsonData['name']" style="margin-left: 10px"><u> {{texJsonData['name']}} </u></span>
</div>
<div class="anima-upload-btn">
<span style="margin-right: 10px">上传 tex_png 文件: </span>
<nz-upload [nzShowUploadList]="false" nzAccept="image/*" [nzAction]="uploadUrl" [nzData]="uploadData"
(nzChange)="texPngHandleChange($event)">
<button nz-button><i nz-icon nzType="upload"></i><span>Upload</span></button>
</nz-upload>
<i *ngIf="isTexPngLoading" style="margin-left: 10px;" nz-icon [nzType]="'loading'"></i>
<span *ngIf="texPngData && texPngData['name']" style="margin-left: 10px"><u> {{texPngData['name']}} </u></span>
</div>
<div class="anima-upload-btn" *ngIf="animaNames && animaNames.length > 0">
提示:需包含动画: {{animaNames.toString()}}.
</div>
</nz-modal>
</div>
\ No newline at end of file
@import '../../style/common_mixin.css';
.p-image-uploader {
position: relative;
display: block;
width: 100%;
height: 0;
padding-bottom: 56.25%;
.p-box {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
border: 2px dashed #ddd;
border-radius: 0.5rem;
background-color: #fafafa;
text-align: center;
color: #aaa;
.p-upload-icon {
text-align: center;
margin: auto;
.anticon-upload {
color: #888;
font-size: 5rem;
}
.p-progress-bar {
position: relative;
width: 20rem;
height: 1.5rem;
border: 1px solid #ccc;
border-radius: 1rem;
.p-progress-bg {
background-color: #1890ff;
border-radius: 1rem;
height: 100%;
}
.p-progress-value {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
text-shadow: 0 0 4px #000;
color: white;
text-align: center;
font-size: 0.9rem;
line-height: 1.5rem;
}
}
}
.p-preview {
width: 100%;
height: 100%;
background-size: contain;
background-repeat: no-repeat;
background-position: 50% 50%;
//background-image: url("https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png");
}
}
.d-flex{
display: flex;
}
}
.p-btn-delete {
position: absolute;
right: -0.5rem;
top: -0.5rem;
width: 2rem;
height: 2rem;
border: 0.2rem solid white;
border-radius: 50%;
font-size: 1.2rem;
background-color: #fb781a;
color: white;
text-align: center;
}
.p-upload-progress-bg {
position: absolute;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
& .i-text {
position: absolute;
text-align: center;
color: white;
text-shadow: 0 0 2px rgba(0, 0, 0, .85);
}
& .i-bg {
position: absolute;
left: 0;
top: 0;
height: 100%;
background-color: #27b43f;
border-radius: 0.5rem;
}
}
.anima-upload-btn {
padding: 10px;
}
:host ::ng-deep .ant-upload {
display: block;
}
import {ApplicationRef, Component, EventEmitter, Input, OnChanges, OnDestroy, Output} from '@angular/core';
import { NzMessageService, UploadXHRArgs, UploadFile } from 'ng-zorro-antd';
@Component({
selector: 'app-upload-dragon-bone',
templateUrl: './upload-dragon-bone.component.html',
styleUrls: ['./upload-dragon-bone.component.scss']
})
export class UploadDragonBoneComponent implements OnDestroy, OnChanges {
uploading = false;
progress = 0;
@Input()
btnName = '配置龙骨动画';
@Input()
animaNames = [];
@Input()
skeJsonData = {};
@Input()
texJsonData = {};
@Input()
texPngData = {};
@Output()
save = new EventEmitter();
@Output()
refreshEmitter = new EventEmitter();
// @Input()
// picUrl;
// @Input()
// canDelete = false;
// @Output()
// imageUploaded = new EventEmitter();
// @Output()
// imageUploadFailure = new EventEmitter();
// @Output()
// delete = new EventEmitter();
// @Input()
// picItem = null;
// @Input()
// iconSize = 2;
// @Input()
// TIP = 'Click here to upload image';
// @Input()
// disableUpload = false;
uploadUrl;
uploadData;
animaPanelVisible = false;
isSkeJsonLoading = false;
isTexJsonLoading = false;
isTexPngLoading = false;
constructor(private appRef: ApplicationRef, private nzMessageService: NzMessageService) {
this.uploadUrl = (<any> window).courseware.uploadUrl();
this.uploadData = (<any> window).courseware.uploadData();
window['air'].getUploadCallback = (url, data) => {
this.uploadUrl = url;
this.uploadData = data;
};
}
ngOnChanges() {
}
setAnimaBtnClick() {
this.animaPanelVisible = true;
this.refresh();
}
animaPanelCancel() {
this.animaPanelVisible = false;
this.refresh();
}
animaPanelOk() {
this.sendItemDragonBoneData();
this.animaPanelVisible = false;
this.refresh();
}
sendItemDragonBoneData() {
const data = {};
data['skeJsonData'] = this.skeJsonData;
data['texJsonData'] = this.texJsonData;
data['texPngData'] = this.texPngData;
this.save.emit(data);
}
skeJsonHandleChange(e) {
console.log('e: ', e);
switch (e.type) {
case 'start':
this.isSkeJsonLoading = true;
break;
case 'success':
this.skeJsonData['url'] = e.file.response.url;
this.skeJsonData['name'] = e.file.name;
this.nzMessageService.success('上传成功');
this.isSkeJsonLoading = false;
break;
case 'progress':
break;
}
}
texJsonHandleChange(e) {
console.log('e: ', e);
switch (e.type) {
case 'start':
this.isTexJsonLoading = true;
break;
case 'success':
this.texJsonData['url'] = e.file.response.url;
this.texJsonData['name'] = e.file.name;
this.nzMessageService.success('上传成功');
this.isTexJsonLoading = false;
break;
case 'progress':
break;
}
}
texPngHandleChange(e) {
console.log('e: ', e);
switch (e.type) {
case 'start':
this.isTexPngLoading = true;
break;
case 'success':
this.texPngData['url'] = e.file.response.url;
this.texPngData['name'] = e.file.name;
this.nzMessageService.success('上传成功');
this.isTexPngLoading = false;
break;
case 'progress':
break;
}
}
/**
* 刷新 渲染页面
*/
refresh() {
// this.refreshEmitter.emit();
setTimeout(() => {
this.appRef.tick();
}, 1);
}
closePanel() {
console.log(' in closePanel ');
this.refresh();
}
ngOnDestroy() {
}
}
...@@ -42,7 +42,24 @@ export class UploadImageWithPreviewComponent implements OnDestroy, OnChanges { ...@@ -42,7 +42,24 @@ export class UploadImageWithPreviewComponent implements OnDestroy, OnChanges {
this.uploadData = data; this.uploadData = data;
}; };
this.setUploadUrl();
} }
setUploadUrl() {
if (!this.uploadUrl) {
this.uploadUrl = (<any> window).courseware.uploadUrl();
this.uploadData = (<any> window).courseware.uploadData();
setTimeout(() => {
this.setUploadUrl();
}, 500);
}
}
ngOnChanges() { ngOnChanges() {
if (!this.picItem) { if (!this.picItem) {
return; return;
......
...@@ -6,3 +6,30 @@ ...@@ -6,3 +6,30 @@
height: 100%; height: 100%;
} }
.radioPaire {
float: left;
margin: 3px;
border-style: dashed;
border-color: #000;
border-width: 1px;
}
.border {
border-radius: 20px;
border-style: dashed;
padding: 20px;
margin: 20px;
/*width: 500px; */
/*//border-radius: 20px;*/
/*//border-width: 2px;*/
/*//border-color: #000000;*/
}
.border-lite {
border: 2px dashed #ddd;
border-radius: 0.5rem;
padding: 10px;
margin: 10px;
}
<div class="model-content"> <div class="model-content">
<div style="position: absolute; left: 200px; top: 100px; width: 800px;"> <div style="padding: 10px;">
<input type="text" nz-input [(ngModel)]="item.text" (blur)="save()"> <div style="width: 100%; margin-top: 15px; margin-bottom: 50px;" align="center">
<h2>气泡文本</h2>
<div style="width: 80%; display: flex; justify-content: center; align-items: center;">
<input type="text" nz-input [(ngModel)]="item.title" (blur)="save()" style="margin-top: 5px">
<!-- <app-audio-recorder
style="margin-top: 5px; margin-left: 5px;"
[audioUrl]="item.title_audio_url"
(audioUploaded)="onAudioUploadSuccess($event, 'title_audio_url')"
></app-audio-recorder> -->
</div>
</div>
<app-custom-hot-zone
[bgItem]="item.bgItem"
[hotZoneItemArr]="item.hotZoneItemArr"
[customTypeGroupArr]="customTypeGroupArr"
(save)="saveHotZone(item, $event)"
>
</app-custom-hot-zone>
<!-- <div style="width: 300px;" align='center'>
<span>图1: </span>
<app-upload-image-with-preview <app-upload-image-with-preview
[picUrl]="item.pic_url" [picUrl]="item.pic_url"
(imageUploaded)="onImageUploadSuccess($event, 'pic_url')" (imageUploaded)="onImageUploadSuccess($event, 'pic_url')">
></app-upload-image-with-preview> </app-upload-image-with-preview>
</div>
<div style="width: 300px; margin-top: 5px;" align='center'>
<span>图2: </span>
<app-upload-image-with-preview
[picUrl]="item.pic_url_2"
(imageUploaded)="onImageUploadSuccess($event, 'pic_url_2')">
</app-upload-image-with-preview>
</div>
<div style="width: 300px; margin-top: 15px;">
<span>文本: </span>
<input type="text" nz-input [(ngModel)]="item.text" (blur)="save()">
</div>
<div style="margin-top: 5px">
<span>音频: </span>
<app-audio-recorder <app-audio-recorder
[audioUrl]="item.audio_url" [audioUrl]="item.audio_url"
(audioUploaded)="onAudioUploadSuccess($event, 'audio_url')" (audioUploaded)="onAudioUploadSuccess($event, 'audio_url')"
></app-audio-recorder> ></app-audio-recorder>
<app-custom-hot-zone></app-custom-hot-zone> </div> -->
<app-upload-video></app-upload-video>
<app-lesson-title-config></app-lesson-title-config>
</div>
</div>
</div> </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';
import { JsonPipe } from '@angular/common';
@Component({ @Component({
...@@ -10,22 +10,96 @@ import {Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, Ap ...@@ -10,22 +10,96 @@ import {Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, Ap
export class FormComponent implements OnInit, OnChanges, OnDestroy { export class FormComponent implements OnInit, OnChanges, OnDestroy {
// 储存数据用 // 储存数据用
saveKey = "test_0011"; saveKey = "pu_16";
// 储存对象 // 储存对象
item; item;
customTypeGroupArr = [
{
name: '遮照图片',
pic: true,
isShowArrowAll: true,
// rect: true,
// animaSmall: true,
// audio: true,
},
{
name: 'Open按钮',
point: true,
// animaSmall: true,
// audio: true,
},
// {
// name: '发音图片',
// pic: true,
// audio: true,
// },
// {
// name: '发音区块',
// rect: true,
// audio: true,
// },
// {
// name: '变化文本',
// action: {
// type: 'text',
// option: [
// ['fontColor', '#000000'],
// ['fontSize', '100'],
// ['opacity', '0', '100']
// ]
// },
// },
// {
// name: '变化图片',
// action: {
// type: 'pic',
// option: [
// // ['scale', '1'],
// ['opacity', '0', '100']
// ]
// },
// },
// {
// name: '变化动画',
// action: {
// type: 'anima',
// option: [
// // ['scale', '1'],
// ['opacity', '0', '100']
// ]
// },
// },
]
constructor(private appRef: ApplicationRef, private changeDetectorRef: ChangeDetectorRef) {
constructor(private appRef: ApplicationRef,private changeDetectorRef: ChangeDetectorRef) { }
createShell() {
this.item.wordList.push({
word: '',
audio: '',
backWord: '',
backWordAudio: '',
});
this.save();
} }
removeShell(idx) {
this.item.wordList.splice(idx, 1);
this.save();
}
ngOnInit() { ngOnInit() {
this.item = {}; this.item = {};
// 获取存储的数据 // 获取存储的数据
(<any> window).courseware.getData((data) => { (<any>window).courseware.getData((data) => {
if (data) { if (data) {
this.item = data; this.item = data;
...@@ -37,20 +111,34 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -37,20 +111,34 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
this.refresh(); this.refresh();
}, this.saveKey); }, this.saveKey);
} }
ngOnChanges() { ngOnChanges() {
} }
ngOnDestroy() { ngOnDestroy() {
} }
init() {
}
init() { onSaveCustomAction(e) {
console.log('e:', e);
this.item.customAction = e;
this.save();
}
saveHotZone(group, e) {
console.log('e: ', e);
const {bgItem, hotZoneItemArr} = e;
group.bgItem = bgItem;
group.hotZoneItemArr = hotZoneItemArr;
this.save();
} }
...@@ -69,19 +157,28 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -69,19 +157,28 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
* @param e * @param e
*/ */
onAudioUploadSuccess(e, key) { onAudioUploadSuccess(e, key) {
this.item[key] = e.url; this.item[key] = e.url;
this.save(); this.save();
} }
onWordAudioUploadSuccess(e, idx) {
this.item.wordList[idx].audio = e.url;
this.save();
}
onBackWordAudioUploadSuccess(e, idx) {
this.item.wordList[idx].backWordAudio = e.url;
this.save();
}
/** /**
* 储存数据 * 储存数据
*/ */
save() { save() {
(<any> window).courseware.setData(this.item, null, this.saveKey); (<any>window).courseware.setData(this.item, null, this.saveKey);
this.refresh(); this.refresh();
console.log('this.item = ' + JSON.stringify(this.item));
} }
/** /**
...@@ -94,4 +191,3 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -94,4 +191,3 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
} }
} }
\ No newline at end of file
...@@ -77,7 +77,9 @@ export class MySprite extends Sprite { ...@@ -77,7 +77,9 @@ export class MySprite extends Sprite {
_offCtx; _offCtx;
isCircleStyle = false; // 切成圆形 isCircleStyle = false; // 切成圆形
parent; parent;
_maskSpr;
_maskSprArr = [];
_maskType = "destination-in" // destination-out
init(imgObj = null, anchorX: number = 0.5, anchorY: number = 0.5) { init(imgObj = null, anchorX: number = 0.5, anchorY: number = 0.5) {
...@@ -114,16 +116,20 @@ export class MySprite extends Sprite { ...@@ -114,16 +116,20 @@ export class MySprite extends Sprite {
this._radius = r; this._radius = r;
} }
setMaskSpr(spr) { addMaskSpr(spr) {
this._maskSpr = spr; this._maskSprArr.push(spr);
this._createOffCtx(); this._createOffCtx();
} }
setMaskType(t) {
this._maskType = t;
}
_createOffCtx() { _createOffCtx() {
if (!this._offCtx) { if (!this._offCtx) {
this._offCanvas = document.createElement('canvas'); // 创建一个新的canvas this._offCanvas = document.createElement('canvas'); // 创建一个新的canvas
this.width = this._offCanvas.width = this.width; // 创建一个正好包裹住一个粒子canvas this._offCanvas.width = this.width; // 创建一个正好包裹住一个粒子canvas
this.height = this._offCanvas.height = this.height; this._offCanvas.height = this.height;
this._offCtx = this._offCanvas.getContext('2d'); this._offCtx = this._offCanvas.getContext('2d');
} }
} }
...@@ -220,12 +226,22 @@ export class MySprite extends Sprite { ...@@ -220,12 +226,22 @@ export class MySprite extends Sprite {
this._offCtx.clearRect(0, 0, this.width, this.height); this._offCtx.clearRect(0, 0, this.width, this.height);
this._offCtx.drawImage(this.img, 0, 0); this._offCtx.drawImage(this.img, 0, 0);
if (this._maskSpr) { this._offCtx.globalCompositeOperation = this._maskType;
this._offCtx.globalCompositeOperation = 'destination-in';
this._offCtx.drawImage(this._maskSpr.img, this._maskSpr.x + this._maskSpr._offX - this._offX , this._maskSpr.y + this._maskSpr._offY - this._offY); if (this._maskSprArr && this._maskSprArr.length > 0) {
for (let i=0; i<this._maskSprArr.length; i++) {
this._maskSprArr[i].ctx = this._offCtx;
this._maskSprArr[i].update();
}
} }
this.ctx.drawImage(this._offCanvas, this._offX, this._offY); this.ctx.drawImage(this._offCanvas, this._offX, this._offY);
this._offCtx.restore(); this._offCtx.restore();
...@@ -822,8 +838,10 @@ export class RichTextOld extends Label { ...@@ -822,8 +838,10 @@ export class RichTextOld extends Label {
export class RichText extends Label { export class RichText extends Label {
disH = 30; disH = 10;
offW = 10; offW = 10;
row = 1;
textBaseline = "middle";
constructor(ctx?: any) { constructor(ctx?: any) {
super(ctx); super(ctx);
...@@ -831,7 +849,17 @@ export class RichText extends Label { ...@@ -831,7 +849,17 @@ export class RichText extends Label {
// this.dataArr = dataArr; // this.dataArr = dataArr;
} }
getLineNum() {
this.drawSelf();
return this.row;
}
getAreaHeight() {
this.drawSelf();
const tmpTextH = this.row * this.fontSize;
const tmpDisH = (this.row - 1) * this.disH
return tmpTextH + tmpDisH;
}
drawText() { drawText() {
...@@ -842,7 +870,7 @@ export class RichText extends Label { ...@@ -842,7 +870,7 @@ export class RichText extends Label {
this.ctx.font = `${this.fontSize}px ${this.fontName}`; this.ctx.font = `${this.fontSize}px ${this.fontName}`;
this.ctx.textAlign = this.textAlign; this.ctx.textAlign = this.textAlign;
this.ctx.textBaseline = 'middle'; this.ctx.textBaseline = this.textBaseline;
this.ctx.fontWeight = this.fontWeight; this.ctx.fontWeight = this.fontWeight;
this.ctx.fillStyle = this.fontColor; this.ctx.fillStyle = this.fontColor;
...@@ -869,8 +897,10 @@ export class RichText extends Label { ...@@ -869,8 +897,10 @@ export class RichText extends Label {
} }
row.push(temp); row.push(temp);
this.row = row.length;
const x = 0; const x = 0;
const y = -row.length * disH / 2; const y = 0//-row.length * disH / 2;
// for (let b = 0 ; b < row.length; b++) { // for (let b = 0 ; b < row.length; b++) {
// this.ctx.strokeText(row[b], x, y + ( b + 1 ) * disH ); // 每行字体y坐标间隔20 // this.ctx.strokeText(row[b], x, y + ( b + 1 ) * disH ); // 每行字体y坐标间隔20
// } // }
...@@ -954,11 +984,33 @@ export class ShapeRect extends MySprite { ...@@ -954,11 +984,33 @@ export class ShapeRect extends MySprite {
drawShape() { drawShape() {
if (this._offCtx) {
this._offCtx.save();
this._offCtx.clearRect(0, 0, this.width, this.height);
this._offCtx.fillStyle = this.fillColor;
this._offCtx.fillRect(this._offX, this._offY, this.width, this.height);
this._offCtx.globalCompositeOperation = this._maskType;
if (this._maskSprArr && this._maskSprArr.length > 0) {
for (let i=0; i<this._maskSprArr.length; i++) {
this._maskSprArr[i].ctx = this._offCtx;
this._maskSprArr[i].update();
}
}
this.ctx.drawImage(this._offCanvas, this._offX, this._offY);
this._offCtx.restore();
} else {
this.ctx.fillStyle = this.fillColor; this.ctx.fillStyle = this.fillColor;
this.ctx.fillRect(this._offX, this._offY, this.width, this.height); this.ctx.fillRect(this._offX, this._offY, this.width, this.height);
} }
}
drawSelf() { drawSelf() {
super.drawSelf(); super.drawSelf();
......
...@@ -14,6 +14,5 @@ ...@@ -14,6 +14,5 @@
@font-face @font-face
{ {
font-family: 'BRLNSDB'; font-family: 'BRLNSDB';
src: url("../../assets/font/BRLNSDB.TTF") ; src: url("../../assets/play/font/BRLNSDB_1.TTF")
} }
<span style="font-family:'BRLNSDB'" ></span>
<div class="game-container" #wrap> <div class="game-container" #wrap>
<canvas id="canvas" #canvas></canvas> <canvas id="canvas" #canvas></canvas>
</div> </div>
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, RichText,
} from './Unit'; } from './Unit';
import {res, resAudio} from './resources'; 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';
...@@ -21,23 +26,38 @@ import TWEEN from '@tweenjs/tween.js'; ...@@ -21,23 +26,38 @@ 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 {
// 数据
_data;
@ViewChild('canvas', {static: true }) canvas: ElementRef; @Input()
@ViewChild('wrap', {static: true }) wrap: ElementRef; set data(data) {
this._data = data;
}
get data() {
return this._data;
}
// 数据 @Input()
data; sid;
@ViewChild('canvas', { static: true }) canvas: ElementRef;
@ViewChild('wrap', { static: true }) wrap: ElementRef;
canvasWidth = 1280;
canvasHeight = 720;
canvasBaseW = 1280;
canvasBaseH = 720;
ctx; ctx;
fps = 0;
frametime = 0; // 上一帧动画的时间, 两帧时间差
canvasWidth = 1280; // canvas实际宽度
canvasHeight = 720; // canvas实际高度
canvasBaseW = 1280; // canvas 资源预设宽度 mx;
canvasBaseH = 720; // canvas 资源预设高度 my; // 点击坐标
mx; // 点击x坐标
my; // 点击y坐标
// 资源 // 资源
...@@ -49,132 +69,1317 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -49,132 +69,1317 @@ export class PlayComponent implements OnInit, OnDestroy {
animationId: any; animationId: any;
winResizeEventStream = new Subject(); winResizeEventStream = new Subject();
audioObj = {};
audioObj = {};
renderArr; renderArr;
mapScale = 1; mapScale = 1;
canvasLeft; canvasLeft;
canvasTop; canvasTop;
saveKey = 'test_0011';
canTouch = true;
KEY = 'pu_16';
// -----
picArr;
titleLabel;
light;
particleLayer;
shadowArr;
answerTarget;
answerCurrent;
bgRect;
starBgArr;
clickedSuccessArr;
pageLabel;
leftBtn;
rightBtn;
bgLayer;
curPageIndex;
hotZoneArr;
picIndex = 0;
bgArr;
endPageArr;
gameEndFlag;
showPetalFlag;
bg;
btnLeft;
btnRight;
pic1;
pic2;
canTouch = true;
curPic;
@HostListener('window:resize', ['$event']) @HostListener('window:resize', ['$event'])
onResize(event) { onResize(event) {
this.winResizeEventStream.next(); this.winResizeEventStream.next();
} }
ngOnInit() { ngOnInit() {
this.data = {};
// 获取数据 const getData = (<any>window).courseware.getData;
const getData = (<any> window).courseware.getData;
getData((data) => { getData((data) => {
if (data && typeof data == 'object') { if (data && typeof data == 'object') {
this.data = data; this.data = { contentObj: data };
} else {
this.initDefaultData();
}
console.log('data:', data);
if (!this.data) {
this.data.contentObj = {};
} }
// console.log('data:' , data);
// 初始化 各事件监听
this.initListener();
// 若无数据 则为预览模式 需要填充一些默认数据用来显示
this.initDefaultData();
// 初始化 音频资源
this.initAudio(); this.initAudio();
// 初始化 图片资源
this.initImg(); this.initImg();
// 开始预加载资源 this.initListener();
this.load();
}, this.KEY);
//
// // this.initAudio();
// this.initImg();
// this.initListener();
}
initDefaultData() {
const data = { "bgItem": { "url": "http://staging-teach.cdn.ireadabc.com/92494971d4791dc82ea2e6a2608a2499.jpeg", "rect": { "x": 279.14, "y": 0, "width": 964.72, "height": 572 } }, "hotZoneItemArr": [{ "id": "1618278861641", "index": 0, "itemType": "rect", "fontScale": 1.18984375, "imgScale": 1, "mapScale": 1.18984375, "gIdx": "0", "rect": { "x": 171.86, "y": 421, "width": 341, "height": 122 } }, { "id": "1618278871717", "index": 1, "itemType": "rect", "fontScale": 1.18984375, "imgScale": 1, "mapScale": 1.18984375, "gIdx": "0", "rect": { "x": 559.86, "y": 225, "width": 293, "height": 156 } }], "title": "qipao qipao qipao qipao qipao qipao ." };
this.data = { contentObj: data };
return;
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.mapScale = this.canvasWidth / this.canvasBaseW;
// this.mapScale = this.canvasHeight / this.canvasBaseH;
this.renderArr = [];
console.log(' in initData', this.data);
this.canTouch = true;
this.curPageIndex = 0;
// this.downFlag = false;
this.endPageArr = [];
this.shadowArr = [];
this.starBgArr = [];
// this.clockUpdateFlag = false;
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 addAudio = (key) => {
// const audioUrl = contentObj[key];
// if (audioUrl) {
// const audio = new Audio();
// audio.src = audioUrl;
// audio.load();
// this.audioObj[key] = audio;
// }
// }
//
// for (let i = 0; i < 4; i ++) {
// const key = i + '_audio_url';
// addAudio(key);
// }
//
// addAudio('audio_url');
//
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('open', this.rawAudios.get('open'), 0.5);
// addOneAudio('cow_start', this.rawAudios.get('cow_start'), 1);
// addOneAudio('eat', this.rawAudios.get('eat'), 1);
// addOneAudio('grass', this.rawAudios.get('grass'), 1);
// addOneAudio('happy', this.rawAudios.get('happy'), 1);
// addOneAudio('right', this.rawAudios.get('right'), 1);
// addOneAudio('wrong', this.rawAudios.get('wrong'), 1);
//
// const titleUrl = this.data.contentObj.title_audio_url;
// if (titleUrl) {
//
// this.titleAudio.src = titleUrl;
// this.titleAudio.load();
// }
// this.bgAudio.src = 'assets/bat-mail/music/bg.mp3';
// this.bgAudio.load();
// this.bgAudio.loop = true;
// this.bgAudio.volume = 0.5;
//
// this.wrongAudio.src = 'assets/common/music/wrong.mp3';
// this.wrongAudio.load();
//
// this.rightAudio.src = 'assets/common/music/right.mp3';
// this.rightAudio.load();
//
// this.successAudio.src = 'assets/magic-hat/music/finish.mp3';
// this.successAudio.load();
//
// this.successAudio.onended = () => {
// // this.showSuccessAudio();
// };
}
initImg() {
const contentObj = this.data.contentObj;
if (contentObj) {
const addPicUrl = (url) => {
if (url) {
this.rawImages.set(url, url);
}
};
let arr = this.data.contentObj.hotZoneItemArr;
if (arr) {
for (let i = 0; i < arr.length; i++) {
console.log('arr[i].pic_url: ', arr[i].pic_url);
addPicUrl(arr[i].pic_url);
}
}
addPicUrl(contentObj.bgItem.url);
}
// this.initFontImg();
// 预加载资源
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.initTitle();
// this.initPic();
// this.initTitle();
// this.initLight();
// this.refreshAnswerNum();
this.test();
}
test() {
}
curDialog;
initTitle() {
const dialogSmall = new MySprite();
dialogSmall.init(this.images.get("dialog_small"))
dialogSmall.x = this.canvasWidth / 2;
dialogSmall.y = ( dialogSmall.height / 2 + 20 ) * dialogSmall.scaleY;
this.renderArr.push(dialogSmall);
const dialogBig = new MySprite();
dialogBig.init(this.images.get("dialog_big"))
dialogBig.x = this.canvasWidth / 2;
dialogBig.y = ( dialogBig.height / 2 + 20 ) * dialogBig.scaleY;
this.renderArr.push(dialogBig);
dialogSmall.setScaleXY(this.mapScale);
dialogBig.setScaleXY(this.mapScale);
const label = new Label();
label.fontSize = 35;
label.fontName = 'BRLNSDB';
label.textAlign = 'center';
// label.setMaxSize(this.canvasWidth * 0.9);
// label.x = this.canvasWidth / 2;
// label.y = this.canvasHeight / 2;
label.fontColor = '#000000';
label.text = this.data.contentObj.title || "";
dialogSmall.addChild(label);
dialogSmall['label'] = label;
label.refreshSize();
const richText = new RichText();
richText.fontSize = 40;
richText.setMaxSize(dialogBig.width * 0.92);
richText.text = label.text;
richText.fontColor = '#000000'
richText.fontName = 'BRLNSDB';
richText.width = dialogBig.width * 0.92;
richText.disH = 10;
richText.x = -richText.width / 2 + 15;
// richText.textAlign = "center";
richText.textBaseline = "top";
const h = richText.getAreaHeight();
richText.y = -h / 2 - dialogBig.height / 2 + richText.fontSize / 2 + 3;
dialogBig.addChild(richText);
dialogBig['label'] = richText;
if (label.width > dialogSmall.width * 0.92) {
dialogSmall.visible = false;
this.curDialog = dialogBig;
} else {
dialogBig.visible = false;
this.curDialog = dialogSmall;
}
// this.renderArr.push(label);
}
_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);
}
}
}
}
showAudio() {
const data = this.picArr[this.curPageIndex];
const audio = this.audioObj[data.audio_url];
if (audio) {
audio.play();
}
}
initPic() {
}
initLight() {
// const light = new MySprite();
// light.init(this.images.get('light'));
// light.visible = false;
// this.light = light;
// this.renderArr.push(light);
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 ShapeRect();
bg.setSize(this.canvasWidth, this.canvasHeight);
bg.fillColor = '#8b6a48'
// bg.x = this.canvasWidth / 2;
// bg.y = this.canvasHeight / 2;
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 / 2;
const maxW = this.canvasWidth;
const maxH = this.canvasHeight;
let sx = maxW / bgItem.width;
let sy = maxH / bgItem.height;
let 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;
}
mapDown(event) {
if (!this.canTouch) {
return;
}
if (this.checkClickTarget(this.openBtn)) {
this.openBtnClicked();
this.canTouch = false;
}
// 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) {
}
openBtnClicked() {
console.log(' cliced open btn');
this.showBgPic();
}
showBgPic() {
const time = 0.7;
tweenChange(this.maskBg, { alpha: 0 }, time, () => {
this.maskBg.visible = false;
}, TWEEN.Easing.Cubic.Out)
tweenChange(this.openBtn, { alpha: 0 }, time, () => {
this.openBtn.visible = false;
}, TWEEN.Easing.Cubic.Out)
this.curDialog.label.visible = false;
tweenChange(this.curDialog, { alpha: 0 }, time / 3, () => {
this.curDialog.visible = false;
}, TWEEN.Easing.Cubic.Out)
this.playAudio('open')
}
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);
}
updateItem(item) {
if (item) {
item.update();
}
}
updateArr(arr) {
if (!arr) {
return;
}
for (let i = 0; i < arr.length; i++) {
arr[i].update(this);
}
}
maskBg;
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;
console.log('arr: ', arr);
const maskBg = new ShapeRect();
maskBg.setSize(this.canvasWidth, this.canvasHeight);
// maskBg.x = curBgRect.x;
// maskBg.y = curBgRect.y;
maskBg.fillColor = "#000000"
this.maskBg = maskBg;
this.renderArr.push(maskBg);
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;
data.rect.y *= rate;
data.rect.width *= rate;
data.rect.height *= rate;
data.rect.x += curBgRect.x;
data.rect.y += curBgRect.y;
const hotZone = this.getHotZoneItem(data);
// hotZone.alpha = 0.5;
// this.hotZoneArr.push(hotZone);
}
}
openBtn;
getHotZoneItem(data) {
console.log(' item data: ', data);
const saveRect = data.rect;
if (data.gIdx == '0') {
//遮照
const pic = new MySprite();
pic.init(this.images.get(data.pic_url));
pic.scaleX = saveRect.width / pic.width;
pic.scaleY = saveRect.height / pic.height;
pic.x = saveRect.x + saveRect.width / 2;
pic.y = saveRect.y + saveRect.height / 2;
pic['data'] = data;
this.maskBg.setMaskType("destination-out");
this.maskBg.addMaskSpr(pic);
return pic;
} else {
//open按钮
const openBtn = new MySprite();
openBtn.init(this.images.get("open"))
}, this.saveKey); openBtn.x = saveRect.x + saveRect.width / 2;
openBtn.y = saveRect.y + saveRect.height / 2;
openBtn['data'] = data;
openBtn.setScaleXY(this.mapScale);
this.openBtn = openBtn;
this.renderArr.push(openBtn);
} }
ngOnDestroy() {
window['curCtx'] = null;
window.cancelAnimationFrame(this.animationId);
this.cleanAudio();
}
// 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.fillColor = '#ff0000';
// item['data'] = data;
cleanAudio() { // this.renderArr.push(item);
if (this.audioObj) {
for (const key in this.audioObj) {
this.audioObj[key].pause();
}
}
}
// return item;
}
load() {
// 预加载资源 showEndPetal() {
this.loadResources().then(() => { this.endPageArr = [];
window["air"].hideAirClassLoading(this.saveKey, this.data); this.showPetalFlag = true;
this.init(); this.addPetal();
this.update();
});
} }
stopEndPetal() {
this.endPageArr = [];
this.showPetalFlag = false;
}
init() { addPetal() {
this.initCtx(); if (!this.showPetalFlag) {
this.initData(); return;
this.initView();
} }
initCtx() { const petal = this.getPetal();
this.canvasWidth = this.wrap.nativeElement.clientWidth; this.endPageArr.push(petal);
this.canvasHeight = this.wrap.nativeElement.clientHeight;
this.canvas.nativeElement.width = this.wrap.nativeElement.clientWidth;
this.canvas.nativeElement.height = this.wrap.nativeElement.clientHeight;
moveItem(petal, petal.x, this.canvasHeight + petal.height * petal.scaleY, petal['time'], () => {
removeItemFromArr(this.endPageArr, petal);
});
this.ctx = this.canvas.nativeElement.getContext('2d'); rotateItem(petal, petal['tr'], petal['time']);
this.canvas.nativeElement.width = this.canvasWidth;
this.canvas.nativeElement.height = this.canvasHeight; setTimeout(() => {
this.addPetal();
}, 100);
window['curCtx'] = this.ctx;
window['curImages'] = this.images;
} }
getPetal() {
const petal = new MySprite(this.ctx);
const id = Math.ceil(Math.random() * 3);
petal.init(this.images.get('petal_' + id));
const randomS = (Math.random() * 0.4 + 0.6) * this.mapScale;
petal.setScaleXY(randomS);
updateItem(item) { const randomR = Math.random() * 360;
if (item) { petal.rotation = randomR;
item.update();
}
}
updateArr(arr) { const randomX = Math.random() * this.canvasWidth;
if (!arr) { petal.x = randomX;
return; petal.y = -petal.height / 2 * petal.scaleY;
}
for (let i = 0; i < arr.length; i++) { const randomT = 0.5 + Math.random() * 2.5;
arr[i].update(this); petal['time'] = randomT;
}
}
let randomTR = 360 * Math.random(); // - 180;
if (Math.random() < 0.5) { randomTR *= -1; }
petal['tr'] = randomTR;
return petal;
}
...@@ -220,6 +1425,7 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -220,6 +1425,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);
}; };
...@@ -237,6 +1443,7 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -237,6 +1443,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);
}; };
...@@ -301,6 +1508,43 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -301,6 +1508,43 @@ 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 = [];
this.rawImages.forEach((value, key) => {// 预加载图片 this.rawImages.forEach((value, key) => {// 预加载图片
...@@ -314,7 +1558,7 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -314,7 +1558,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(() => {
...@@ -340,8 +1584,9 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -340,8 +1584,9 @@ export class PlayComponent implements OnInit, OnDestroy {
preloadAudio(url) { preloadAudio(url) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const audio = new Audio(); const audio = new Audio();
resolve({})
audio.oncanplay = (a) => { audio.oncanplay = (a) => {
resolve(); //resolve();
}; };
audio.onerror = () => { audio.onerror = () => {
reject(); reject();
...@@ -360,8 +1605,6 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -360,8 +1605,6 @@ export class PlayComponent implements OnInit, OnDestroy {
checkClickTarget(target) { checkClickTarget(target) {
const rect = target.getBoundingBox(); const rect = target.getBoundingBox();
...@@ -394,297 +1637,22 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -394,297 +1637,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);
} }
} }
const res = [ const res = [
// ['bg', "assets/play/bg.jpg"], // ['bg', "assets/play/bg.jpg"],
['btn_left', "assets/play/btn_left.png"], ['bg_left', "assets/play/bg_left.png"],
['btn_right', "assets/play/btn_right.png"], ['bg_right', "assets/play/bg_right.png"],
['bg', "assets/play/bg.png"],
['open', "assets/play/open.png"],
['dialog_big', "assets/play/dialog_big.png"],
['dialog_small', "assets/play/dialog_small.png"],
// ['text_bg', "assets/play/text_bg.png"], // ['text_bg', "assets/play/text_bg.png"],
]; ];
...@@ -11,7 +15,7 @@ const res = [ ...@@ -11,7 +15,7 @@ const res = [
const resAudio = [ const resAudio = [
['click', "assets/play/music/click.mp3"], ['open', "assets/play/music/open.mp3"],
]; ];
......
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