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

feat: 初次提交

parent ce304201
...@@ -128,5 +128,8 @@ ...@@ -128,5 +128,8 @@
} }
} }
}, },
"defaultProject": "ng-template-generator" "defaultProject": "ng-template-generator",
"cli": {
"analytics": "7ae231a8-358a-4ce6-9597-2bc03da77a3e"
}
} }
\ No newline at end of file
...@@ -29,10 +29,10 @@ ...@@ -29,10 +29,10 @@
"compressing": "^1.5.0", "compressing": "^1.5.0",
"ng-zorro-antd": "^8.5.2", "ng-zorro-antd": "^8.5.2",
"rxjs": "~6.5.4", "rxjs": "~6.5.4",
"node-sass": "^4.0.0",
"spark-md5": "^3.0.0", "spark-md5": "^3.0.0",
"tslib": "^1.10.0", "tslib": "^1.10.0",
"zone.js": "~0.10.2" "zone.js": "~0.10.2",
"node-sass": "^4.0.0"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "~0.900.3", "@angular-devkit/build-angular": "~0.900.3",
......
...@@ -24,7 +24,6 @@ import {AudioRecorderComponent} from './common/audio-recorder/audio-recorder.com ...@@ -24,7 +24,6 @@ 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 { UploadDragonBoneComponent } from './common/upload-dragon-bone/upload-dragon-bone.component';
registerLocaleData(zh); registerLocaleData(zh);
...@@ -41,7 +40,7 @@ registerLocaleData(zh); ...@@ -41,7 +40,7 @@ registerLocaleData(zh);
TimePipe, TimePipe,
UploadVideoComponent, UploadVideoComponent,
CustomHotZoneComponent, CustomHotZoneComponent,
UploadDragonBoneComponent,
PlayerContentWrapperComponent PlayerContentWrapperComponent
], ],
......
class Obj{
/**音频材料 */
audioUrl: String;
/**图片材料 */
picUrl:String;
/**值 */
val : String;
}
export class Answer extends Obj{
/**是否正确:0-否,1-是 */
isRight:String;
}
export class Exercises extends Obj{
/**备选择答案:3-5个 */
answers :Array<Answer> = [];
/**序列帧 */
frames : Array<Frame> = [];
hotZoneItemArr = [];
bg : Backgroud;
}
export class Frame extends Obj{
}
export class Backgroud extends Obj{
rect = {};
}
export class Title extends Obj{
}
export class Item{
title : Title;
//练习题
exercisesArr : Array<Exercises> = [];
}
export function getDefaultItem(){
const item = new Item();
item.title = new Title();
item.title.val = 'Find Body Part'
return item;
}
export function getDefaultExercises(){
const exercises = new Exercises();
exercises.bg = new Backgroud();
for(let i = 0; i < 3; ++ i){
const answer = new Answer();
answer.isRight = '0';
exercises.answers.push(answer);
}
return exercises;
}
\ No newline at end of file
...@@ -7,13 +7,14 @@ ...@@ -7,13 +7,14 @@
</div> </div>
<div nz-row nzType="flex" nzAlign="middle"> <div nz-row nzType="flex" nzAlign="middle">
<div nz-col nzSpan="5" nzOffset="1"> <div nz-col nzSpan="5" nzOffset="1">
<h5> add background: </h5> <h5> add background: </h5>
<div class="bg-box"> <div class="bg-box">
<app-upload-image-with-preview <app-upload-image-with-preview
[picUrl]="bgItem?.url" [picUrl]="bgItem?.picUrl"
(imageUploaded)="onBackgroundUploadSuccess($event)"> (imageUploaded)="onBackgroundUploadSuccess($event)">
</app-upload-image-with-preview> </app-upload-image-with-preview>
</div> </div>
...@@ -35,9 +36,12 @@ ...@@ -35,9 +36,12 @@
<div style="margin-top: -20px; margin-bottom: 5px"> <div style="margin-top: -20px; margin-bottom: 5px">
<nz-radio-group [ngModel]="it.itemType" (ngModelChange)="radioChange($event, it)"> <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>
...@@ -68,10 +72,10 @@ ...@@ -68,10 +72,10 @@
<div class="bg-box"> <div class="bg-box">
<button nz-button nzType="dashed" (click)="addBtnClick()" <button nz-button nzType="dashed" (click)="addBtnClick()"
class="add-btn"> class="add-btn" [disabled]="hotZoneArr.length == 1 ? true : false">
<i nz-icon nzType="plus-circle" nzTheme="outline"></i> <i nz-icon nzType="plus-circle" nzTheme="outline"></i>
<!--Add Image--> <!--Add Image-->
Add hot zone 添气泡
</button> </button>
</div> </div>
......
...@@ -10,12 +10,12 @@ import { ...@@ -10,12 +10,12 @@ import {
Output, Output,
ViewChild ViewChild
} 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, Label, MySprite, removeItemFromArr } from './Unit';
import TWEEN from '@tweenjs/tween.js'; import TWEEN from '@tweenjs/tween.js';
import {getMinScale} from "../../play/Unit"; import { getMinScale, ShapeRect } from "../../play/Unit";
import {tar} from "compressing"; import { tar } from "compressing";
@Component({ @Component({
...@@ -34,8 +34,8 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -34,8 +34,8 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
hotZoneArr = null; hotZoneArr = null;
@Output() @Output()
save = new EventEmitter(); save = new EventEmitter();
@ViewChild('canvas', {static: true}) canvas: ElementRef; @ViewChild('canvas', { static: true }) canvas: ElementRef;
@ViewChild('wrap', {static: true}) wrap: ElementRef; @ViewChild('wrap', { static: true }) wrap: ElementRef;
@Input() @Input()
isHasRect = true; isHasRect = true;
...@@ -50,7 +50,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -50,7 +50,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
color: '#8f3758' color: '#8f3758'
} }
@Input() @Input()
defaultItemType = 'text'; defaultItemType = 'pic';
@Input() @Input()
hotZoneImgSize = 190; hotZoneImgSize = 190;
...@@ -129,7 +129,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -129,7 +129,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
onBackgroundUploadSuccess(e) { onBackgroundUploadSuccess(e) {
console.log('e: ', e); console.log('e: ', e);
this.bgItem.url = e.url; this.bgItem.picUrl = e.url;
this.refreshBackground(); this.refreshBackground();
} }
...@@ -145,20 +145,25 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -145,20 +145,25 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
refreshBackground(callBack = null) { refreshBackground(callBack = null) {
if (this.bgItem.picUrl) {
if (!this.bg) { if (!this.bg) {
this.bg = new MySprite(this.ctx); this.bg = new MySprite(this.ctx);
this.renderArr.push(this.bg); this.renderArr.push(this.bg);
} }
const bg = this.bg; const bg = this.bg;
if (this.bgItem.url) {
bg.load(this.bgItem.url).then(() => { bg.load(this.bgItem.picUrl).then(() => {
const rate1 = this.canvasWidth / bg.width; const rate1 = this.canvasWidth / bg.width;
const rate2 = this.canvasHeight / bg.height; const rate2 = this.canvasHeight / bg.height;
const rate = Math.min(rate1, rate2); //const rate = Math.max(rate1, rate2);
bg.setScaleXY(rate); //bg.setScaleXY(rate);
bg.scaleX = rate1;
bg.scaleY = rate2;
bg.x = this.canvasWidth / 2; bg.x = this.canvasWidth / 2;
...@@ -169,6 +174,11 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -169,6 +174,11 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
} }
}); });
} }
else{
if (callBack) {
callBack();
}
}
} }
...@@ -257,7 +267,6 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -257,7 +267,6 @@ 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.showLineDash(); item.showLineDash();
...@@ -382,25 +391,21 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -382,25 +391,21 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
} }
initItem() { initItem() {
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 = [];
} else { } else {
this.initHotZoneArr(); this.initHotZoneArr();
} }
}); });
} }
...@@ -413,7 +418,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -413,7 +418,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
if (this.bg) { if (this.bg) {
curBgRect = this.bg.getBoundingBox(); curBgRect = this.bg.getBoundingBox();
} else { } else {
curBgRect = {x: 0, y: 0, width: this.canvasWidth, height: this.canvasHeight}; curBgRect = { x: 0, y: 0, width: this.canvasWidth, height: this.canvasHeight };
} }
let oldBgRect = this.bgItem.rect; let oldBgRect = this.bgItem.rect;
...@@ -440,10 +445,6 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -440,10 +445,6 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
data.rect.x += curBgRect.x; data.rect.x += curBgRect.x;
data.rect.y += curBgRect.y; data.rect.y += curBgRect.y;
// img['picItem'] = this.getPicItem(img, data);
// img['audio_url'] = arr[i].audio_url;
// this.imgArr.push(img);
const item = this.getHotZoneItem(data); const item = this.getHotZoneItem(data);
item.audio_url = data.audio_url; item.audio_url = data.audio_url;
item.pic_url = data.pic_url; item.pic_url = data.pic_url;
...@@ -451,7 +452,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -451,7 +452,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
item.itemType = data.itemType; item.itemType = data.itemType;
this.refreshItem(item); this.refreshItem(item);
console.log('item: ', item); //console.log('item: ', item);
this.hotZoneArr.push(item); this.hotZoneArr.push(item);
} }
...@@ -470,7 +471,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -470,7 +471,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
if (this.bg) { if (this.bg) {
curBgRect = this.bg.getBoundingBox(); curBgRect = this.bg.getBoundingBox();
} else { } else {
curBgRect = {x: 0, y: 0, width: this.canvasWidth, height: this.canvasHeight}; curBgRect = { x: 0, y: 0, width: this.canvasWidth, height: this.canvasHeight };
} }
let oldBgRect = this.bgItem.rect; let oldBgRect = this.bgItem.rect;
...@@ -487,7 +488,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -487,7 +488,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
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]));
const img = {pic_url: data.pic_url}; const img = { pic_url: data.pic_url };
data.rect.x *= rate; data.rect.x *= rate;
data.rect.y *= rate; data.rect.y *= rate;
...@@ -510,6 +511,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -510,6 +511,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
this.canvasWidth = this.wrap.nativeElement.clientWidth; this.canvasWidth = this.wrap.nativeElement.clientWidth;
this.canvasHeight = this.wrap.nativeElement.clientHeight; this.canvasHeight = this.wrap.nativeElement.clientHeight;
this.mapScale = this.canvasWidth / this.canvasBaseW; this.mapScale = this.canvasWidth / this.canvasBaseW;
this.renderArr = []; this.renderArr = [];
this.bg = null; this.bg = null;
...@@ -518,6 +520,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -518,6 +520,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
} }
initCtx() { initCtx() {
this.ctx = this.canvas.nativeElement.getContext('2d'); this.ctx = this.canvas.nativeElement.getContext('2d');
this.canvas.nativeElement.width = this.canvasWidth; this.canvas.nativeElement.width = this.canvasWidth;
this.canvas.nativeElement.height = this.canvasHeight; this.canvas.nativeElement.height = this.canvasHeight;
...@@ -526,7 +529,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -526,7 +529,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
mapDown(event) { mapDown(event) {
this.oldPos = {x: this.mx, y: this.my}; this.oldPos = { x: this.mx, y: this.my };
for (let i = 0; i < this.hotZoneArr.length; i++) { for (let i = 0; i < this.hotZoneArr.length; i++) {
...@@ -580,7 +583,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -580,7 +583,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
this.curItem.y += addY; this.curItem.y += addY;
} }
this.oldPos = {x: this.mx, y: this.my}; this.oldPos = { x: this.mx, y: this.my };
this.saveDisabled = true; this.saveDisabled = true;
...@@ -880,7 +883,9 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -880,7 +883,9 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
fontColor: this.hotZoneFontObj.color, 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,
picX: hotZoneArr[i].pic ? hotZoneArr[i].pic.x : 0,
picY: hotZoneArr[i].pic ? hotZoneArr[i].pic.y : 0
}; };
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;
...@@ -888,13 +893,11 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -888,13 +893,11 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
hotZoneItem['rect'].width = Math.round((hotZoneItem['rect'].width) * 100) / 100; hotZoneItem['rect'].width = Math.round((hotZoneItem['rect'].width) * 100) / 100;
hotZoneItem['rect'].height = Math.round((hotZoneItem['rect'].height) * 100) / 100; hotZoneItem['rect'].height = Math.round((hotZoneItem['rect'].height) * 100) / 100;
hotZoneItemArr.push(hotZoneItem); hotZoneItemArr.push(hotZoneItem);
} }
console.log('hotZoneItemArr: ', hotZoneItemArr);
this.save.emit({bgItem, hotZoneItemArr}); this.save.emit({ bgItem, hotZoneItemArr });
} }
private updatePos() { private updatePos() {
...@@ -979,8 +982,8 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -979,8 +982,8 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
private loadHotZonePic(pic: HotZoneImg, url) { private loadHotZonePic(pic: HotZoneImg, url) {
const baseLen = this.hotZoneImgSize * this.mapScale; const baseLen = this.hotZoneImgSize * this.mapScale;
pic.load(url).then(() => { pic.load(url).then(() => {
const s = getMinScale(pic, baseLen); //const s = getMinScale(pic, baseLen);
pic.setScaleXY(s); pic.setScaleXY(this.mapScale);
}); });
} }
} }
<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() {
}
}
<div class="model-content"> <div class="model-content">
<div nz-row>
<div style="padding: 10px;"> <div nz-col nzOffset='4'>
<h1 nz-title>课程练习内容编辑</h1>
<div style="width: 300px;" align='center'> </div>
<span>图1: </span> </div>
<app-upload-image-with-preview <div nz-row>
[picUrl]="item.pic_url" <div nz-col [nzSpan]="20" nzOffset="2">
(imageUploaded)="onImageUploadSuccess($event, 'pic_url')"> <div nz-form>
<div id='title-anchor'>
<nz-divider nzText="基本信息" nzOrientation="left"></nz-divider>
<nz-form-item>
<nz-form-label [nzSpan]="3" nzFor="title">标题</nz-form-label>
<nz-form-control [nzSpan]="6">
<input type="text" id="title" nz-input [(ngModel)]="item.title.val" (blur)="save()">
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSpan]="3" nzFor="audioUrl">发音</nz-form-label>
<nz-form-control [nzSpan]="6">
<app-audio-recorder [audioUrl]="item.title.audioUrl" id="audioUrl"
(audioUploaded)="onAudioUploadSuccess($event, item.title, 'audioUrl')">
</app-audio-recorder>
</nz-form-control>
</nz-form-item>
<!--
<nz-form-item>
<nz-form-label [nzSpan]="3">背景图片</nz-form-label>
<nz-form-control [nzSpan]="6">
<app-upload-image-with-preview style="width: 100%" [picUrl]="item.bg.picUrl"
(imageUploaded)="onImageUploadSuccess($event,item.bg, 'picUrl')">
</app-upload-image-with-preview> </app-upload-image-with-preview>
</nz-form-control>
</nz-form-item>
-->
</div>
</div>
</div>
</div> </div>
<div nz-row>
<div id='listen-anchor' nz-col [nzSpan]="20" nzOffset="2">
<nz-divider nzText="练习题" nzOrientation="left"></nz-divider>
<nz-form-item>
<nz-form-label [nzSpan]="6" nzFor="exercises">操作</nz-form-label>
<nz-form-control [nzSpan]="6">
<button nz-button nzType="dashed" class="add-btn" id="add-btn" (click)="addExercisesItem()">
<i nz-icon nzType="plus-circle" nzTheme="outline"></i>添加
</button>
</nz-form-control>
</nz-form-item>
</div>
<div nz-col [nzSpan]="20" nzOffset="2" class='border'>
<div *ngFor="let data of item.exercisesArr;let i = index">
<div class='border-lite'>内容:{{i+1}}
<button style="margin: 10px;" nz-button nzType="danger" (click)="delExercisesItem(i)">
<span>删除</span>
</button>
</div>
<app-custom-hot-zone [bgItem]="data.bg" [hotZoneItemArr]="data.hotZoneItemArr"
(save)="saveData($event, i)"></app-custom-hot-zone>
<nz-form-item>
<nz-form-label [nzSpan]="6">动画</nz-form-label>
<nz-form-control [nzSpan]="6">
<button nz-button nzType="dashed" (click)="setAnimaBtnClick(data)" nzSize="large" style="margin-top: 10px" >
<i nz-icon nzType="tool" nzTheme="outline"></i>
配置龙骨动画
</button>
</nz-form-control>
</nz-form-item>
<div style="width: 300px; margin-top: 5px;" align='center'> <nz-form-item>
<span>图2: </span> <nz-form-label [nzSpan]="6">备选答案</nz-form-label>
<app-upload-image-with-preview <nz-form-control [nzSpan]="6">
[picUrl]="item.pic_url_2" <button nz-button nzType="dashed" class="add-btn" id="add-btn"
(imageUploaded)="onImageUploadSuccess($event, 'pic_url_2')"> (click)="addAnswer(data, 'answers')" [disabled]="data.answers.length == 5 ? true : false">
<i nz-icon nzType="plus-circle" nzTheme="outline"></i>添加
</button>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control [nzOffset]="2" [nzSpan]="18">
<nz-table #answerTable nzBordered nzTitle="备选答案" [nzData]="data.answers"
[nzShowPagination]=false>
<thead>
<tr>
<th>序号</th>
<th>音频</th>
<th>图片</th>
<th>是否正确答案</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let answer of answerTable.data;let j = index">
<td>{{ j+1 }}</td>
<td>
<app-audio-recorder [audioUrl]="answer.audioUrl"
(audioUploaded)="onAudioUploadSuccess($event, answer, 'audioUrl')">
</app-audio-recorder>
</td>
<td>
<app-upload-image-with-preview [picUrl]="answer.picUrl"
(imageUploaded)="onImageUploadSuccess($event, answer, 'picUrl')">
</app-upload-image-with-preview> </app-upload-image-with-preview>
</td>
<td>
<nz-radio-group [(ngModel)]="answer.isRight" (ngModelChange)="radioChange($event, data, answer)">
<label nz-radio nzValue="1"></label>
<label nz-radio nzValue="0"></label>
</nz-radio-group>
</td>
<td>
<button nz-button nzType="danger" (click)="delAnswer(data, 'answers', j)"
[disabled]="data.answers.length == 3 ? true : false">
<span>删除</span>
</button>
</td>
</tr>
</tbody>
</nz-table>
</nz-form-control>
</nz-form-item>
</div>
</div>
</div> </div>
<div style="width: 300px; margin-top: 15px;"> <!--龙骨面板-->
<span>文本: </span> <nz-modal [(nzVisible)]="animaPanelVisible" nzTitle="配置资源文件" (nzOnCancel)="animaPanelCancel()" (nzOnOk)="animaPanelOk()" nzOkText="保存">
<input type="text" nz-input [(ngModel)]="item.text" (blur)="save()">
<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>
<div style="margin-top: 5px"> <div class="anima-upload-btn">
<span>音频: </span> <span style="margin-right: 10px">上传 tex_json 文件: </span>
<app-audio-recorder <nz-upload [nzShowUploadList]="false"
[audioUrl]="item.audio_url" nzAccept="application/json"
(audioUploaded)="onAudioUploadSuccess($event, 'audio_url')" [nzAction]="uploadUrl"
></app-audio-recorder> [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>
<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>
</nz-modal>
</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'; import { JsonPipe } from '@angular/common';
import { Answer, Backgroud, Frame, getDefaultExercises, getDefaultItem } from '../bean/ObjBean';
import {NzMessageService} from 'ng-zorro-antd';
@Component({ @Component({
selector: 'app-form', selector: 'app-form',
...@@ -10,32 +11,35 @@ import { JsonPipe } from '@angular/common'; ...@@ -10,32 +11,35 @@ import { JsonPipe } from '@angular/common';
export class FormComponent implements OnInit, OnChanges, OnDestroy { export class FormComponent implements OnInit, OnChanges, OnDestroy {
// 储存数据用 // 储存数据用
saveKey = "test_001"; saveKey = "FT-01";
// 储存对象 // 储存对象
item; item;
isShowPicPanel = false;
curGroup = null;
skeJsonData = {};
texJsonData = {};
texPngData = {};
animaPanelVisible = false;
isSkeJsonLoading = false;
isTexJsonLoading = false;
isTexPngLoading = false;
constructor(private appRef: ApplicationRef, private changeDetectorRef: ChangeDetectorRef) { uploadUrl;
uploadData;
}
createShell() { constructor(private appRef: ApplicationRef, private changeDetectorRef: ChangeDetectorRef,private nzMessageService: NzMessageService) {
this.item.wordList.push({ this.uploadUrl = (<any> window).courseware.uploadUrl();
word: '', this.uploadData = (<any> window).courseware.uploadData();
audio: '',
backWord: '',
backWordAudio: '',
});
this.save();
}
removeShell(idx) { window['air'].getUploadCallback = (url, data) => {
this.item.wordList.splice(idx, 1); this.uploadUrl = url;
this.save(); this.uploadData = data;
};
} }
ngOnInit() { ngOnInit() {
this.item = {}; this.item = getDefaultItem();
// 获取存储的数据 // 获取存储的数据
(<any>window).courseware.getData((data) => { (<any>window).courseware.getData((data) => {
...@@ -43,7 +47,7 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -43,7 +47,7 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
if (data) { if (data) {
this.item = data; this.item = data;
} }
this.item.exercisesArr[0].hotZoneItemArr[0].picX= 0;
this.init(); this.init();
this.changeDetectorRef.markForCheck(); this.changeDetectorRef.markForCheck();
this.changeDetectorRef.detectChanges(); this.changeDetectorRef.detectChanges();
...@@ -59,7 +63,15 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -59,7 +63,15 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
} }
init() { init() {
console.log(JSON.stringify(this.item));
for(let i = 0; i < this.item.exercisesArr.length; ++ i ){
let exercises = this.item.exercisesArr[i];
if(!exercises.bg){
exercises.bg = new Backgroud();
}
}
} }
...@@ -67,20 +79,21 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -67,20 +79,21 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
* 储存图片数据 * 储存图片数据
* @param e * @param e
*/ */
onImageUploadSuccess(e, key) { onImageUploadSuccess(e, item, key) {
this.item[key] = e.url; item[key] = e.url;
this.save(); this.save();
} }
/** /**
* 储存音频数据 * 储存音频数据
* @param e * @param e
*/ */
onAudioUploadSuccess(e, key) { onAudioUploadSuccess(e, item, key) {
this.item[key] = e.url;
item[key] = e.url;
this.save(); this.save();
} }
onWordAudioUploadSuccess(e, idx) { onWordAudioUploadSuccess(e, idx) {
this.item.wordList[idx].audio = e.url; this.item.wordList[idx].audio = e.url;
...@@ -111,4 +124,168 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -111,4 +124,168 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
}, 1); }, 1);
} }
/**
* 添加练习
*/
addExercisesItem() {
let exercises = getDefaultExercises();
this.item.exercisesArr.push(exercises);
this.save();
}
delExercisesItem(index) {
if (index !== -1) {
this.item.exercisesArr.splice(index, 1);
this.save();
}
}
addAnswer(exercises, key){
let answer = new Answer();
exercises[key] = [...exercises[key], answer];
this.save();
}
delAnswer(exercises, key, index) {
if (index !== -1) {
exercises[key].splice(index, 1);
exercises[key] = [...exercises[key]];
this.save();
}
}
radioChange(e, exercises, answer){
//如果正确答案,则将其它答案置成否
if( e == '1'){
let answers = exercises.answers;
for(let m = 0; m < answers.length; ++ m){
if(answers[m] == answer){
continue;
}
answers[m].isRight = '0';
}
exercises['answers'] = [...exercises['answers']];
}
this.save();
}
saveData(e, i) {
console.log('savedata e:', e);
this.item.exercisesArr[i].bg = e.bgItem;
this.item.exercisesArr[i].hotZoneItemArr = e.hotZoneItemArr;
this.save();
}
handleOk() {
this.isShowPicPanel = false;
}
handleCancel() {
this.isShowPicPanel = false;
}
setAnimaBtnClick(group) {
console.log(' in setAnimaBtnClick');
this.curGroup = group;
const {skeJsonData, texJsonData, texPngData} = group;
this.skeJsonData = skeJsonData || {};
this.texJsonData = texJsonData || {};
this.texPngData = texPngData || {};
this.animaPanelVisible = true;
this.refresh();
}
animaPanelCancel() {
this.animaPanelVisible = false;
}
animaPanelOk() {
this.animaPanelVisible = false;
this.setItemDragonBoneData(this.curGroup);
this.save();
}
setItemDragonBoneData(item) {
item['skeJsonData'] = this.skeJsonData;
item['texJsonData'] = this.texJsonData;
item['texPngData'] = this.texPngData;
}
skeJsonHandleChange(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) {
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) {
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;
}
}
} }
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
import { onHomeworkFinish } from "../script/util";
import { defaultData } from "../script/defaultData";
cc.Class({
extends: cc.Component,
properties: {
},
// 生命周期 onLoad
onLoad() {
this.initSceneData();
this.initSize();
},
_imageResList: null,
_audioResList: null,
_animaResList: null,
initSceneData() {
this._imageResList = [];
this._audioResList = [];
this._animaResList = [];
},
_designSize: null, // 设计分辨率
_frameSize: null, // 屏幕分辨率
_mapScaleMin: null, // 场景中常用缩放(取大值)
_mapScaleMax: null, // 场景中常用缩放(取小值)
_cocosScale: null, // cocos 自缩放 (较少用到)
initSize() {
// 注意cc.winSize只有在适配后(修改fitHeight/fitWidth后)才能获取到正确的值,因此使用cc.getFrameSize()来获取初始的屏幕大小
let screen_size = cc.view.getFrameSize().width / cc.view.getFrameSize().height
let design_size = cc.Canvas.instance.designResolution.width / cc.Canvas.instance.designResolution.height
let f = screen_size >= design_size
cc.Canvas.instance.fitHeight = f
cc.Canvas.instance.fitWidth = !f
const frameSize = cc.view.getFrameSize();
this._frameSize = frameSize;
this._designSize = cc.view.getDesignResolutionSize();
let sx = cc.winSize.width / frameSize.width;
let sy = cc.winSize.height / frameSize.height;
this._cocosScale = Math.min(sx, sy);
sx = frameSize.width / this._designSize.width;
sy = frameSize.height / this._designSize.height;
this._mapScaleMin = Math.min(sx, sy) * this._cocosScale;
this._mapScaleMax = Math.max(sx, sy) * this._cocosScale;
},
// 生命周期 start
start() {
let getData = this.getData.bind(this);
if (window && window.courseware) {
getData = window.courseware.getData;
}
getData((data) => {
console.log('data:', data);
this.data = data || this.getDefaultData();
this.data = JSON.parse(JSON.stringify(this.data))
this.preloadItem()
})
},
getData(func) {
if (window && window.courseware) {
window.courseware.getData(func, 'scene');
return;
}
const middleLayer = cc.find('middleLayer');
if (middleLayer) {
const middleLayerComponent = middleLayer.getComponent('middleLayer');
middleLayerComponent.getData(func);
return;
}
func(this.getDefaultData());
},
getDefaultData() {
return defaultData;
},
preloadItem() {
this.addPreloadImage();
this.addPreloadAudio();
this.addPreloadAnima();
this.preload();
},
addPreloadImage() {
this._imageResList.push({ url: this.data.pic_url });
this._imageResList.push({ url: this.data.pic_url_2 });
},
addPreloadAudio() {
this._audioResList.push({ url: this.data.audio_url });
},
addPreloadAnima() {
},
preload() {
const preloadArr = this._imageResList.concat(this._audioResList).concat(this._animaResList);
cc.assetManager.loadAny(preloadArr, null, null, (err, data) => {
this.loadEnd();
if (window && window["air"]) {
window["air"].hideAirClassLoading();
}
cc.debug.setDisplayStats(false);
});
},
loadEnd() {
this.initData();
this.initAudio();
this.initView();
// this.initListener();
},
_cantouch: null,
initData() {
// 所有全局变量 默认都是null
this._cantouch = true;
},
audioBtn: null,
initAudio() {
const audioNode = cc.find('Canvas/res/audio');
const getAudioByResName = (resName) => {
return audioNode.getChildByName(resName).getComponent(cc.AudioSource);
}
this.audioBtn = getAudioByResName('btn');
},
initView() {
this.initBg();
this.initPic();
this.initBtn();
this.initIcon();
},
initBg() {
const bgNode = cc.find('Canvas/bg');
bgNode.scale = this._mapScaleMax;
},
pic1: null,
pic2: null,
initPic() {
const canvas = cc.find('Canvas');
const maxW = canvas.width * 0.7;
this.getSprNodeByUrl(this.data.pic_url, (sprNode) => {
const picNode1 = sprNode;
picNode1.scale = maxW / picNode1.width;
picNode1.baseX = picNode1.x;
canvas.addChild(picNode1);
this.pic1 = picNode1;
const labelNode = new cc.Node();
labelNode.color = cc.Color.YELLOW;
const label = labelNode.addComponent(cc.Label);
label.string = this.data.text;
label.fontSize = 60;
label.lineHeight = 60;
label.font = cc.find('Canvas/res/font/BRLNSDB').getComponent('cc.Label').font;
picNode1.addChild(labelNode);
});
this.getSprNodeByUrl(this.data.pic_url_2, (sprNode) => {
const picNode2 = sprNode;
picNode2.scale = maxW / picNode2.width;
canvas.addChild(picNode2);
picNode2.x = canvas.width;
picNode2.baseX = picNode2.x;
this.pic2 = picNode2;
const labelNode = new cc.Node();
const label = labelNode.addComponent(cc.RichText);
const size = 60
label.font = cc.find('Canvas/res/font/BRLNSDB').getComponent(cc.Label).font;
label.string = `<outline color=#751e00 width=4><size=${size}><color=#ffffff>${this.data.text}</color></size></outline>`
label.lineHeight = size;
picNode2.addChild(labelNode);
});
},
initIcon() {
const iconNode = this.getSprNode('icon');
iconNode.zIndex = 5;
iconNode.anchorX = 1;
iconNode.anchorY = 1;
iconNode.parent = cc.find('Canvas');
iconNode.x = iconNode.parent.width / 2 - 10;
iconNode.y = iconNode.parent.height / 2 - 10;
iconNode.on(cc.Node.EventType.TOUCH_START, () => {
this.playAudioByUrl(this.data.audio_url);
})
},
curPage: null,
initBtn() {
this.curPage = 0;
const bottomPart = cc.find('Canvas/bottomPart');
bottomPart.zIndex = 5; // 提高层级
bottomPart.x = bottomPart.parent.width / 2;
bottomPart.y = -bottomPart.parent.height / 2;
const leftBtnNode = bottomPart.getChildByName('btn_left');
//节点中添加了button组件 则可以添加click事件监听
leftBtnNode.on('click', () => {
if (!this._cantouch) {
return;
}
if (this.curPage == 0) {
return;
}
this.curPage = 0
this.leftMove();
// 游戏结束时需要调用这个方法通知系统作业完成
onHomeworkFinish();
cc.audioEngine.play(this.audioBtn.clip, false, 0.8)
})
const rightBtnNode = bottomPart.getChildByName('btn_right');
//节点中添加了button组件 则可以添加click事件监听
rightBtnNode.on('click', () => {
if (!this._cantouch) {
return;
}
if (this.curPage == 1) {
return;
}
this.curPage = 1
this.rightMove();
cc.audioEngine.play(this.audioBtn.clip, false, 0.5)
})
},
leftMove() {
this._cantouch = false;
const len = this.pic1.parent.width;
cc.tween(this.pic1)
.to(1, { x: this.pic1.baseX }, { easing: 'cubicInOut' })
.start();
cc.tween(this.pic2)
.to(1, { x: this.pic2.baseX }, { easing: 'cubicInOut' })
.call(() => {
this._cantouch = true;
})
.start();
},
rightMove() {
this._cantouch = false;
const len = this.pic1.parent.width;
cc.tween(this.pic1)
.to(1, { x: this.pic1.baseX - len }, { easing: 'cubicInOut' })
.start();
cc.tween(this.pic2)
.to(1, { x: this.pic2.baseX - len }, { easing: 'cubicInOut' })
.call(() => {
this._cantouch = true;
})
.start();
},
// update (dt) {},
// ------------------------------------------------
getSprNode(resName) {
const sf = cc.find('Canvas/res/img/' + resName).getComponent(cc.Sprite).spriteFrame;
const node = new cc.Node();
node.addComponent(cc.Sprite).spriteFrame = sf;
return node;
},
getSpriteFrimeByUrl(url, cb) {
cc.loader.load({ url }, (err, img) => {
const spriteFrame = new cc.SpriteFrame(img)
if (cb) {
cb(spriteFrame);
}
})
},
getSprNodeByUrl(url, cb) {
const node = new cc.Node();
const spr = node.addComponent(cc.Sprite);
this.getSpriteFrimeByUrl(url, (sf) => {
spr.spriteFrame = sf;
if (cb) {
cb(node);
}
})
},
playAudioByUrl(audio_url, cb = null) {
if (audio_url) {
cc.assetManager.loadRemote(audio_url, (err, audioClip) => {
const audioId = cc.audioEngine.play(audioClip, false, 0.8);
if (cb) {
cc.audioEngine.setFinishCallback(audioId, () => {
cb();
});
}
});
}
},
// ------------------------------------------
});
export const defaultData = {
"pic_url": "http://staging-teach.cdn.ireadabc.com/ed94332a503c31e0908bd4c6923a2665.png",
"pic_url_2": "http://staging-teach.cdn.ireadabc.com/5fb60317ade0195d35ad8034d5370a7f.png",
"text": "This is a test label.",
"audio_url": "http://staging-teach.cdn.ireadabc.com/f47f1d7b5c160fe1c59500d180346240.mp3"
}
\ No newline at end of file
This diff is collapsed.
{
"ver": "1.0.8",
"uuid": "b54300af-b8e5-4b4e-aa2f-9ac1cef7b598",
"isPlugin": true,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}
\ No newline at end of file
{
"ver": "2.3.5",
"uuid": "18d07592-51a9-421e-8972-0f67b68d29e1",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 144,
"height": 144,
"platformSettings": {},
"subMetas": {
"icon": {
"ver": "1.0.4",
"uuid": "6fbc30a8-3c49-44ae-8ba4-7f56f385b78a",
"rawTextureUuid": "18d07592-51a9-421e-8972-0f67b68d29e1",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": -0.5,
"trimX": 3,
"trimY": 2,
"width": 138,
"height": 141,
"rawWidth": 144,
"rawHeight": 144,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}
\ No newline at end of file
{
"ver": "2.0.1",
"uuid": "5f44c988-3569-413f-b9c3-42e3c60e3506",
"downloadMode": 0,
"duration": 1.575667,
"subMetas": {}
}
\ No newline at end of file
{
"ver": "2.0.1",
"uuid": "a7d0dac1-bbd1-4495-8e8d-8d08928a4f75",
"downloadMode": 0,
"duration": 0.556563,
"subMetas": {}
}
\ No newline at end of file
{
"ver": "2.0.1",
"uuid": "4c818237-b74e-46d0-9d13-ff5b648ad96f",
"downloadMode": 0,
"duration": 1.044898,
"subMetas": {}
}
\ No newline at end of file
{
"ver": "2.0.1",
"uuid": "c992521a-0464-46cf-8bfd-7eaedf06827d",
"downloadMode": 0,
"duration": 1.07102,
"subMetas": {}
}
\ No newline at end of file
This diff is collapsed.
{ {
"ver": "1.2.9", "ver": "1.2.7",
"uuid": "57ea7c61-9b8b-498a-b024-c98ee9124beb", "uuid": "57ea7c61-9b8b-498a-b024-c98ee9124beb",
"asyncLoadAssets": false, "asyncLoadAssets": false,
"autoReleaseAssets": true, "autoReleaseAssets": true,
......
This diff is collapsed.
...@@ -132,223 +132,3 @@ export function btnClickAnima(btn, time=0.15, rate=1.05) { ...@@ -132,223 +132,3 @@ export function btnClickAnima(btn, time=0.15, rate=1.05) {
.start() .start()
}) })
} }
export function getSpriteFrimeByUrl(url, cb) {
cc.loader.load({ url }, (err, img) => {
const spriteFrame = new cc.SpriteFrame(img)
if (cb) {
cb(spriteFrame);
}
})
}
export function getSprNode(resName) {
const sf = cc.find('Canvas/res/img/' + resName).getComponent(cc.Sprite).spriteFrame;
const node = new cc.Node();
node.addComponent(cc.Sprite).spriteFrame = sf;
return node;
}
export function getSprNodeByUrl(url, cb) {
const node = new cc.Node();
const spr = node.addComponent(cc.Sprite);
getSpriteFrimeByUrl(url, (sf) => {
spr.spriteFrame = sf;
if (cb) {
cb(spr);
}
})
}
export function playAudio(audioClip, cb = null) {
if (audioClip) {
const audioId = cc.audioEngine.playEffect(audioClip, false, 0.8);
if (cb) {
cc.audioEngine.setFinishCallback(audioId, () => {
cb();
});
}
}
}
export async function asyncDelay(time) {
return new Promise((resolve, reject) => {
try {
setTimeout(() => {
resolve();
}, time * 1000);
} catch (e) {
reject(e);
}
})
}
export class FireworkSettings {
baseNode; // 父节点
nodeList; // 火花节点的array
pos; // 发射点
side; // 发射方向
range; // 扩散范围
number; // 发射数量
scalseRange; // 缩放范围
constructor(baseNode, nodeList,
pos = cc.v2(0, 0),
side = cc.v2(0, 100),
range = 50,
number = 100,
scalseRange = 0
) {
this.baseNode = baseNode;
this.nodeList = nodeList;
this.pos = pos;
this.side = side;
this.range = range;
this.number = number;
this.scalseRange = scalseRange;
}
static copy(firework) {
return new FireworkSettings(
firework.baseNode,
firework.nodeList,
firework.pos,
firework.side,
firework.range,
firework.number,
);
}
}
export async function showFireworks(fireworkSettings) {
const { baseNode, nodeList, pos, side, range, number, scalseRange } = fireworkSettings;
new Array(number).fill(' ').forEach(async (_, i) => {
let rabbonNode = new cc.Node();
rabbonNode.parent = baseNode;
rabbonNode.x = pos.x;
rabbonNode.y = pos.y;
rabbonNode.angle = 60 * Math.random() - 30;
let node = cc.instantiate(nodeList[RandomInt(nodeList.length)]);
node.parent = rabbonNode;
node.active = true;
node.x = 0;
node.y = 0;
node.angle = 0;
node.scale = (Math.random() - 0.5) * scalseRange + 1;
const rate = Math.random();
const angle = Math.PI * (Math.random() * 2 - 1);
await asyncTweenBy(rabbonNode, 0.3, {
x: side.x * rate + Math.cos(angle) * range * rate,
y: side.y * rate + Math.sin(angle) * range * rate
}, {
easing: 'quadIn'
});
cc.tween(rabbonNode)
.by(8, { y: -2000 })
.start();
cc.tween(rabbonNode)
.to(5, { scale: (Math.random() - 0.5) * scalseRange + 1 })
.start();
rabbonFall(rabbonNode);
await asyncDelay(Math.random());
cc.tween(node)
.by(0.15, { x: -10, angle: -10 })
.by(0.3, { x: 20, angle: 20 })
.by(0.15, { x: -10, angle: -10 })
.union()
.repeatForever()
.start();
cc.tween(rabbonNode)
.delay(5)
.to(0.3, { opacity: 0 })
.call(() => {
node.stopAllActions();
node.active = false;
node.parent = null;
node = null;
})
.start();
});
}
async function rabbonFall(node) {
const time = 1 + Math.random();
const offsetX = RandomInt(-200, 200) * time;
await asyncTweenBy(node, time, { x: offsetX, angle: offsetX * 60 / 200 });
rabbonFall(node);
}
export async function asyncTweenTo(node, duration, obj, ease = undefined) {
return new Promise((resolve, reject) => {
try {
cc.tween(node)
.to(duration, obj, ease)
.call(() => {
resolve();
})
.start();
} catch (e) {
reject(e);
}
});
}
export async function asyncTweenBy(node, duration, obj, ease = undefined) {
return new Promise((resolve, reject) => {
try {
cc.tween(node)
.by(duration, obj, ease)
.call(() => {
resolve();
})
.start();
} catch (e) {
reject(e);
}
});
}
export function showTrebleFirework(baseNode, rabbonList) {
const middle = new FireworkSettings(baseNode, rabbonList);
middle.pos = cc.v2(0, -400);
middle.side = cc.v2(0, 1000);
middle.range = 200;
middle.number = 100;
middle.scalseRange = 0.4;
const left = FireworkSettings.copy(middle);
left.pos = cc.v2(-600, -400);
left.side = cc.v2(200, 1000);
const right = FireworkSettings.copy(middle);
right.pos = cc.v2(600, -400);
right.side = cc.v2(-200, 1000);
showFireworks(middle);
showFireworks(left);
showFireworks(right);
}
export function onHomeworkFinish() {
const middleLayer = cc.find('middleLayer');
if (middleLayer) {
const middleLayerComponent = middleLayer.getComponent('middleLayer');
if (middleLayerComponent.role == 'student') {
middleLayerComponent.onHomeworkFinish(() => { });
}
} else {
console.log('onHomeworkFinish');
}
}
\ No newline at end of file
This diff is collapsed.
{ {
"ver": "1.0.8", "ver": "1.0.8",
"uuid": "c41b0e51-55d7-443c-af3a-b22c3dd9b9e5", "uuid": "d545f402-231b-417e-99e6-3269412a5a2c",
"isPlugin": false, "isPlugin": false,
"loadPluginInWeb": true, "loadPluginInWeb": true,
"loadPluginInNative": true, "loadPluginInNative": true,
......
{
"ver": "1.1.0",
"uuid": "3d78532c-02ec-4ba2-8453-c83171eb39f5",
"subMetas": {}
}
\ No newline at end of file
{
"ver": "2.3.5",
"uuid": "8aa84c5f-aa0e-456d-aeed-4b3d799af2dd",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 1280,
"height": 388,
"platformSettings": {},
"subMetas": {
"bg_floor": {
"ver": "1.0.4",
"uuid": "129b0bf8-e9a1-4f43-b3c5-a8783dd27b44",
"rawTextureUuid": "8aa84c5f-aa0e-456d-aeed-4b3d799af2dd",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 1280,
"height": 388,
"rawWidth": 1280,
"rawHeight": 388,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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