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

feat: 初次提交

parent ce304201
......@@ -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 @@
"compressing": "^1.5.0",
"ng-zorro-antd": "^8.5.2",
"rxjs": "~6.5.4",
"node-sass": "^4.0.0",
"spark-md5": "^3.0.0",
"tslib": "^1.10.0",
"zone.js": "~0.10.2"
"zone.js": "~0.10.2",
"node-sass": "^4.0.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.900.3",
......@@ -55,4 +55,4 @@
"tslint": "~5.18.0",
"typescript": "~3.7.5"
}
}
\ No newline at end of file
}
......@@ -24,7 +24,6 @@ import {AudioRecorderComponent} from './common/audio-recorder/audio-recorder.com
import { FontAwesomeModule, FaIconLibrary } from '@fortawesome/angular-fontawesome';
import { fas } from '@fortawesome/free-solid-svg-icons';
import { far } from '@fortawesome/free-regular-svg-icons';
import { UploadDragonBoneComponent } from './common/upload-dragon-bone/upload-dragon-bone.component';
registerLocaleData(zh);
......@@ -41,7 +40,7 @@ registerLocaleData(zh);
TimePipe,
UploadVideoComponent,
CustomHotZoneComponent,
UploadDragonBoneComponent,
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,18 +7,19 @@
</div>
<div nz-row nzType="flex" nzAlign="middle">
<div nz-col nzSpan="5" nzOffset="1">
<h5> add background: </h5>
<div class="bg-box">
<app-upload-image-with-preview
[picUrl]="bgItem?.url"
[picUrl]="bgItem?.picUrl"
(imageUploaded)="onBackgroundUploadSuccess($event)">
</app-upload-image-with-preview>
</div>
</div>
<div nz-col nzSpan="5" nzOffset="1" class="img-box"
*ngFor="let it of hotZoneArr; let i = index">
......@@ -35,9 +36,12 @@
<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="isHasText" nz-radio nzValue="text">文本</label>
-->
</nz-radio-group>
</div>
......@@ -68,10 +72,10 @@
<div class="bg-box">
<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>
<!--Add Image-->
Add hot zone
添气泡
</button>
</div>
......
......@@ -10,12 +10,12 @@ import {
Output,
ViewChild
} from '@angular/core';
import {Subject} from 'rxjs';
import {debounceTime} from 'rxjs/operators';
import {EditorItem, HotZoneImg, HotZoneItem, HotZoneLabel, Label, MySprite, removeItemFromArr} from './Unit';
import { Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import { EditorItem, HotZoneImg, HotZoneItem, HotZoneLabel, Label, MySprite, removeItemFromArr } from './Unit';
import TWEEN from '@tweenjs/tween.js';
import {getMinScale} from "../../play/Unit";
import {tar} from "compressing";
import { getMinScale, ShapeRect } from "../../play/Unit";
import { tar } from "compressing";
@Component({
......@@ -34,8 +34,8 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
hotZoneArr = null;
@Output()
save = new EventEmitter();
@ViewChild('canvas', {static: true}) canvas: ElementRef;
@ViewChild('wrap', {static: true}) wrap: ElementRef;
@ViewChild('canvas', { static: true }) canvas: ElementRef;
@ViewChild('wrap', { static: true }) wrap: ElementRef;
@Input()
isHasRect = true;
......@@ -50,7 +50,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
color: '#8f3758'
}
@Input()
defaultItemType = 'text';
defaultItemType = 'pic';
@Input()
hotZoneImgSize = 190;
......@@ -129,7 +129,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
onBackgroundUploadSuccess(e) {
console.log('e: ', e);
this.bgItem.url = e.url;
this.bgItem.picUrl = e.url;
this.refreshBackground();
}
......@@ -145,20 +145,25 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
refreshBackground(callBack = null) {
if (!this.bg) {
this.bg = new MySprite(this.ctx);
this.renderArr.push(this.bg);
}
if (this.bgItem.picUrl) {
const bg = this.bg;
if (this.bgItem.url) {
if (!this.bg) {
this.bg = new MySprite(this.ctx);
this.renderArr.push(this.bg);
}
const bg = this.bg;
bg.load(this.bgItem.url).then(() => {
bg.load(this.bgItem.picUrl).then(() => {
const rate1 = this.canvasWidth / bg.width;
const rate2 = this.canvasHeight / bg.height;
const rate = Math.min(rate1, rate2);
bg.setScaleXY(rate);
//const rate = Math.max(rate1, rate2);
//bg.setScaleXY(rate);
bg.scaleX = rate1;
bg.scaleY = rate2;
bg.x = this.canvasWidth / 2;
......@@ -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 {
item.scaleY = saveRect.height / item.height;
item.x = saveRect.x + saveRect.width / 2;
item.y = saveRect.y + saveRect.height / 2;
}
item.showLineDash();
......@@ -382,25 +391,21 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
}
initItem() {
if (!this.bgItem) {
this.bgItem = {};
} else {
this.refreshBackground(() => {
// if (!this.imgItemArr) {
// this.imgItemArr = [];
// } else {
// this.initImgArr();
// }
// console.log('aaaaa');
if (!this.hotZoneItemArr) {
this.hotZoneItemArr = [];
} else {
this.initHotZoneArr();
}
});
}
......@@ -413,7 +418,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
if (this.bg) {
curBgRect = this.bg.getBoundingBox();
} else {
curBgRect = {x: 0, y: 0, width: this.canvasWidth, height: this.canvasHeight};
curBgRect = { x: 0, y: 0, width: this.canvasWidth, height: this.canvasHeight };
}
let oldBgRect = this.bgItem.rect;
......@@ -440,10 +445,6 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
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);
const item = this.getHotZoneItem(data);
item.audio_url = data.audio_url;
item.pic_url = data.pic_url;
......@@ -451,7 +452,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
item.itemType = data.itemType;
this.refreshItem(item);
console.log('item: ', item);
//console.log('item: ', item);
this.hotZoneArr.push(item);
}
......@@ -470,7 +471,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
if (this.bg) {
curBgRect = this.bg.getBoundingBox();
} else {
curBgRect = {x: 0, y: 0, width: this.canvasWidth, height: this.canvasHeight};
curBgRect = { x: 0, y: 0, width: this.canvasWidth, height: this.canvasHeight };
}
let oldBgRect = this.bgItem.rect;
......@@ -487,7 +488,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
for (let i = 0; i < arr.length; i++) {
const data = JSON.parse(JSON.stringify(arr[i]));
const img = {pic_url: data.pic_url};
const img = { pic_url: data.pic_url };
data.rect.x *= rate;
data.rect.y *= rate;
......@@ -510,6 +511,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
this.canvasWidth = this.wrap.nativeElement.clientWidth;
this.canvasHeight = this.wrap.nativeElement.clientHeight;
this.mapScale = this.canvasWidth / this.canvasBaseW;
this.renderArr = [];
this.bg = null;
......@@ -518,6 +520,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
}
initCtx() {
this.ctx = this.canvas.nativeElement.getContext('2d');
this.canvas.nativeElement.width = this.canvasWidth;
this.canvas.nativeElement.height = this.canvasHeight;
......@@ -526,7 +529,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
mapDown(event) {
this.oldPos = {x: this.mx, y: this.my};
this.oldPos = { x: this.mx, y: this.my };
for (let i = 0; i < this.hotZoneArr.length; i++) {
......@@ -580,7 +583,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
this.curItem.y += addY;
}
this.oldPos = {x: this.mx, y: this.my};
this.oldPos = { x: this.mx, y: this.my };
this.saveDisabled = true;
......@@ -880,7 +883,9 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
fontColor: this.hotZoneFontObj.color,
fontScale: hotZoneArr[i].textLabel ? hotZoneArr[i].textLabel.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'].x = Math.round((hotZoneItem['rect'].x - bgItem['rect'].x) * 100) / 100;
......@@ -888,13 +893,11 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
hotZoneItem['rect'].width = Math.round((hotZoneItem['rect'].width) * 100) / 100;
hotZoneItem['rect'].height = Math.round((hotZoneItem['rect'].height) * 100) / 100;
hotZoneItemArr.push(hotZoneItem);
}
console.log('hotZoneItemArr: ', hotZoneItemArr);
this.save.emit({bgItem, hotZoneItemArr});
this.save.emit({ bgItem, hotZoneItemArr });
}
private updatePos() {
......@@ -979,8 +982,8 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
private loadHotZonePic(pic: HotZoneImg, url) {
const baseLen = this.hotZoneImgSize * this.mapScale;
pic.load(url).then(() => {
const s = getMinScale(pic, baseLen);
pic.setScaleXY(s);
//const s = getMinScale(pic, baseLen);
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 style="padding: 10px;">
<div style="width: 300px;" align='center'>
<span>图1: </span>
<app-upload-image-with-preview
[picUrl]="item.pic_url"
(imageUploaded)="onImageUploadSuccess($event, 'pic_url')">
</app-upload-image-with-preview>
<div nz-row>
<div nz-col nzOffset='4'>
<h1 nz-title>课程练习内容编辑</h1>
</div>
</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 nz-row>
<div nz-col [nzSpan]="20" nzOffset="2">
<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>
</nz-form-control>
</nz-form-item>
-->
</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>
<nz-form-item>
<nz-form-label [nzSpan]="6">备选答案</nz-form-label>
<nz-form-control [nzSpan]="6">
<button nz-button nzType="dashed" class="add-btn" id="add-btn"
(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>
</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>
<!--龙骨面板-->
<nz-modal [(nzVisible)]="animaPanelVisible" nzTitle="配置资源文件" (nzOnCancel)="animaPanelCancel()" (nzOnOk)="animaPanelOk()" nzOkText="保存">
<div style="width: 300px; margin-top: 15px;">
<span>文本: </span>
<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 style="margin-top: 5px">
<span>音频: </span>
<app-audio-recorder
[audioUrl]="item.audio_url"
(audioUploaded)="onAudioUploadSuccess($event, 'audio_url')"
></app-audio-recorder>
<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>
<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>
\ No newline at end of file
import { Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, ApplicationRef, ChangeDetectorRef } from '@angular/core';
import { JsonPipe } from '@angular/common';
import { Answer, Backgroud, Frame, getDefaultExercises, getDefaultItem } from '../bean/ObjBean';
import {NzMessageService} from 'ng-zorro-antd';
@Component({
selector: 'app-form',
......@@ -10,32 +11,35 @@ import { JsonPipe } from '@angular/common';
export class FormComponent implements OnInit, OnChanges, OnDestroy {
// 储存数据用
saveKey = "test_001";
saveKey = "FT-01";
// 储存对象
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() {
this.item.wordList.push({
word: '',
audio: '',
backWord: '',
backWordAudio: '',
});
this.save();
}
constructor(private appRef: ApplicationRef, private changeDetectorRef: ChangeDetectorRef,private nzMessageService: NzMessageService) {
this.uploadUrl = (<any> window).courseware.uploadUrl();
this.uploadData = (<any> window).courseware.uploadData();
removeShell(idx) {
this.item.wordList.splice(idx, 1);
this.save();
window['air'].getUploadCallback = (url, data) => {
this.uploadUrl = url;
this.uploadData = data;
};
}
ngOnInit() {
this.item = {};
this.item = getDefaultItem();
// 获取存储的数据
(<any>window).courseware.getData((data) => {
......@@ -43,7 +47,7 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
if (data) {
this.item = data;
}
this.item.exercisesArr[0].hotZoneItemArr[0].picX= 0;
this.init();
this.changeDetectorRef.markForCheck();
this.changeDetectorRef.detectChanges();
......@@ -59,28 +63,37 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
}
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();
}
}
}
/**
* 储存图片数据
* @param e
*/
onImageUploadSuccess(e, key) {
* 储存图片数据
* @param e
*/
onImageUploadSuccess(e, item, key) {
this.item[key] = e.url;
this.save();
}
item[key] = e.url;
this.save();
}
/**
* 储存音频数据
* @param e
*/
onAudioUploadSuccess(e, key) {
this.item[key] = e.url;
this.save();
}
/**
* 储存音频数据
* @param e
*/
onAudioUploadSuccess(e, item, key) {
item[key] = e.url;
this.save();
}
onWordAudioUploadSuccess(e, idx) {
this.item.wordList[idx].audio = e.url;
......@@ -111,4 +124,168 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
}, 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 source diff could not be displayed because it is too large. You can view the blob instead.
[
{
"__type__": "cc.SceneAsset",
"_name": "",
"_objFlags": 0,
"_native": "",
"scene": {
"__id__": 1
}
},
{
"__type__": "cc.Scene",
"_objFlags": 0,
"_parent": null,
"_children": [
{
"__id__": 2
}
],
"_active": false,
"_components": [],
"_prefab": null,
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 0,
"height": 0
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
0,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_is3DNode": true,
"_groupIndex": 0,
"groupIndex": 0,
"autoReleaseAssets": true,
"_id": "57ea7c61-9b8b-498a-b024-c98ee9124beb"
},
{
"__type__": "cc.Node",
"_name": "Canvas",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_children": [
{
"__id__": 3
},
{
"__id__": 5
},
{
"__id__": 7
},
{
"__id__": 14
}
],
"_active": true,
"_components": [
{
"__id__": 24
},
{
"__id__": 25
},
{
"__id__": 26
}
],
"_prefab": null,
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 1280,
"height": 720
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
640,
360,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "a5esZu+45LA5mBpvttspPD"
},
{
"__type__": "cc.Node",
"_name": "Main Camera",
"_objFlags": 0,
"_parent": {
"__id__": 2
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 4
}
],
"_prefab": null,
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 1280,
"height": 720
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
0,
362.85545494732423,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "e1WoFrQ79G7r4ZuQE3HlNb"
},
{
"__type__": "cc.Camera",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 3
},
"_enabled": true,
"_cullingMask": 4294967295,
"_clearFlags": 7,
"_backgroundColor": {
"__type__": "cc.Color",
"r": 0,
"g": 0,
"b": 0,
"a": 255
},
"_depth": -1,
"_zoomRatio": 1,
"_targetTexture": null,
"_fov": 60,
"_orthoSize": 10,
"_nearClip": 1,
"_farClip": 4096,
"_ortho": true,
"_rect": {
"__type__": "cc.Rect",
"x": 0,
"y": 0,
"width": 1,
"height": 1
},
"_renderStages": 1,
"_alignWithScreen": true,
"_id": "81GN3uXINKVLeW4+iKSlim"
},
{
"__type__": "cc.Node",
"_name": "bg",
"_objFlags": 0,
"_parent": {
"__id__": 2
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 6
}
],
"_prefab": null,
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 1280,
"height": 720
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
0,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "32MJMZ2HRGF4BOf533Avyi"
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 5
},
"_enabled": true,
"_materials": [
{
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
}
],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_spriteFrame": {
"__uuid__": "8288e3d4-4c75-4b27-8f01-f7014417f4dd"
},
"_type": 0,
"_sizeMode": 1,
"_fillType": 0,
"_fillCenter": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_atlas": null,
"_id": "97/S6HDq9MeqgmV1Zwnhbb"
},
{
"__type__": "cc.Node",
"_name": "bottomPart",
"_objFlags": 0,
"_parent": {
"__id__": 2
},
"_children": [
{
"__id__": 8
},
{
"__id__": 11
}
],
"_active": true,
"_components": [],
"_prefab": null,
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 0,
"height": 0
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
635.132,
-356.326,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "8c7k8ep/ZFNpO263+1QHz9"
},
{
"__type__": "cc.Node",
"_name": "btn_left",
"_objFlags": 0,
"_parent": {
"__id__": 7
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 9
},
{
"__id__": 10
}
],
"_prefab": null,
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 61,
"height": 67
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
-148.464,
34,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "5ad2wLQLxIN5Eg7OHecSH6"
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 8
},
"_enabled": true,
"_materials": [
{
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
}
],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_spriteFrame": {
"__uuid__": "ce19457d-e8f3-4c38-ae3e-d4b99208ddb5"
},
"_type": 0,
"_sizeMode": 1,
"_fillType": 0,
"_fillCenter": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_atlas": null,
"_id": "84mqOgJ3JNqZrYVTEU8CjE"
},
{
"__type__": "cc.Button",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 8
},
"_enabled": true,
"_normalMaterial": null,
"_grayMaterial": null,
"duration": 0.1,
"zoomScale": 1.2,
"clickEvents": [],
"_N$interactable": true,
"_N$enableAutoGrayEffect": false,
"_N$transition": 0,
"transition": 0,
"_N$normalColor": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_N$pressedColor": {
"__type__": "cc.Color",
"r": 211,
"g": 211,
"b": 211,
"a": 255
},
"pressedColor": {
"__type__": "cc.Color",
"r": 211,
"g": 211,
"b": 211,
"a": 255
},
"_N$hoverColor": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"hoverColor": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_N$disabledColor": {
"__type__": "cc.Color",
"r": 124,
"g": 124,
"b": 124,
"a": 255
},
"_N$normalSprite": null,
"_N$pressedSprite": null,
"pressedSprite": null,
"_N$hoverSprite": null,
"hoverSprite": null,
"_N$disabledSprite": null,
"_N$target": null,
"_id": "bcYN/4EKBJhbIAfovo9Ah1"
},
{
"__type__": "cc.Node",
"_name": "btn_right",
"_objFlags": 0,
"_parent": {
"__id__": 7
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 12
},
{
"__id__": 13
}
],
"_prefab": null,
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 60,
"height": 66
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
-47.164,
34,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "46i3stdzpHX6zQHTGnRsNE"
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 11
},
"_enabled": true,
"_materials": [
{
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
}
],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_spriteFrame": {
"__uuid__": "e5a2dbaa-a677-4a32-90d7-a1b057d7fb59"
},
"_type": 0,
"_sizeMode": 1,
"_fillType": 0,
"_fillCenter": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_atlas": null,
"_id": "42Sh8QS/BHn4WiGyPQPKPt"
},
{
"__type__": "cc.Button",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 11
},
"_enabled": true,
"_normalMaterial": null,
"_grayMaterial": null,
"duration": 0.1,
"zoomScale": 1.2,
"clickEvents": [],
"_N$interactable": true,
"_N$enableAutoGrayEffect": false,
"_N$transition": 0,
"transition": 0,
"_N$normalColor": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_N$pressedColor": {
"__type__": "cc.Color",
"r": 211,
"g": 211,
"b": 211,
"a": 255
},
"pressedColor": {
"__type__": "cc.Color",
"r": 211,
"g": 211,
"b": 211,
"a": 255
},
"_N$hoverColor": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"hoverColor": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_N$disabledColor": {
"__type__": "cc.Color",
"r": 124,
"g": 124,
"b": 124,
"a": 255
},
"_N$normalSprite": null,
"_N$pressedSprite": null,
"pressedSprite": null,
"_N$hoverSprite": null,
"hoverSprite": null,
"_N$disabledSprite": null,
"_N$target": null,
"_id": "1aj32fYY1IxLesa77E70Qu"
},
{
"__type__": "cc.Node",
"_name": "res",
"_objFlags": 0,
"_parent": {
"__id__": 2
},
"_children": [
{
"__id__": 15
},
{
"__id__": 18
},
{
"__id__": 21
}
],
"_active": false,
"_components": [],
"_prefab": null,
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 0,
"height": 0
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
0,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "0aAzbH6R1E+6AmGRrkKa5O"
},
{
"__type__": "cc.Node",
"_name": "font",
"_objFlags": 0,
"_parent": {
"__id__": 14
},
"_children": [
{
"__id__": 16
}
],
"_active": true,
"_components": [],
"_prefab": null,
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 0,
"height": 0
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
0,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "9bLfcYeeNKrr524vzWchiM"
},
{
"__type__": "cc.Node",
"_name": "BRLNSDB",
"_objFlags": 0,
"_parent": {
"__id__": 15
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 17
}
],
"_prefab": null,
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 0,
"height": 0
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
0,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "cfMLGsq0BMhJARv+ySMAxS"
},
{
"__type__": "cc.Label",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 16
},
"_enabled": true,
"_materials": [],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_string": "",
"_N$string": "",
"_fontSize": 40,
"_lineHeight": 40,
"_enableWrapText": true,
"_N$file": {
"__uuid__": "c551970e-b095-45f3-9f1d-25cde8b8deb1"
},
"_isSystemFontUsed": false,
"_spacingX": 0,
"_batchAsBitmap": false,
"_styleFlags": 0,
"_underlineHeight": 0,
"_N$horizontalAlign": 0,
"_N$verticalAlign": 0,
"_N$fontFamily": "Arial",
"_N$overflow": 0,
"_N$cacheMode": 0,
"_id": "9bNHNPu5lC7rQYyr8ai/sY"
},
{
"__type__": "cc.Node",
"_name": "img",
"_objFlags": 0,
"_parent": {
"__id__": 14
},
"_children": [
{
"__id__": 19
}
],
"_active": true,
"_components": [],
"_prefab": null,
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 0,
"height": 0
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
0,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "53LUHHG2pEr79fyrvazXJs"
},
{
"__type__": "cc.Node",
"_name": "icon",
"_objFlags": 0,
"_parent": {
"__id__": 18
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 20
}
],
"_prefab": null,
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 138,
"height": 141
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
0,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "1blU2OArJIfoC9XfupGxJG"
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 19
},
"_enabled": true,
"_materials": [],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_spriteFrame": {
"__uuid__": "6fbc30a8-3c49-44ae-8ba4-7f56f385b78a"
},
"_type": 0,
"_sizeMode": 1,
"_fillType": 0,
"_fillCenter": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_atlas": null,
"_id": "03GEWUEZJGyKormWgIWCtM"
},
{
"__type__": "cc.Node",
"_name": "audio",
"_objFlags": 0,
"_parent": {
"__id__": 14
},
"_children": [
{
"__id__": 22
}
],
"_active": true,
"_components": [],
"_prefab": null,
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 0,
"height": 0
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
0,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "b823DIVC9L+Ihc3T9Bt7m3"
},
{
"__type__": "cc.Node",
"_name": "btn",
"_objFlags": 0,
"_parent": {
"__id__": 21
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 23
}
],
"_prefab": null,
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 0,
"height": 0
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
0,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "3d0p0/uJZJIoRva5Br2iqv"
},
{
"__type__": "cc.AudioSource",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 22
},
"_enabled": true,
"_clip": {
"__uuid__": "f0680ae0-c079-45ef-abd7-9e63d90b982b"
},
"_volume": 1,
"_mute": false,
"_loop": false,
"_firstlyEnabled": true,
"playOnLoad": false,
"preload": false,
"_id": "0adN50f61DlbmppsPkOnjX"
},
{
"__type__": "cc.Canvas",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 2
},
"_enabled": true,
"_designResolution": {
"__type__": "cc.Size",
"width": 1280,
"height": 720
},
"_fitWidth": false,
"_fitHeight": false,
"_id": "59Cd0ovbdF4byw5sbjJDx7"
},
{
"__type__": "cc.Widget",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 2
},
"_enabled": true,
"alignMode": 1,
"_target": null,
"_alignFlags": 45,
"_left": 0,
"_right": 0,
"_top": 0,
"_bottom": 0,
"_verticalCenter": 0,
"_horizontalCenter": 0,
"_isAbsLeft": true,
"_isAbsRight": true,
"_isAbsTop": true,
"_isAbsBottom": true,
"_isAbsHorizontalCenter": true,
"_isAbsVerticalCenter": true,
"_originalWidth": 0,
"_originalHeight": 0,
"_id": "29zXboiXFBKoIV4PQ2liTe"
},
{
"__type__": "f4edeRi+NdAabqAkVYRwFjK",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 2
},
"_enabled": true,
"_id": "e687yyoRBIzZAOVRL8Sseh"
}
]
\ No newline at end of file
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
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
cc.sys.capabilities["touches"] = true;
!(function (global) {
"use strict";
var Op = Object.prototype;
var hasOwn = Op.hasOwnProperty;
var undefined; // More compressible than void 0.
var $Symbol = typeof Symbol === "function" ? Symbol : {};
var iteratorSymbol = $Symbol.iterator || "@@iterator";
var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
var inModule = typeof module === "object";
var runtime = global.regeneratorRuntime;
if (runtime) {
if (inModule) {
// If regeneratorRuntime is defined globally and we're in a module,
// make the exports object identical to regeneratorRuntime.
module.exports = runtime;
}
// Don't bother evaluating the rest of this file if the runtime was
// already defined globally.
return;
}
// Define the runtime globally (as expected by generated code) as either
// module.exports (if we're in a module) or a new, empty object.
runtime = global.regeneratorRuntime = inModule ? module.exports : {};
function wrap(innerFn, outerFn, self, tryLocsList) {
// If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
var generator = Object.create(protoGenerator.prototype);
var context = new Context(tryLocsList || []);
// The ._invoke method unifies the implementations of the .next,
// .throw, and .return methods.
generator._invoke = makeInvokeMethod(innerFn, self, context);
return generator;
}
runtime.wrap = wrap;
// Try/catch helper to minimize deoptimizations. Returns a completion
// record like context.tryEntries[i].completion. This interface could
// have been (and was previously) designed to take a closure to be
// invoked without arguments, but in all the cases we care about we
// already have an existing method we want to call, so there's no need
// to create a new function object. We can even get away with assuming
// the method takes exactly one argument, since that happens to be true
// in every case, so we don't have to touch the arguments object. The
// only additional allocation required is the completion record, which
// has a stable shape and so hopefully should be cheap to allocate.
function tryCatch(fn, obj, arg) {
try {
return { type: "normal", arg: fn.call(obj, arg) };
} catch (err) {
return { type: "throw", arg: err };
}
}
var GenStateSuspendedStart = "suspendedStart";
var GenStateSuspendedYield = "suspendedYield";
var GenStateExecuting = "executing";
var GenStateCompleted = "completed";
// Returning this object from the innerFn has the same effect as
// breaking out of the dispatch switch statement.
var ContinueSentinel = {};
// Dummy constructor functions that we use as the .constructor and
// .constructor.prototype properties for functions that return Generator
// objects. For full spec compliance, you may wish to configure your
// minifier not to mangle the names of these two functions.
function Generator() { }
function GeneratorFunction() { }
function GeneratorFunctionPrototype() { }
// This is a polyfill for %IteratorPrototype% for environments that
// don't natively support it.
var IteratorPrototype = {};
IteratorPrototype[iteratorSymbol] = function () {
return this;
};
var getProto = Object.getPrototypeOf;
var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
if (NativeIteratorPrototype &&
NativeIteratorPrototype !== Op &&
hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
// This environment has a native %IteratorPrototype%; use it instead
// of the polyfill.
IteratorPrototype = NativeIteratorPrototype;
}
var Gp = GeneratorFunctionPrototype.prototype =
Generator.prototype = Object.create(IteratorPrototype);
GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
GeneratorFunctionPrototype.constructor = GeneratorFunction;
GeneratorFunctionPrototype[toStringTagSymbol] =
GeneratorFunction.displayName = "GeneratorFunction";
// Helper for defining the .next, .throw, and .return methods of the
// Iterator interface in terms of a single ._invoke method.
function defineIteratorMethods(prototype) {
["next", "throw", "return"].forEach(function (method) {
prototype[method] = function (arg) {
return this._invoke(method, arg);
};
});
}
runtime.isGeneratorFunction = function (genFun) {
var ctor = typeof genFun === "function" && genFun.constructor;
return ctor
? ctor === GeneratorFunction ||
// For the native GeneratorFunction constructor, the best we can
// do is to check its .name property.
(ctor.displayName || ctor.name) === "GeneratorFunction"
: false;
};
runtime.mark = function (genFun) {
if (Object.setPrototypeOf) {
Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
} else {
genFun.__proto__ = GeneratorFunctionPrototype;
if (!(toStringTagSymbol in genFun)) {
genFun[toStringTagSymbol] = "GeneratorFunction";
}
}
genFun.prototype = Object.create(Gp);
return genFun;
};
// Within the body of any async function, `await x` is transformed to
// `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
// `hasOwn.call(value, "__await")` to determine if the yielded value is
// meant to be awaited.
runtime.awrap = function (arg) {
return { __await: arg };
};
function AsyncIterator(generator) {
function invoke(method, arg, resolve, reject) {
var record = tryCatch(generator[method], generator, arg);
if (record.type === "throw") {
reject(record.arg);
} else {
var result = record.arg;
var value = result.value;
if (value &&
typeof value === "object" &&
hasOwn.call(value, "__await")) {
return Promise.resolve(value.__await).then(function (value) {
invoke("next", value, resolve, reject);
}, function (err) {
invoke("throw", err, resolve, reject);
});
}
return Promise.resolve(value).then(function (unwrapped) {
// When a yielded Promise is resolved, its final value becomes
// the .value of the Promise<{value,done}> result for the
// current iteration. If the Promise is rejected, however, the
// result for this iteration will be rejected with the same
// reason. Note that rejections of yielded Promises are not
// thrown back into the generator function, as is the case
// when an awaited Promise is rejected. This difference in
// behavior between yield and await is important, because it
// allows the consumer to decide what to do with the yielded
// rejection (swallow it and continue, manually .throw it back
// into the generator, abandon iteration, whatever). With
// await, by contrast, there is no opportunity to examine the
// rejection reason outside the generator function, so the
// only option is to throw it from the await expression, and
// let the generator function handle the exception.
result.value = unwrapped;
resolve(result);
}, reject);
}
}
var previousPromise;
function enqueue(method, arg) {
function callInvokeWithMethodAndArg() {
return new Promise(function (resolve, reject) {
invoke(method, arg, resolve, reject);
});
}
return previousPromise =
// If enqueue has been called before, then we want to wait until
// all previous Promises have been resolved before calling invoke,
// so that results are always delivered in the correct order. If
// enqueue has not been called before, then it is important to
// call invoke immediately, without waiting on a callback to fire,
// so that the async generator function has the opportunity to do
// any necessary setup in a predictable way. This predictability
// is why the Promise constructor synchronously invokes its
// executor callback, and why async functions synchronously
// execute code before the first await. Since we implement simple
// async functions in terms of async generators, it is especially
// important to get this right, even though it requires care.
previousPromise ? previousPromise.then(
callInvokeWithMethodAndArg,
// Avoid propagating failures to Promises returned by later
// invocations of the iterator.
callInvokeWithMethodAndArg
) : callInvokeWithMethodAndArg();
}
// Define the unified helper method that is used to implement .next,
// .throw, and .return (see defineIteratorMethods).
this._invoke = enqueue;
}
defineIteratorMethods(AsyncIterator.prototype);
AsyncIterator.prototype[asyncIteratorSymbol] = function () {
return this;
};
runtime.AsyncIterator = AsyncIterator;
// Note that simple async functions are implemented on top of
// AsyncIterator objects; they just return a Promise for the value of
// the final result produced by the iterator.
runtime.async = function (innerFn, outerFn, self, tryLocsList) {
var iter = new AsyncIterator(
wrap(innerFn, outerFn, self, tryLocsList)
);
return runtime.isGeneratorFunction(outerFn)
? iter // If outerFn is a generator, return the full iterator.
: iter.next().then(function (result) {
return result.done ? result.value : iter.next();
});
};
function makeInvokeMethod(innerFn, self, context) {
var state = GenStateSuspendedStart;
return function invoke(method, arg) {
if (state === GenStateExecuting) {
throw new Error("Generator is already running");
}
if (state === GenStateCompleted) {
if (method === "throw") {
throw arg;
}
// Be forgiving, per 25.3.3.3.3 of the spec:
// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
return doneResult();
}
context.method = method;
context.arg = arg;
while (true) {
var delegate = context.delegate;
if (delegate) {
var delegateResult = maybeInvokeDelegate(delegate, context);
if (delegateResult) {
if (delegateResult === ContinueSentinel) continue;
return delegateResult;
}
}
if (context.method === "next") {
// Setting context._sent for legacy support of Babel's
// function.sent implementation.
context.sent = context._sent = context.arg;
} else if (context.method === "throw") {
if (state === GenStateSuspendedStart) {
state = GenStateCompleted;
throw context.arg;
}
context.dispatchException(context.arg);
} else if (context.method === "return") {
context.abrupt("return", context.arg);
}
state = GenStateExecuting;
var record = tryCatch(innerFn, self, context);
if (record.type === "normal") {
// If an exception is thrown from innerFn, we leave state ===
// GenStateExecuting and loop back for another invocation.
state = context.done
? GenStateCompleted
: GenStateSuspendedYield;
if (record.arg === ContinueSentinel) {
continue;
}
return {
value: record.arg,
done: context.done
};
} else if (record.type === "throw") {
state = GenStateCompleted;
// Dispatch the exception by looping back around to the
// context.dispatchException(context.arg) call above.
context.method = "throw";
context.arg = record.arg;
}
}
};
}
// Call delegate.iterator[context.method](context.arg) and handle the
// result, either by returning a { value, done } result from the
// delegate iterator, or by modifying context.method and context.arg,
// setting context.delegate to null, and returning the ContinueSentinel.
function maybeInvokeDelegate(delegate, context) {
var method = delegate.iterator[context.method];
if (method === undefined) {
// A .throw or .return when the delegate iterator has no .throw
// method always terminates the yield* loop.
context.delegate = null;
if (context.method === "throw") {
if (delegate.iterator.return) {
// If the delegate iterator has a return method, give it a
// chance to clean up.
context.method = "return";
context.arg = undefined;
maybeInvokeDelegate(delegate, context);
if (context.method === "throw") {
// If maybeInvokeDelegate(context) changed context.method from
// "return" to "throw", let that override the TypeError below.
return ContinueSentinel;
}
}
context.method = "throw";
context.arg = new TypeError(
"The iterator does not provide a 'throw' method");
}
return ContinueSentinel;
}
var record = tryCatch(method, delegate.iterator, context.arg);
if (record.type === "throw") {
context.method = "throw";
context.arg = record.arg;
context.delegate = null;
return ContinueSentinel;
}
var info = record.arg;
if (!info) {
context.method = "throw";
context.arg = new TypeError("iterator result is not an object");
context.delegate = null;
return ContinueSentinel;
}
if (info.done) {
// Assign the result of the finished delegate to the temporary
// variable specified by delegate.resultName (see delegateYield).
context[delegate.resultName] = info.value;
// Resume execution at the desired location (see delegateYield).
context.next = delegate.nextLoc;
// If context.method was "throw" but the delegate handled the
// exception, let the outer generator proceed normally. If
// context.method was "next", forget context.arg since it has been
// "consumed" by the delegate iterator. If context.method was
// "return", allow the original .return call to continue in the
// outer generator.
if (context.method !== "return") {
context.method = "next";
context.arg = undefined;
}
} else {
// Re-yield the result returned by the delegate method.
return info;
}
// The delegate iterator is finished, so forget it and continue with
// the outer generator.
context.delegate = null;
return ContinueSentinel;
}
// Define Generator.prototype.{next,throw,return} in terms of the
// unified ._invoke helper method.
defineIteratorMethods(Gp);
Gp[toStringTagSymbol] = "Generator";
// A Generator should always return itself as the iterator object when the
// @@iterator function is called on it. Some browsers' implementations of the
// iterator prototype chain incorrectly implement this, causing the Generator
// object to not be returned from this call. This ensures that doesn't happen.
// See https://github.com/facebook/regenerator/issues/274 for more details.
Gp[iteratorSymbol] = function () {
return this;
};
Gp.toString = function () {
return "[object Generator]";
};
function pushTryEntry(locs) {
var entry = { tryLoc: locs[0] };
if (1 in locs) {
entry.catchLoc = locs[1];
}
if (2 in locs) {
entry.finallyLoc = locs[2];
entry.afterLoc = locs[3];
}
this.tryEntries.push(entry);
}
function resetTryEntry(entry) {
var record = entry.completion || {};
record.type = "normal";
delete record.arg;
entry.completion = record;
}
function Context(tryLocsList) {
// The root entry object (effectively a try statement without a catch
// or a finally block) gives us a place to store values thrown from
// locations where there is no enclosing try statement.
this.tryEntries = [{ tryLoc: "root" }];
tryLocsList.forEach(pushTryEntry, this);
this.reset(true);
}
runtime.keys = function (object) {
var keys = [];
for (var key in object) {
keys.push(key);
}
keys.reverse();
// Rather than returning an object with a next method, we keep
// things simple and return the next function itself.
return function next() {
while (keys.length) {
var key = keys.pop();
if (key in object) {
next.value = key;
next.done = false;
return next;
}
}
// To avoid creating an additional object, we just hang the .value
// and .done properties off the next function object itself. This
// also ensures that the minifier will not anonymize the function.
next.done = true;
return next;
};
};
function values(iterable) {
if (iterable) {
var iteratorMethod = iterable[iteratorSymbol];
if (iteratorMethod) {
return iteratorMethod.call(iterable);
}
if (typeof iterable.next === "function") {
return iterable;
}
if (!isNaN(iterable.length)) {
var i = -1, next = function next() {
while (++i < iterable.length) {
if (hasOwn.call(iterable, i)) {
next.value = iterable[i];
next.done = false;
return next;
}
}
next.value = undefined;
next.done = true;
return next;
};
return next.next = next;
}
}
// Return an iterator with no values.
return { next: doneResult };
}
runtime.values = values;
function doneResult() {
return { value: undefined, done: true };
}
Context.prototype = {
constructor: Context,
reset: function (skipTempReset) {
this.prev = 0;
this.next = 0;
// Resetting context._sent for legacy support of Babel's
// function.sent implementation.
this.sent = this._sent = undefined;
this.done = false;
this.delegate = null;
this.method = "next";
this.arg = undefined;
this.tryEntries.forEach(resetTryEntry);
if (!skipTempReset) {
for (var name in this) {
// Not sure about the optimal order of these conditions:
if (name.charAt(0) === "t" &&
hasOwn.call(this, name) &&
!isNaN(+name.slice(1))) {
this[name] = undefined;
}
}
}
},
stop: function () {
this.done = true;
var rootEntry = this.tryEntries[0];
var rootRecord = rootEntry.completion;
if (rootRecord.type === "throw") {
throw rootRecord.arg;
}
return this.rval;
},
dispatchException: function (exception) {
if (this.done) {
throw exception;
}
var context = this;
function handle(loc, caught) {
record.type = "throw";
record.arg = exception;
context.next = loc;
if (caught) {
// If the dispatched exception was caught by a catch block,
// then let that catch block handle the exception normally.
context.method = "next";
context.arg = undefined;
}
return !!caught;
}
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
var entry = this.tryEntries[i];
var record = entry.completion;
if (entry.tryLoc === "root") {
// Exception thrown outside of any try block that could handle
// it, so set the completion value of the entire function to
// throw the exception.
return handle("end");
}
if (entry.tryLoc <= this.prev) {
var hasCatch = hasOwn.call(entry, "catchLoc");
var hasFinally = hasOwn.call(entry, "finallyLoc");
if (hasCatch && hasFinally) {
if (this.prev < entry.catchLoc) {
return handle(entry.catchLoc, true);
} else if (this.prev < entry.finallyLoc) {
return handle(entry.finallyLoc);
}
} else if (hasCatch) {
if (this.prev < entry.catchLoc) {
return handle(entry.catchLoc, true);
}
} else if (hasFinally) {
if (this.prev < entry.finallyLoc) {
return handle(entry.finallyLoc);
}
} else {
throw new Error("try statement without catch or finally");
}
}
}
},
abrupt: function (type, arg) {
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
var entry = this.tryEntries[i];
if (entry.tryLoc <= this.prev &&
hasOwn.call(entry, "finallyLoc") &&
this.prev < entry.finallyLoc) {
var finallyEntry = entry;
break;
}
}
if (finallyEntry &&
(type === "break" ||
type === "continue") &&
finallyEntry.tryLoc <= arg &&
arg <= finallyEntry.finallyLoc) {
// Ignore the finally entry if control is not jumping to a
// location outside the try/catch block.
finallyEntry = null;
}
var record = finallyEntry ? finallyEntry.completion : {};
record.type = type;
record.arg = arg;
if (finallyEntry) {
this.method = "next";
this.next = finallyEntry.finallyLoc;
return ContinueSentinel;
}
return this.complete(record);
},
complete: function (record, afterLoc) {
if (record.type === "throw") {
throw record.arg;
}
if (record.type === "break" ||
record.type === "continue") {
this.next = record.arg;
} else if (record.type === "return") {
this.rval = this.arg = record.arg;
this.method = "return";
this.next = "end";
} else if (record.type === "normal" && afterLoc) {
this.next = afterLoc;
}
return ContinueSentinel;
},
finish: function (finallyLoc) {
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
var entry = this.tryEntries[i];
if (entry.finallyLoc === finallyLoc) {
this.complete(entry.completion, entry.afterLoc);
resetTryEntry(entry);
return ContinueSentinel;
}
}
},
"catch": function (tryLoc) {
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
var entry = this.tryEntries[i];
if (entry.tryLoc === tryLoc) {
var record = entry.completion;
if (record.type === "throw") {
var thrown = record.arg;
resetTryEntry(entry);
}
return thrown;
}
}
// The context.catch method must only be called with a location
// argument that corresponds to a known catch block.
throw new Error("illegal catch attempt");
},
delegateYield: function (iterable, resultName, nextLoc) {
this.delegate = {
iterator: values(iterable),
resultName: resultName,
nextLoc: nextLoc
};
if (this.method === "next") {
// Deliberately forget the last sent value so that we don't
// accidentally pass it on to the delegate.
this.arg = undefined;
}
return ContinueSentinel;
}
};
})(
// In sloppy mode, unbound `this` refers to the global object, fallback to
// Function constructor if we're in global strict mode. That is sadly a form
// of indirect eval which violates Content Security Policy.
(function () { return this })() || Function("return this")()
);
{
"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 source diff could not be displayed because it is too large. You can view the blob instead.
{
"ver": "1.2.9",
"ver": "1.2.7",
"uuid": "57ea7c61-9b8b-498a-b024-c98ee9124beb",
"asyncLoadAssets": false,
"autoReleaseAssets": true,
......
// Learn cc.Class:
// - https://docs.cocos.com/creator/manual/en/scripting/class.html
// Learn Attribute:
// - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
// - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html
import { setSprNodeMaxLen, btnClickAnima } from "./util";
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(cb) {
cb(this.getDefaultData());
},
getDefaultData() {
const dataJson = '{"exercisesArr":[{"answers":[{"isRight":"1","audioUrl":"http://staging-teach.cdn.ireadabc.com/f95fd3997cdd67abd51a1ab45efd855d.mp3","picUrl":"http://staging-teach.cdn.ireadabc.com/10dab2d49188db958a6a6e6b3ab7b5f5.png"},{"isRight":"0","picUrl":"http://staging-teach.cdn.ireadabc.com/cb6a2f948c3febbb7881e6b6a7417811.png","audioUrl":"http://staging-teach.cdn.ireadabc.com/b44fa51172b19b555fda30717c773027.mp3"},{"isRight":"0","picUrl":"http://staging-teach.cdn.ireadabc.com/a886b150e8792d433ced3672f4df7dfb.jpg","audioUrl":"http://staging-teach.cdn.ireadabc.com/b62600fd1e72b54d1d1c3bc71b7361af.mp3"}],"frames":[{"picUrl":"http://staging-teach.cdn.ireadabc.com/824c94f5e363c351e24dde9325731ab7.png"},{"picUrl":"http://staging-teach.cdn.ireadabc.com/95638e0ab356b51f960e800e3fa5aacb.png"},{"picUrl":"http://staging-teach.cdn.ireadabc.com/3d330a49df81ae964a705048f8ea0e0d.png"},{"picUrl":"http://staging-teach.cdn.ireadabc.com/3023da8f58edfa36a0a9c34e68902ef7.png"}],"hotZoneItemArr":[{"index":0,"pic_url":"http://staging-teach.cdn.ireadabc.com/28c3a876b5d0bbbb43f1b118bbe40df6.png","audio_url":"http://staging-teach.cdn.ireadabc.com/afdd23cc154d515a3afff15ccc775502.mp3","itemType":"pic","fontSize":50,"fontName":"BRLNSR_1","fontColor":"#8f3758","fontScale":0.9,"imgScale":0.5089285714285714,"mapScale":0.9,"picX":0,"picY":168.00142857142856,"rect":{"x":779,"y":146.19,"width":200,"height":200}}],"skeJsonData":{"url":"http://staging-teach.cdn.ireadabc.com/d74f4a1fff340bf4cf02101d5bfda7e8.json","name":"女孩_ske.json"},"texJsonData":{"url":"http://staging-teach.cdn.ireadabc.com/66d2f8e8c531a4a8583e5faf2cf35e41.json","name":"女孩_tex.json"},"texPngData":{"url":"http://staging-teach.cdn.ireadabc.com/546d11d5c1abbe2a0e442fe4816718b7.png","name":"女孩_tex.png"},"bg":{"rect":{"x":0,"y":-78.18857142857144,"width":1152,"height":690.3771428571429}}},{"answers":[{"isRight":"0","audioUrl":"http://staging-teach.cdn.ireadabc.com/b62600fd1e72b54d1d1c3bc71b7361af.mp3","picUrl":"http://staging-teach.cdn.ireadabc.com/cb6dfd436c533f44e8e9fdd594458576.png"},{"isRight":"1","audioUrl":"http://staging-teach.cdn.ireadabc.com/8b5ecca5d4509e1b8a7e81e69d8db615.mp3","picUrl":"http://staging-teach.cdn.ireadabc.com/b2b296923e5fd09e77cd29fd3883f78e.png"},{"isRight":"0","picUrl":"http://staging-teach.cdn.ireadabc.com/3fed3a7bacc07dfb84de7196a50d39ab.png","audioUrl":"http://staging-teach.cdn.ireadabc.com/919b2c150b41b3306869ebe78ecb70b3.mp3"},{"picUrl":"http://staging-teach.cdn.ireadabc.com/9f9361601b4f2dbd60f037c6996a5af6.png","isRight":"0","audioUrl":"http://staging-teach.cdn.ireadabc.com/a252c069d04f8e04f91b2a1394072f30.mp3"},{"picUrl":"http://staging-teach.cdn.ireadabc.com/2f65d31e390318626fce1180bb09b2ea.png","isRight":"0","audioUrl":"http://staging-teach.cdn.ireadabc.com/b44fa51172b19b555fda30717c773027.mp3"}],"frames":[{"picUrl":"http://staging-teach.cdn.ireadabc.com/25a82fd9d55b026a76d2caaeed754a02.png"},{"picUrl":"http://staging-teach.cdn.ireadabc.com/25a82fd9d55b026a76d2caaeed754a02.png"},{"picUrl":"http://staging-teach.cdn.ireadabc.com/3d8d02f661a45283aa4eef1b6faed704.png"},{"picUrl":"http://staging-teach.cdn.ireadabc.com/8c1833c5a38efea3394ad78a44cd8801.png"},{"picUrl":"http://staging-teach.cdn.ireadabc.com/3d8d02f661a45283aa4eef1b6faed704.png"}],"hotZoneItemArr":[{"index":0,"pic_url":"http://staging-teach.cdn.ireadabc.com/28c3a876b5d0bbbb43f1b118bbe40df6.png","audio_url":"http://staging-teach.cdn.ireadabc.com/518441578f9d37076d87ef067c70a734.mp3","itemType":"pic","fontSize":50,"fontName":"BRLNSR_1","fontColor":"#8f3758","fontScale":0.9,"imgScale":0.5089285714285714,"mapScale":0.9,"picX":793,"picY":160,"rect":{"x":693,"y":117,"width":200,"height":200}}],"skeJsonData":{"url":"http://staging-teach.cdn.ireadabc.com/6db25cc732cb592dd26295aaefdd016a.json","name":"FT01测试_ske.json"},"texJsonData":{"url":"http://staging-teach.cdn.ireadabc.com/9223e48368163e5d2bd556aa869b4610.json","name":"FT01测试_tex.json"},"texPngData":{"url":"http://staging-teach.cdn.ireadabc.com/f7314ee89b8f27dc6b7cfcd6831ed728.png","name":"FT01测试_tex.png"},"bg":{"rect":{"x":0,"y":-57,"width":1152,"height":648},"picUrl":"http://staging-teach.cdn.ireadabc.com/0b6497174aed7ae05127d1eb8c29d94a.jpg"}}],"bg":{"rect":{"x":0,"y":-153.75,"width":1152,"height":841.5}},"title":{"val":"Find Body Part","audioUrl":"http://staging-teach.cdn.ireadabc.com/ef597f87e534ab2c73f4f9ed34eb26fa.mp3"}}';
const data = JSON.parse(dataJson);
return data;
},
preloadItem() {
this.addPreloadImage();
this.addPreloadAudio();
this.addPreloadAnima();
this.preload();
},
addPreloadImage() {
for (let i = 0; i < this.data.exercisesArr.length; ++i) {
let exercises = this.data.exercisesArr[i];
if (exercises.bg && exercises.bg.picUrl){
this._imageResList.push({ url: exercises.bg.picUrl });
}
//循环处理备选答案的图片
let answers = exercises.answers;
for (let j = 0; j < answers.length; ++j) {
let answer = answers[j];
if (answer.picUrl) {
this._imageResList.push({ url: answer.picUrl });
}
}
let hotZoneItemArr = exercises.hotZoneItemArr;
for (let j = 0; j < hotZoneItemArr.length; ++j) {
let hotZoneItem = hotZoneItemArr[j];
if (hotZoneItem.pic_url) {
this._imageResList.push({ url: hotZoneItem.pic_url });
}
}
}
},
addPreloadAudio() {
//this._audioResList.push({ url: this.data.audio_url });
if (this.data.title.audioUrl) {
this._audioResList.push({ url: this.data.title.audioUrl });
}
for (let i = 0; i < this.data.exercisesArr.length; ++i) {
let exercises = this.data.exercisesArr[i];
//循环处理备选答案的音频
let answers = exercises.answers;
for (let j = 0; j < answers.length; ++j) {
let answer = answers[j];
if (answer.audioUrl) {
this._audioResList.push({ url: answer.audioUrl });
}
}
let hotZoneItemArr = exercises.hotZoneItemArr;
for (let j = 0; j < hotZoneItemArr.length; ++j) {
let hotZoneItem = hotZoneItemArr[j];
if (hotZoneItem.audio_url) {
this._audioResList.push({ url: hotZoneItem.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();
},
_cantouch: null,
_curIndex: null,
_curExercise: null,
_circleArr: null,
initData() {
// 所有全局变量 默认都是null
this._cantouch = true;
this._curIndex = 0;
this._curExercise = this.data.exercisesArr[this._curIndex];
this._circleArr = [];
},
audioBtn: null,
/**正确音频 */
audioRight: null,
/**错误音频 */
audioError: null,
/**重试一次音频 */
audioTryAgain: null,
/**刷新 */
audioRefresh: null,
initAudio() {
const audioNode = cc.find('Canvas/res/audio');
const getAudioByResName = (resName) => {
return audioNode.getChildByName(resName).getComponent(cc.AudioSource);
}
this.audioBtn = getAudioByResName('btn');
this.audioRight = getAudioByResName('good_job');
this.audioError = getAudioByResName('error');
this.audioTryAgain = getAudioByResName('try_again');
this.audioRefresh = getAudioByResName('appear');
},
initView() {
this.initMaskLayer();
this.initTitle();
this.initBtn();
this.initExercise();
this.showStartAudio();
},
maskLayer: null,
initMaskLayer() {
const bNode = this.getSprNode('black');
bNode.scaleX = cc.winSize.width / bNode.width;
bNode.scaleY = cc.winSize.height / bNode.height;
bNode.parent = cc.find('Canvas');
bNode.active = false;
this.maskLayer = bNode;
},
showStartAudio() {
this.playAudioByUrl(this.data.title.audioUrl, () => {
this.showQuestionAudio();
})
},
showQuestionAudio() {
if (this._curExercise.hotZoneItemArr && this._curExercise.hotZoneItemArr.length > 0) {
this.playAudioByUrl(this._curExercise.hotZoneItemArr[0].audio_url);
}
},
initBg() {
const bgNode = cc.find('Canvas/bg');
bgNode.active = true;
bgNode.opacity = 255;
//如果客户自定义背景图片,则进行替换
if (this._curExercise.bg.picUrl) {
let spr = bgNode.bg;
if(spr){
spr.removeFromParent();
}
spr = bgNode.getComponent(cc.Sprite)
cc.find('Canvas/decorate').active = false;
this.getSpriteFrimeByUrl(this._curExercise.bg.picUrl, (sf) => {
spr.spriteFrame = sf;
bgNode.scaleX = this._frameSize.width / bgNode.width * this._cocosScale;
bgNode.scaleY = this._frameSize.height / bgNode.height * this._cocosScale;
})
}
else {
bgNode.scaleX = this._frameSize.width / bgNode.width * this._cocosScale;
bgNode.scaleY = this._frameSize.height / bgNode.height * this._cocosScale;
cc.find('Canvas/decorate').active = true;
const bgFloorNode = cc.find('Canvas/decorate/bg_floor');
bgFloorNode.scaleX = this._frameSize.width / bgFloorNode.width * this._cocosScale;
const bgTopNode = cc.find('Canvas/decorate/bg_top');
bgTopNode.scale = this._frameSize.width / bgTopNode.width * this._cocosScale;
const titleBgNode = this.getSprNode('bg');
titleBgNode.parent = bgNode;
}
},
titleLabel: null,
initTitle() {
/*
const titleBgNode = this.getSprNode('title_bg');
titleBgNode.parent = cc.find('Canvas');
titleBgNode.scale = this._mapScaleMin;
titleBgNode.anchorX = 0;
titleBgNode.anchorY = 1;
titleBgNode.x = -titleBgNode.parent.width / 2
titleBgNode.y = titleBgNode.parent.height / 2;
*/
const titleBgNode = cc.find('Canvas/title_bg');
titleBgNode.zIndex = 99;
const labelNode = new cc.Node();
labelNode.parent = titleBgNode;
const label = labelNode.addComponent(cc.RichText);
const size = 36
label.font = cc.find('Canvas/res/font/FatMarker').getComponent(cc.Label).font;
label.string = `<size=${size}><color=#6e160c>${this.data.title.val}</color></size>`
label.horizontalAlign = cc.macro.TextAlignment.LEFT
labelNode.anchorX = 0.5;
labelNode.anchorY = 0.5;
labelNode.rotation = -3;
this.titleLabel = label;
const maxW = titleBgNode.width * 0.65;
if (labelNode.width > maxW) {
labelNode.scale = maxW / labelNode.width;
}
labelNode.x = titleBgNode.width / 2 - 20 * this._cocosScale;
labelNode.y = -(titleBgNode.height - labelNode.height) / 2;
titleBgNode.addComponent(cc.Button);
titleBgNode.on('click', () => {
this.playAudioByUrl(this.data.title.audioUrl);
});
},
initBtn() {
const bottomPart = cc.find('Canvas/bottomBtn')
bottomPart.scale = this._mapScaleMin;
//bottomPart.x = bottomPart.parent.width / 2;
//bottomPart.y = -bottomPart.parent.height / 2;
const lastBtn = bottomPart.getChildByName('btn_last');
const nextBtn = bottomPart.getChildByName('btn_next');
const refreshBtn = bottomPart.getChildByName('btn_refresh');
btnClickAnima(lastBtn)
lastBtn.on('click', () => {
if (!this._cantouch) {
return;
}
this._cantouch = false;
this.lastBtnClick();
this.refreshBtnStatue();
})
btnClickAnima(nextBtn)
nextBtn.on('click', () => {
if (!this._cantouch) {
return;
}
this._cantouch = false;
this.nextBtnClick();
this.refreshBtnStatue();
})
btnClickAnima(refreshBtn)
refreshBtn.on('click', () => {
console.log("this._cantouch: ", this._cantouch);
if (!this._cantouch) {
return;
}
this._cantouch = false;
this.refreshBtnClick();
this.refreshBtnStatue();
})
this.refreshBtnStatue();
},
refreshBtnStatue() {
const lastBtn = cc.find('Canvas/bottomBtn/btn_last');
const nextBtn = cc.find('Canvas/bottomBtn/btn_next');
lastBtn.opacity = 255;
nextBtn.opacity = 255;
if (this._curIndex <= 0) {
lastBtn.opacity = 80;
}
if (this._curIndex >= this.data.exercisesArr.length - 1) {
nextBtn.opacity = 80;
}
},
lastBtnClick() {
if (this._curIndex <= 0) {
this._cantouch = true;
return;
}
cc.audioEngine.play(this.audioBtn.clip, false, 0.1)
this._curIndex--;
this._curExercise = this.data.exercisesArr[this._curIndex];
this.showNewGroup();
},
nextBtnClick() {
if (this._curIndex >= this.data.exercisesArr.length - 1) {
this._cantouch = true;
return;
}
cc.audioEngine.play(this.audioBtn.clip, false, 0.1)
this._curIndex++;
this._curExercise = this.data.exercisesArr[this._curIndex];
this.showNewGroup();
},
refreshBtnClick() {
cc.audioEngine.play(this.audioRefresh.clip, false, 0.2);
this.showNewGroup();
},
showNewGroup() {
this.showMaskLayer(() => {
this.initExercise();
this.hideMaskLayer(() => {
this._cantouch = true;
this.showQuestionAudio();
});
})
},
showMaskLayer(cb) {
this.maskLayer.opacity = 0;
this.maskLayer.active = true;
cc.tween(this.maskLayer)
.to(0.5, { opacity: 255 }, { easing: 'sineOut' })
.call(() => {
cb()
})
.start()
},
hideMaskLayer(cb = null) {
this.maskLayer.opacity = 255;
cc.tween(this.maskLayer)
.to(0.5, { opacity: 0 }, { easing: 'sineIn' })
.call(() => {
this.maskLayer.active = false;
if (cb) {
cb()
}
})
.start()
},
initCenterPart() {
const centerPart = cc.find('Canvas/stage/centerPart');
centerPart.scale = this._mapScaleMin;
this.setOneAnima(this._curExercise);
if (centerPart.bubbleArr) {
centerPart.bubbleArr.forEach((bubble, i) => {
bubble.removeFromParent();
});
}
centerPart.bubbleArr = [];
for (let i = 0; i < this._curExercise.hotZoneItemArr.length; ++i) {
let hotZoneItem = this._curExercise.hotZoneItemArr[i];
this.getSprNodeByUrl(hotZoneItem.pic_url, (bubbleSpr) => {
if (centerPart.bubbleArr[i]) {
centerPart.bubbleArr[i].removeFromParent();
}
let bubble_bg = cc.find('Canvas/stage/centerPart/bubble_bg');
bubble_bg.zIndex = 4;
bubbleSpr.node.parent = bubble_bg;
let rate = bubble_bg.width / this._curExercise.bg.rect.width;
let rect = {};
rect.x = hotZoneItem.rect.x * rate;
rect.y = hotZoneItem.rect.y * rate;
rect.width = hotZoneItem.rect.width * rate;
rect.height = hotZoneItem.rect.height * rate;
let x = rect.x + rect.width / 2 - bubble_bg.width / 2;
let y = bubble_bg.height / 2 - (rect.y + rect.height / 2);
bubbleSpr.node.x = x;
bubbleSpr.node.y = y;
bubbleSpr.node.scale = 0;
bubbleSpr.zIndex = 5;
centerPart.bubbleArr[i] = bubbleSpr.node;
bubbleSpr.node.addComponent(cc.Button)
bubbleSpr.node.on('click', () => {
this.playAudioByUrl(hotZoneItem.audio_url, () => {
});
});
cc.tween(bubbleSpr.node)
.to(0.7, { scale: this._mapScaleMin }, { easing: 'cubicIn' }).call(() => {
}).start();
});
}
},
initExercise() {
let answers = this._curExercise.answers;
this.initBg();
this.initCenterPart();
const circleArr = this.getCircleArr(answers);
this._circleArr = circleArr;
circleArr.forEach((item, i) => {
const data = answers[i];
if (data) {
this.getSprNodeByUrl(data.picUrl, (spr) => {
if (!item.blackMask) {
const blackMaskNode = this.getSprNode('mask')
blackMaskNode.parent = item;
blackMaskNode.scale = 1.0;
blackMaskNode.x = 0;
blackMaskNode.y = 3;
blackMaskNode.zIndex = 2;
item.blackMask = blackMaskNode;
}
item.blackMask.active = false;
if (!item.blackMask.icon) {
const icon = this.getSprNode('circle_x');
icon.parent = item.blackMask;
item.blackMask.icon = icon;
}
item.blackMask.icon.scale = 0;
if(!item.board2){
const board2 = this.getSprNode('option_board2');
board2.parent = item;
board2.scale = 1.0;
board2.zIndex = 1;
board2.opacity = 0;
item.board2 = board2;
}
if (!item.maskNode) {
let maskNode = new cc.Node(); // new cc.Node();
maskNode.parent = item;
if (item.getChildByName('mask')) {
maskNode = item.getChildByName('mask');
maskNode.scale = 1.0;
maskNode.x = 0;
maskNode.y = 3;
maskNode.zIndex = 2;
const mask = maskNode.getComponent(cc.Mask);
mask.inverted = false;
}
item.maskNode = maskNode
}
const maskNode = item.maskNode;
if (item.pic) {
item.pic.removeFromParent();
}
spr.node.parent = maskNode;
let picMaxW, picMaxH
picMaxW = item.width;
picMaxH = item.height;
spr.node.zIndex = 2;
setSprNodeMaxLen(spr.node, picMaxW, picMaxH);
item.pic = spr.node;
spr.node.addComponent(cc.Button);
spr.node.on('click', () => {
if (!this._cantouch) {
return;
}
if (data.isRight == '1') {
this.showRightCircle(item);
this._cantouch = false;
} else {
this.showWrongCircle(item);
}
});
})
}
});
this.addCircleSound();
this._curExercise.isAnswered = false;
this._cantouch = true;
},
_answer_node: null,
getCircleArr(answers) {
const circleArr = [];
let node, circleNum = 0;
console.log('answers: ', answers);
const answer_3 = cc.find('Canvas/stage/answer_3');
const answer_4 = cc.find('Canvas/stage/answer_4');
const answer_5 = cc.find('Canvas/stage/answer_5');
if (answers.length == 3) {
answer_3.active = true;
answer_4.active = false;
answer_5.active = false;
node = answer_3;
circleNum = 3;
} else if (answers.length == 4) {
answer_3.active = false;
answer_4.active = true;
answer_5.active = false;
node = answer_4;
circleNum = 4;
}
else if (answers.length == 5) {
answer_3.active = false;
answer_4.active = false;
answer_5.active = true;
node = answer_5;
circleNum = 5;
}
this._answer_node = node;
for (let i = 0; i < circleNum; i++) {
let circleNode = node.getChildByName('option_board_' + (i + 1).toString());
if (answers[i]) {
circleNode.active = true;
circleNode.data = answers[i];
circleArr.push(circleNode);
} else {
circleNode.active = false;
}
}
return circleArr;
},
addCircleSound() {
this._circleArr.forEach(item => {
if (item.icon) {
return;
}
const sprNode = this.getSprNode('loudspeaker');
sprNode.parent = item;
sprNode.x = item.width / 2.4;
sprNode.y = item.height / 3.0;
sprNode.zIndex = 5;
item.icon = sprNode;
const sprNode2 = this.getSprNode('loudspeaker_playing');
sprNode2.parent = sprNode.parent;
sprNode2.x = sprNode.x;
sprNode2.y = sprNode.y;
sprNode2.zIndex = 6;
sprNode2.opacity = 0;
sprNode.spr2 = sprNode2;
sprNode.addComponent(cc.Button)
sprNode.on('click', () => {
this.showSoundAnima(sprNode, item);
this.playAudioByUrl(item.data.audioUrl, () => {
this.stopSoundAnima(sprNode);
});
});
});
},
/**正在播放的音频节点 */
_playingNode: null,
showSoundAnima(iconNode, item, time = 0.4) {
if (this._playingNode != iconNode && this._playingNode) {
this.stopSoundAnima(this._playingNode);
}
this._playingNode = iconNode;
iconNode.isRunAnima = true;
iconNode.spr2.opacity = 255;
iconNode.opacity = 0;
item.board2.opacity = 255;console.log(item.board2);
cc.tween(iconNode)
.delay(time / 2)
.call(() => {
iconNode.spr2.opacity = 0;
iconNode.opacity = 255;
item.board2.opacity = 0;
})
.delay(time / 2)
.call(() => {
if (iconNode.isRunAnima) {
this.showSoundAnima(iconNode, item);
}
})
.start()
},
stopSoundAnima(iconNode) {
iconNode.isRunAnima = false;
},
showRightCircle(circle) {
cc.audioEngine.play(this.audioRight.clip, false, 0.3)
cc.tween(this._answer_node)
.to(0.7, { scale: 0 }, { easing: 'cubicIn' })
.call(() => {
this._answer_node.active = false;
this._answer_node.scale = this._mapScaleMin;
this._cantouch = true;
this._curExercise.isAnswered = true;
this.showDragonAnima();
})
.start();
},
showWrongCircle(circle) {
if (circle.blackMask.active) {
return;
}
cc.audioEngine.play(this.audioError.clip, false, 0.2)
const showIcon = () => {
cc.tween(circle.blackMask.icon)
.to(0.3, { scale: 0.9 }, { easing: 'bounceOut' })
.delay(0.2)
.to(0.7, { scale: 0 }, { easing: 'cubicIn' })
.start();
}
const hide = () => {
circle.blackMask.opacity = 0;
cc.tween(circle.blackMask)
.to(0.1, { opacity: 255 })
.call(() => {
showIcon();
})
.start()
}
hide();
circle.blackMask.active = true;
},
curDragonDisplay: null,
setOneAnima(data) {
const picNode = cc.find('Canvas/stage/centerPart/ani');
if (picNode.animaNode) {
picNode.animaNode.removeFromParent();
}
const animaNode = new cc.Node();
animaNode.parent = picNode;
animaNode.x =0;
animaNode.y = 0;
picNode.animaNode = animaNode;
const dragonDisplay = animaNode.addComponent(dragonBones.ArmatureDisplay);
this.curDragonDisplay = dragonDisplay;
const image = data.texPngData.url//"http://staging-teach.cdn.ireadabc.com/5a0c5af3e952acd0ac83a6e5c6f03ff1.png";
const ske = data.skeJsonData.url//"http://staging-teach.cdn.ireadabc.com/bd825dcceea298d1146be8067ae3d17f.json";
const atlas = data.texJsonData.url//"http://staging-teach.cdn.ireadabc.com/246f8991b729fa3e5a7f4802de828efa.json";
cc.loader.load(image, (error, texture) => {
cc.loader.load({url: atlas, type: 'txt'}, (error, atlasJson) => {
cc.loader.load({url: ske, type: 'txt'}, (error, dragonBonesJson) => {
const atlas = new dragonBones.DragonBonesAtlasAsset();
atlas.atlasJson = atlasJson;
atlas.texture = texture;
const asset = new dragonBones.DragonBonesAsset();
asset.dragonBonesJson = dragonBonesJson;
dragonDisplay.dragonAtlasAsset = atlas;
dragonDisplay.dragonAsset = asset;
let json = JSON.parse(asset.dragonBonesJson);
let armatures = json["armature"];
// console.log('armatures: ', armatures);
let armatureNames = [];
for (let i = 0; i < armatures.length; i++) {
armatureNames.push(armatures[i].name);
}
// console.log('armatureNames: ', armatureNames);
if (armatureNames.length > 0) {
let defaultArmatureName = armatureNames[0];
dragonDisplay.armatureName = defaultArmatureName;
// let animationNames = dragonDisplay.getAnimationNames(defaultArmatureName);
let defaultArmature = armatures[0];
let animations = defaultArmature.animation;
let animationNames = [];
for (let i = 0; i < animations.length; i++) {
animationNames.push(animations[i].name);
}
dragonDisplay.animaNames = animationNames;
console.log('animaNode: ', animaNode);
animaNode.addComponent(cc.Button)
animaNode.on('click', () => {
if(this._curExercise.isAnswered){
console.log('anima node clicked ~~~');
this.showDragonAnima();
}
})
}
});
});
});
},
showDragonAnima() {
if (this.curDragonDisplay && this.curDragonDisplay.animaNames.length > 0) {
this.curDragonDisplay.playAnimation(this.curDragonDisplay.animaNames[0], 1);
}
},
// ------------------------------------------------
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(spr);
}
})
},
_audioId : null,
playAudioByUrl(audio_url, cb = null) {
if(this._audioId){
cc.audioEngine.pause(this._audioId);
}
if (audio_url) {
cc.assetManager.loadRemote(audio_url, (err, audioClip) => {
const audioId = cc.audioEngine.play(audioClip, false, 0.8);
this._audioId = audioId;
if (cb) {
cc.audioEngine.setFinishCallback(audioId, () => {
cb();
});
}
});
}
},
// ------------------------------------------
});
......@@ -131,224 +131,4 @@ export function btnClickAnima(btn, time=0.15, rate=1.05) {
.to(time / 2, {scale: btn.tmpScale})
.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
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 = Math.abs(px - mx);
const y = Math.abs(py - my);
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;
}
export function exchangeNodePos(baseNode, targetNode) {
return baseNode.convertToNodeSpaceAR(targetNode._parent.convertToWorldSpaceAR(cc.v2(targetNode.x, targetNode.y)));
}
export function RandomInt(a, b = 0) {
let max = Math.max(a, b);
let min = Math.min(a, b);
return Math.floor(Math.random() * (max - min) + min);
}
export function Between(a, b, c) {
return [a, b, c].sort((a, b) => a - b)[1];
}
export function randomSortByArr(arr) {
const newArr = [];
const tmpArr = arr.concat();
while (tmpArr.length > 0) {
const randomIndex = Math.floor(tmpArr.length * Math.random());
newArr.push(tmpArr[randomIndex]);
tmpArr.splice(randomIndex, 1);
}
return newArr;
}
export async function asyncTweenTo(node, duration, obj, ease = undefined) {
return new Promise((resolve, reject) => {
cc.tween(node)
.to(duration, obj, ease)
.call(() => {
resolve();
})
.start();
});
}
export async function asyncTweenBy(node, duration, obj, ease = undefined) {
return new Promise((resolve, reject) => {
cc.tween(node)
.by(duration, obj, ease)
.call(() => {
resolve();
})
.start();
});
}
export async function asyncPlayDragonBoneAnimation(node, animationName, time = 1, onFrameEvent) {
return new Promise((resolve, reject) => {
node.getComponent(dragonBones.ArmatureDisplay)
.once(dragonBones.EventObject.COMPLETE, () => {
resolve();
});
node.getComponent(dragonBones.ArmatureDisplay)
.on(dragonBones.EventObject.FRAME_EVENT, ({ name }) => {
if (onFrameEvent && typeof (onFrameEvent) == 'function') {
onFrameEvent(name);
}
});
node.getComponent(dragonBones.ArmatureDisplay)
.playAnimation(animationName, time);
});
}
export async function asyncPlayEffectByUrl(url, loop = false) {
return new Promise((resolve, reject) => {
cc.assetManager.loadRemote(url, (err, clip) => {
console.log(clip);
cc.audioEngine.playEffect(clip, loop);
resolve();
});
});
}
export async function jelly(node) {
return new Promise((resolve, reject) => {
cc.tween(node)
.to(0.1, { scaleX: 0.9, scaleY: 1.1 })
.to(0.1, { scaleX: 1.1, scaleY: 0.9 })
.to(0.1, { scaleX: 1, scaleY: 1 })
.call(resolve)
.start();
});
}
export async function asyncDelay(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, time * 1000);
})
}
export async function showFireworks(baseNode, nodeList, pos = cc.v2(0, 0), side = cc.v2(0, 100), range = 50, number = 100) {
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;
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();
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);
}
\ No newline at end of file
{
"ver": "1.0.8",
"uuid": "c41b0e51-55d7-443c-af3a-b22c3dd9b9e5",
"uuid": "d545f402-231b-417e-99e6-3269412a5a2c",
"isPlugin": false,
"loadPluginInWeb": 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
{
"ver": "2.3.5",
"uuid": "efa5fa09-a4dd-4bfc-ab7e-17c19f85408f",
"uuid": "78232ea2-bf69-4323-a632-539e486a3aac",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 366,
"height": 336,
"width": 285,
"height": 205,
"platformSettings": {},
"subMetas": {
"1orange": {
"bg_lt": {
"ver": "1.0.4",
"uuid": "43d1e79d-6de8-4dcb-b8ce-d767df7913aa",
"rawTextureUuid": "efa5fa09-a4dd-4bfc-ab7e-17c19f85408f",
"uuid": "d4aba120-0e61-4836-853a-0a38433ffc04",
"rawTextureUuid": "78232ea2-bf69-4323-a632-539e486a3aac",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": -0.5,
"offsetY": 0,
"trimX": 0,
"trimY": 1,
"width": 366,
"height": 335,
"rawWidth": 366,
"rawHeight": 336,
"trimY": 0,
"width": 285,
"height": 205,
"rawWidth": 285,
"rawHeight": 205,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
......
{
"ver": "2.3.5",
"uuid": "d582359e-924e-4ee9-9964-1fc4bb417e71",
"uuid": "fb7cf0eb-92ee-4ccd-add2-ff91274d4f84",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 61,
"height": 67,
"width": 285,
"height": 205,
"platformSettings": {},
"subMetas": {
"btn_right": {
"bg_rt": {
"ver": "1.0.4",
"uuid": "e5a2dbaa-a677-4a32-90d7-a1b057d7fb59",
"rawTextureUuid": "d582359e-924e-4ee9-9964-1fc4bb417e71",
"uuid": "a76c2fa5-6864-4076-8209-2abfac0ffdf3",
"rawTextureUuid": "fb7cf0eb-92ee-4ccd-add2-ff91274d4f84",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": -0.5,
"offsetY": 0.5,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 60,
"height": 66,
"rawWidth": 61,
"rawHeight": 67,
"width": 285,
"height": 205,
"rawWidth": 285,
"rawHeight": 205,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
......
{
"ver": "2.3.5",
"uuid": "d5320ba1-149b-41d6-a429-fe8046456b60",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 990,
"height": 345,
"platformSettings": {},
"subMetas": {
"bg_star": {
"ver": "1.0.4",
"uuid": "d53bf7c7-6195-4009-a62b-3aa2557b51e4",
"rawTextureUuid": "d5320ba1-149b-41d6-a429-fe8046456b60",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 990,
"height": 345,
"rawWidth": 990,
"rawHeight": 345,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}
\ No newline at end of file
{
"ver": "2.3.5",
"uuid": "e8229e86-8527-4b88-80ee-36d84a95e746",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 1280,
"height": 102,
"platformSettings": {},
"subMetas": {
"bg_top": {
"ver": "1.0.4",
"uuid": "760864d5-b4bf-4f7a-929b-833fdd1ed24c",
"rawTextureUuid": "e8229e86-8527-4b88-80ee-36d84a95e746",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 1280,
"height": 102,
"rawWidth": 1280,
"rawHeight": 102,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}
\ No newline at end of file
{
"ver": "2.3.5",
"uuid": "f7b806a4-4c99-482c-9ef5-3faba9ed4d7a",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 100,
"height": 100,
"platformSettings": {},
"subMetas": {
"black": {
"ver": "1.0.4",
"uuid": "b71ab9cc-f816-4ab4-a418-c3894b9c33f1",
"rawTextureUuid": "f7b806a4-4c99-482c-9ef5-3faba9ed4d7a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 100,
"height": 100,
"rawWidth": 100,
"rawHeight": 100,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}
\ No newline at end of file
{
"ver": "2.3.5",
"uuid": "a88ca261-1410-40a6-8b62-de00aac4311e",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 49,
"height": 50,
"platformSettings": {},
"subMetas": {
"btn_close": {
"ver": "1.0.4",
"uuid": "ee764781-bde3-4e88-83dc-6afaac9fb481",
"rawTextureUuid": "a88ca261-1410-40a6-8b62-de00aac4311e",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 49,
"height": 50,
"rawWidth": 49,
"rawHeight": 50,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}
\ No newline at end of file
{
"ver": "2.3.5",
"uuid": "9a79969a-0506-48d4-bc98-3c05d109b027",
"uuid": "273e9e9f-35a8-4de2-bcb0-930e497ae0d1",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 61,
"height": 67,
"width": 45,
"height": 46,
"platformSettings": {},
"subMetas": {
"btn_left": {
"btn_last": {
"ver": "1.0.4",
"uuid": "ce19457d-e8f3-4c38-ae3e-d4b99208ddb5",
"rawTextureUuid": "9a79969a-0506-48d4-bc98-3c05d109b027",
"uuid": "8d639968-f42c-4f91-90de-4ba34c6bca91",
"rawTextureUuid": "273e9e9f-35a8-4de2-bcb0-930e497ae0d1",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
......@@ -22,10 +22,10 @@
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 61,
"height": 67,
"rawWidth": 61,
"rawHeight": 67,
"width": 45,
"height": 46,
"rawWidth": 45,
"rawHeight": 46,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
......
{
"ver": "2.3.5",
"uuid": "9a1a9dd9-b5d6-4d65-8a84-cfd59a350b0a",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 44,
"height": 46,
"platformSettings": {},
"subMetas": {
"btn_next": {
"ver": "1.0.4",
"uuid": "4a7548c2-e983-41ab-b6b4-f1092dd2b2cc",
"rawTextureUuid": "9a1a9dd9-b5d6-4d65-8a84-cfd59a350b0a",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 44,
"height": 46,
"rawWidth": 44,
"rawHeight": 46,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}
\ No newline at end of file
{
"ver": "2.3.5",
"uuid": "7d99e5d6-be6e-4906-ad92-2140f52fb705",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 47,
"height": 57,
"platformSettings": {},
"subMetas": {
"btn_refresh": {
"ver": "1.0.4",
"uuid": "3237b1d3-0795-4bbb-bee3-ba2a77b875df",
"rawTextureUuid": "7d99e5d6-be6e-4906-ad92-2140f52fb705",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 47,
"height": 57,
"rawWidth": 47,
"rawHeight": 57,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}
\ No newline at end of file
{
"ver": "2.3.5",
"uuid": "aa5ca4b8-3f45-40f2-a72e-784660086597",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 109,
"height": 109,
"platformSettings": {},
"subMetas": {
"circle_x": {
"ver": "1.0.4",
"uuid": "5e2f92d5-3a8f-4299-afec-39341eae777b",
"rawTextureUuid": "aa5ca4b8-3f45-40f2-a72e-784660086597",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 109,
"height": 109,
"rawWidth": 109,
"rawHeight": 109,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}
\ No newline at end of file
{
"ver": "2.3.5",
"uuid": "1512c336-ab6d-470e-a794-6f1dbedda6de",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 103,
"height": 646,
"platformSettings": {},
"subMetas": {
"l_curtain": {
"ver": "1.0.4",
"uuid": "42998bc9-e010-4a63-bc8f-f1e82cfaa1b9",
"rawTextureUuid": "1512c336-ab6d-470e-a794-6f1dbedda6de",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 103,
"height": 646,
"rawWidth": 103,
"rawHeight": 646,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}
\ No newline at end of file
{
"ver": "2.3.5",
"uuid": "f2d0669f-ebdb-4b51-96b1-460f95f7166f",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 57,
"height": 61,
"platformSettings": {},
"subMetas": {
"loudspeaker": {
"ver": "1.0.4",
"uuid": "e1f115a3-879c-4c53-8b4e-daabf238e534",
"rawTextureUuid": "f2d0669f-ebdb-4b51-96b1-460f95f7166f",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 57,
"height": 61,
"rawWidth": 57,
"rawHeight": 61,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}
\ No newline at end of file
{
"ver": "2.3.5",
"uuid": "67cab122-fe68-4fed-ab6c-7106ad4aa97c",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 57,
"height": 61,
"platformSettings": {},
"subMetas": {
"loudspeaker_playing": {
"ver": "1.0.4",
"uuid": "703040de-e10d-4a49-acdd-fecb3c0ecf98",
"rawTextureUuid": "67cab122-fe68-4fed-ab6c-7106ad4aa97c",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 57,
"height": 61,
"rawWidth": 57,
"rawHeight": 61,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}
\ No newline at end of file
{
"ver": "2.3.5",
"uuid": "2189026f-8e66-4610-b5f7-f5b7d506ff76",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 149,
"height": 149,
"platformSettings": {},
"subMetas": {
"mask": {
"ver": "1.0.4",
"uuid": "e5623257-3b71-4720-8b9b-bd5b0f3d2106",
"rawTextureUuid": "2189026f-8e66-4610-b5f7-f5b7d506ff76",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 149,
"height": 149,
"rawWidth": 149,
"rawHeight": 149,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}
\ No newline at end of file
{
"ver": "2.3.5",
"uuid": "6218c4e7-1f95-4a09-9776-06b34ad295e0",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 190,
"height": 201,
"platformSettings": {},
"subMetas": {
"option_board": {
"ver": "1.0.4",
"uuid": "54fa87db-64cb-4caf-89dc-f7685524fc22",
"rawTextureUuid": "6218c4e7-1f95-4a09-9776-06b34ad295e0",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 190,
"height": 201,
"rawWidth": 190,
"rawHeight": 201,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}
\ No newline at end of file
{
"ver": "2.3.5",
"uuid": "7ae02098-5a52-4daf-9239-ca33060886c8",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 190,
"height": 201,
"platformSettings": {},
"subMetas": {
"option_board2": {
"ver": "1.0.4",
"uuid": "f20c61a5-42f5-4ffc-9da8-95edd7de6ef7",
"rawTextureUuid": "7ae02098-5a52-4daf-9239-ca33060886c8",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 190,
"height": 201,
"rawWidth": 190,
"rawHeight": 201,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}
\ No newline at end of file
{
"ver": "2.3.5",
"uuid": "76a2de25-7550-48cf-858f-b8b0679bda10",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 108,
"height": 645,
"platformSettings": {},
"subMetas": {
"r_curtain": {
"ver": "1.0.4",
"uuid": "ce048b47-60c7-4e56-bc63-72082210abaf",
"rawTextureUuid": "76a2de25-7550-48cf-858f-b8b0679bda10",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 108,
"height": 645,
"rawWidth": 108,
"rawHeight": 645,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}
\ No newline at end of file
{
"ver": "2.3.5",
"uuid": "cfc43dd1-2c05-4266-b488-bd0a86b5edd7",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 644,
"height": 132,
"platformSettings": {},
"subMetas": {
"shadow": {
"ver": "1.0.4",
"uuid": "9022c3d2-32e2-442c-82f6-0d8d80d25560",
"rawTextureUuid": "cfc43dd1-2c05-4266-b488-bd0a86b5edd7",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 644,
"height": 132,
"rawWidth": 644,
"rawHeight": 132,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}
\ No newline at end of file
{
"ver": "2.3.5",
"uuid": "6a87a898-22b2-4a6a-ba15-1c4f510eb73c",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 181,
"height": 109,
"platformSettings": {},
"subMetas": {
"small_bubble": {
"ver": "1.0.4",
"uuid": "52a4a2be-d3df-4d86-9d2d-192d5dbe2967",
"rawTextureUuid": "6a87a898-22b2-4a6a-ba15-1c4f510eb73c",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 1,
"offsetY": 1.5,
"trimX": 4,
"trimY": 0,
"width": 175,
"height": 106,
"rawWidth": 181,
"rawHeight": 109,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}
\ No newline at end of file
{
"ver": "2.3.5",
"uuid": "501c0733-2659-461d-807a-d7d7a08c7829",
"type": "sprite",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"width": 517,
"height": 128,
"platformSettings": {},
"subMetas": {
"title_bg": {
"ver": "1.0.4",
"uuid": "14e7fe89-0579-40cd-80a9-b226f20c1a55",
"rawTextureUuid": "501c0733-2659-461d-807a-d7d7a08c7829",
"trimType": "auto",
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 517,
"height": 128,
"rawWidth": 517,
"rawHeight": 128,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"subMetas": {}
}
}
}
\ No newline at end of file
......@@ -3,6 +3,6 @@
"packages": "packages",
"name": "play",
"id": "9af72fd2-44a6-4131-8ea3-3e1b3fa22231",
"version": "2.4.5",
"version": "2.4.0",
"isNew": false
}
\ No newline at end of file
{
"last-module-event-record-time": 1600677246969,
"migrate-history": [
"cloud-function"
]
"last-module-event-record-time": 1600677246969
}
#!/bin/sh
cd publish
set -e
node build_check.js
set +e
cd ../form
cd form
npm install
npm run publish
cd ../publish
node build_step_0.js
cd ../play
/Applications/CocosCreator/Creator/2.4.0/CocosCreator.app/Contents/MacOS/CocosCreator --path "./" --build "platform=web-desktop;debug=true" --force
echo "生成 web desktop 完成~!"
cd ../publish
node build_step_1.js
echo "build_step_1 完成~!"
cd ../play
/Applications/CocosCreator/Creator/2.4.4/CocosCreator.app/Contents/MacOS/CocosCreator --path "./" --build "platform=ios;debug=false;md5Cache=true;buildPath=build_ios;encryptJs=true;xxteaKey=6bbfce23-28b4-4a;zipCompressJs=true" --force
echo "生成 ios 完成~!"
cd ../publish
node build_step_2.js
echo "build_step_2 完成~!"
cd ../play
/Applications/CocosCreator/Creator/2.4.4/CocosCreator.app/Contents/MacOS/CocosCreator --path "./" --build "platform=ios;debug=false;md5Cache=true;buildPath=build_android;appABIs=['armeabi-v7a','x86','x86_64','arm64-v8a'];encryptJs=true;xxteaKey=6bbfce23-28b4-4a;zipCompressJs=true" --force
echo "生成 android 完成~!"
cd ../publish
node build_step_3.js
echo "build_step_3 完成~!"
cd ../play
/Applications/CocosCreator/Creator/2.4.4/CocosCreator.app/Contents/MacOS/CocosCreator --path "./" --build "platform=web-desktop;debug=false;buildPath=build_web_desktop" --force
echo "生成 web-desktop 完成~!"
cd ../publish
node build_step_4.js
echo "build_step_4 完成~!"
\ No newline at end of file
node build.js
let fs = require('fs');
const dirNames = __dirname.split('/');
const projectName = dirNames[dirNames.length - 2];
const path = '../play/assets'
let folderName = '';
fs.readdirSync(path).find(fileName => {
const st = fs.statSync(`${path}/${fileName}`);
if (st.isDirectory()) {
folderName = fileName;
}
});
if (projectName != folderName) {
throw (`项目名(${projectName})与bundle文件夹名(${folderName})不相同`);
}
let same = false;
const files = fs.readdirSync(`${path}/${folderName}/scene`);
files.forEach(fileName => {
fileName.split('.').forEach((str, idx, arr) => {
if (str == 'fire') {
const sceneName = arr[idx - 1];
if (folderName == sceneName) {
same = true;
}
}
})
});
if (!same) {
throw (`bundle文件夹名称(${folderName})与scene名称不相同`);
}
\ No newline at end of file
let fs = require('fs');
const path = '../play/assets'
let folderName = '';
fs.readdirSync(path).find(fileName => {
const st = fs.statSync(`${path}/${fileName}`);
if (st.isDirectory()) {
folderName = fileName;
}
});
const metaPath = `${path}/${folderName}.meta`;
const metaDataStr = fs.readFileSync(metaPath);
const metaData = JSON.parse(metaDataStr);
metaData.isBundle = false;
fs.writeFileSync(metaPath, JSON.stringify(metaData));
const { removeDir, copyDir, fix2 } = require('./utils');
const compressing = require('compressing');
let fs = require('fs');
async function main() {
await removeDir('./publish/play');
await removeDir('./publish/form');
await copyDir('../play/build/web-desktop', './publish/play');
compressing.zip.uncompress('../form/publish/form.zip', './publish/form');
const data = await fs.readFileSync('./index.html');
await fs.writeFileSync('./publish/play/index.html', data);
await removeDir('../play/build/web-desktop');
const path = '../play/assets'
let folderName = '';
fs.readdirSync(path).find(fileName => {
const st = fs.statSync(`${path}/${fileName}`);
if (st.isDirectory()) {
folderName = fileName;
}
});
const metaPath = `${path}/${folderName}.meta`;
const metaDataStr = fs.readFileSync(metaPath);
const metaData = JSON.parse(metaDataStr);
metaData.isBundle = true;
metaData.isRemoteBundle = {
ios: true,
android: true
};
fs.writeFileSync(metaPath, JSON.stringify(metaData));
}
main();
\ No newline at end of file
const { removeDir, copyDir, fix2 } = require('./utils');
const compressing = require('compressing');
async function main() {
await removeDir('./publish/ios');
await copyDir('../play/build_ios/jsb-link/remote', './publish/ios');
await removeDir('../play/build_ios/jsb-link');
}
main();
\ No newline at end of file
const { removeDir, copyDir, fix2 } = require('./utils');
const compressing = require('compressing');
let fs = require('fs');
async function main() {
await removeDir('./publish/android');
await copyDir('../play/build_android/jsb-link/remote', './publish/android');
await removeDir('../play/build_android/jsb-link');
}
main();
\ No newline at end of file
const { removeDir, copyDir, fix2 } = require('./utils');
const compressing = require('compressing');
let fs = require('fs');
async function main() {
await removeDir('./publish/web_desktop');
const projectName = await getBundleName('../play/build_web_desktop/web-desktop/assets');
await copyDir(`../play/build_web_desktop/web-desktop/assets/${projectName}`, './publish/web_desktop');
await removeDir('../play/build_web_desktop');
const bundleData = {
ios: await getBundleData('./publish/ios'),
android: await getBundleData('./publish/android'),
}
fs.writeFileSync('./publish/config.json', JSON.stringify(bundleData));
const tarStream = new compressing.zip.Stream();
tarStream.addEntry('./publish/play');
tarStream.addEntry('./publish/form');
tarStream.addEntry('./publish/ios');
tarStream.addEntry('./publish/android');
tarStream.addEntry('./publish/web_desktop');
tarStream.addEntry('./publish/config.json');
const destStream = fs.createWriteStream(`publish/${getReleaseFileName()}.zip`);
tarStream.pipe(destStream);
console.log('打包完成!');
}
async function getBundleName(path) {
const paths = fs.readdirSync(path);
return paths.find(path => path != 'internal' && path !='main');
}
async function getBundleData(path) {
const bundleData = {
sceneName: '',
version: '',
}
const paths = fs.readdirSync(path);
bundleData.sceneName = paths[0];
const files = fs.readdirSync(path + '/' + bundleData.sceneName);
files.forEach(fileName => {
fileName.split('.').forEach((str, idx, arr) => {
if (str == 'config') {
bundleData.version = arr[idx + 1];
}
})
});
return bundleData;
}
function getReleaseFileName() {
let date = new Date();
let fileName = `Release_${date.getFullYear()}${fix2(date.getMonth() + 1)}${fix2(date.getDate())} `;
fileName += `${fix2(date.getHours())}-${fix2(date.getMinutes())}-${fix2(date.getSeconds())}`;
return fileName;
}
main();
\ No newline at end of file
......@@ -35,7 +35,7 @@
<script src="src/settings.js" charset="utf-8"></script>
<script src="main.js" charset="utf-8"></script>
<script type="text/javascript" src="//staging-teach.cdn.ireadabc.com/h5template/h5-static-lib/js/air.js"></script>
<script type="text/javascript" src="https://staging-teach.cdn.ireadabc.com/h5template/h5-static-lib/js/air.js"></script>
<script type="text/javascript">
......
......@@ -5,9 +5,9 @@
"requires": true,
"dependencies": {
"bl": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz",
"integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==",
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
"integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
"requires": {
"readable-stream": "^2.3.5",
"safe-buffer": "^5.1.1"
......
let fs = require('fs');
module.exports = {
fix2: function (num) {
if (num >= 10) {
return '' + num;
} else {
return '0' + num;
}
},
copyDir: async function (src, dst) {
const exists = await fs.existsSync(dst);
if (!exists) {
await fs.mkdirSync(dst);
}
//读取目录
const paths = await fs.readdirSync(src);
for (let i = 0; i < paths.length; i++) {
let path = paths[i];
const newSrc = `${src}/${path}`;
const newDst = `${dst}/${path}`;
const st = await fs.statSync(newSrc);
if (st.isFile()) {
console.log('copy: ' + newDst);
const data = await fs.readFileSync(newSrc);
await fs.writeFileSync(newDst, data);
} else if (st.isDirectory()) {
arguments.callee(newSrc, newDst);
}
}
},
removeDir: async function (src) {
const exists = await fs.existsSync(src);
if (!exists) {
return;
}
//读取目录
const st = await fs.statSync(src);
const paths = await fs.readdirSync(src);
for (let i = 0; i < paths.length; i++) {
let path = paths[i];
const newSrc = `${src}/${path}`;
const st = await fs.statSync(newSrc);
if (st.isFile()) {
console.log('remove: ' + newSrc);
await fs.unlinkSync(newSrc);
} else if (st.isDirectory()) {
await arguments.callee(newSrc);
}
}
await fs.rmdirSync(src);
}
}
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