Commit bb72683a authored by Chen Jiping's avatar Chen Jiping

模板完成

parent 3695f7ce
......@@ -128,5 +128,8 @@
}
}
},
"defaultProject": "ng-template-generator"
}
"defaultProject": "ng-template-generator",
"cli": {
"analytics": "181ec1bf-5950-47fe-8144-2a4fdffe488d"
}
}
\ No newline at end of file
export class Course {
/**练习类型:01-文本, 02-音频, 03-图片 */
type: string;
text: string;
picUrl: string;
audioUrl: string;
picArr: [];
}
export class Picture {
picUrl: string;
color: string;
}
\ No newline at end of file
<div class="model-content">
<nz-card nzTitle="课程练习内容编辑" style="margin:5vw;" nzType="inner">
<div nz-row>
<nz-form-item>
<nz-form-label [nzSpan]="6" nzFor="type" nzNoColon=true>类型</nz-form-label>
<nz-form-control [nzSpan]="6">
<nz-select [(ngModel)]="item.type" style="width: 110px;" id="type"
(ngModelChange)="onChange($event, item, 'type')" nzPlaceHolder="type">
<nz-option [nzValue]="option.code" [nzLabel]="option.name" *ngFor="let option of courseTypeArr">
</nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSpan]="6" nzFor="type" nzNoColon=true>内容(长度:96)</nz-form-label>
<nz-form-control [nzSpan]="8" [nzXs]='24' [nzSm]='12' [nzMd]='12' [nzLg]='8' nzHasFeedback nzErrorTip="MaxLength is 96">
<div *ngIf="item.type == '01'">
<textarea rows="6" nz-input [(ngModel)]="item.text" (blur)="save()" maxlength="96" placeholder="write any thing"></textarea>
</div>
<div *ngIf="item.type == '02'">
<app-audio-recorder [audioUrl]="item.audioUrl"
(audioUploaded)="onAudioUploadSuccess($event, item, 'audioUrl')">
</app-audio-recorder>
</div>
<div *ngIf="item.type == '03'">
<app-upload-image-with-preview [picUrl]="item.picUrl"
(imageUploaded)="onImageUploadSuccess($event, item, 'picUrl')">
</app-upload-image-with-preview>
</div>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSpan]="6" nzFor="add-btn" nzNoColon=true>图片</nz-form-label>
<nz-form-control [nzXs]='24' [nzSm]='12' [nzMd]='12' [nzLg]='6'>
<button nz-button nzType="dashed" class="add-btn" id="add-btn" (click)="addPicItem()">
<i nz-icon nzType="plus-circle" nzTheme="outline"></i>添加
</button>
</nz-form-control>
</nz-form-item>
</div>
<div nz-row>
<div *ngFor="let data of item.picArr;let i = index" nz-col [nzXs]='24' [nzSm]='12' [nzMd]='12' [nzLg]='7' style="margin: 1vw;">
<nz-card nzTitle="图片-{{i + 1}}" [nzExtra]="extraTemplate">
<nz-form-item>
<nz-form-label [nzSpan]="6" nzNoColon=true>图片</nz-form-label>
<nz-form-control [nzSpan]="18">
<app-upload-image-with-preview [picUrl]="data.picUrl"
(imageUploaded)="onImageUploadSuccess($event, data, 'picUrl')">
</app-upload-image-with-preview>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSpan]="6" nzNoColon=true>涂色</nz-form-label>
<nz-form-control [nzSpan]="18">
<nz-select [(ngModel)]="data.color" style="width: 100%;" id="color"
(ngModelChange)="onChange($event, data, 'color')" nzPlaceHolder="color">
<nz-option [nzValue]="option.code" nzCustomContent [nzLabel]="option.name"
*ngFor="let option of colorArr"><img src='{{option.picUrl}}'>{{option.name}}
</nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
</nz-card>
<ng-template #extraTemplate>
<button style="margin: 10px;" nz-button nzType="danger" (click)="delPicItem(i)">
<span>删除</span>
</button>
</ng-template>
</div>
</div>
<div style="position: absolute; left: 200px; top: 100px; width: 800px;">
<input type="text" nz-input [(ngModel)]="item.text" (blur)="save()">
<app-upload-image-with-preview
[picUrl]="item.pic_url"
(imageUploaded)="onImageUploadSuccess($event, 'pic_url')"
></app-upload-image-with-preview>
</nz-card>
<app-audio-recorder
[audioUrl]="item.audio_url"
(audioUploaded)="onAudioUploadSuccess($event, 'audio_url')"
></app-audio-recorder>
<app-custom-hot-zone></app-custom-hot-zone>
<app-upload-video></app-upload-video>
<app-lesson-title-config></app-lesson-title-config>
</div>
</div>
\ No newline at end of file
</div>
\ No newline at end of file
import {Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, ApplicationRef, ChangeDetectorRef} from '@angular/core';
import { Course, Picture} from './Course';
import { NzMessageService } from 'ng-zorro-antd/message';
@Component({
selector: 'app-form',
......@@ -10,19 +12,27 @@ import {Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, Ap
export class FormComponent implements OnInit, OnChanges, OnDestroy {
// 储存数据用
saveKey = "test_0011";
saveKey = "PU-17";
// 储存对象
item;
colorArr = [];
constructor(private appRef: ApplicationRef,private changeDetectorRef: ChangeDetectorRef) {
courseTypeArr = [];
constructor(private appRef: ApplicationRef,private changeDetectorRef: ChangeDetectorRef, private message: NzMessageService) {
}
ngOnInit() {
this.item = {};
this.item = new Course();
this.item.type = '01';
this.initColorArr();
this.initCourseType();
// 获取存储的数据
(<any> window).courseware.getData((data) => {
......@@ -30,7 +40,7 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
if (data) {
this.item = data;
}
console.log(this.item);
this.init();
this.changeDetectorRef.markForCheck();
this.changeDetectorRef.detectChanges();
......@@ -51,6 +61,37 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
init() {
if(!this.item.picArr){
this.item.picArr = [];
}
}
initColorArr(){
this.colorArr.push({code:'01',name:'红色', color:'#f3440d', picUrl:'assets/play/palette/red.png'});
this.colorArr.push({code:'02',name:'紫色', color:'#c80df3', picUrl:'assets/play/palette/purple.png'});
this.colorArr.push({code:'03',name:'绿色', color:'#26eb45', picUrl:'assets/play/palette/green.png'});
this.colorArr.push({code:'04',name:'蓝色', color:'#404dfb', picUrl:'assets/play/palette/blue.png'});
this.colorArr.push({code:'05',name:'橘色', color:'#ff9600', picUrl:'assets/play/palette/orange.png'});
this.colorArr.push({code:'06',name:'粉色', color:'#ff6073', picUrl:'assets/play/palette/pink.png'});
this.colorArr.push({code:'07',name:'天蓝色', color:'#07d6ff', picUrl:'assets/play/palette/skyBlue.png'});
this.colorArr.push({code:'08',name:'紫粉色', color:'#ff07ff', picUrl:'assets/play/palette/purplePink.png'});
}
initCourseType(){
this.courseTypeArr.push({code:'01', name:'文本'});
this.courseTypeArr.push({code:'02', name:'音频'});
this.courseTypeArr.push({code:'03', name:'图片'});
}
......@@ -58,19 +99,19 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
* 储存图片数据
* @param e
*/
onImageUploadSuccess(e, key) {
onImageUploadSuccess(e, item, key) {
this.item[key] = e.url;
this.save();
item[key] = e.url;
this.save();
}
/**
* 储存音频数据
* @param e
*/
onAudioUploadSuccess(e, key) {
onAudioUploadSuccess(e, item, key) {
this.item[key] = e.url;
item[key] = e.url;
this.save();
}
......@@ -93,5 +134,54 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
}, 1);
}
addPicItem() {
const picItem = new Picture();
this.item.picArr.push(picItem);
this.save();
}
delPicItem(index) {
if (index !== -1) {
this.item.picArr.splice(index, 1);
this.save();
}
}
onChange(event, item, key){
item[key] = event;
this.save();
}
validatorMaxLength(value, length){
if (!value) {
return true;
}
const chr = value.replace(' ','');
if (chr.length > length){
let id = this.message.error('超过' + length +'个字母', { nzDuration: 0 }).messageId;
setTimeout(() => {
this.message.remove(id);
}, 3000);
return false;
}
else{
return true;
}
}
saveContent(value) {
let result = this.validatorMaxLength(value, 20);
if (result) {
this.save();
}
}
}
This diff is collapsed.
import { MySprite } from './Unit';
interface AirWindow extends Window {
air: any;
curCtx: any;
}
declare let window: AirWindow;
export class Item {
/**图片集合 */
images;
audioObj;
_scaleX = 1;
_scaleY = 1;
ctx;
_width = 0;
_height = 0;
_x = 0;
_y = 0;
constructor(images, audioObj, scaleX = 1, scaleY = 1, ctx = null) {
this.images = images;
this.audioObj = audioObj;
this._scaleX = scaleX;
this._scaleY = scaleY;
if (!ctx) {
this.ctx = window.curCtx;
} else {
this.ctx = ctx;
}
}
set width(width){
this._width = width * this.scaleX;
}
get width(){
return this._width;
}
set height(height){
this._height = height * this.scaleY;
}
get height(){
return this._height;
}
set scaleX(v) {
this._scaleX = v;
}
get scaleX() {
return this._scaleX;
}
set scaleY(v) {
this._scaleY = v;
}
get scaleY() {
return this._scaleY;
}
set x(x){
this._x = x;
}
get x(){
return this._x;
}
set y(y){
this._y = y;
}
get y(){
return this._y;
}
getPic(picName, anchorX: number = 0.5, anchorY: number = 0.5) {
const pic = new MySprite();
pic.init(this.images.get(picName), anchorX, anchorY);
pic.scaleX = this.scaleX;
pic.scaleY = this.scaleY;
pic.x = 0;
pic.y = 0;
return pic;
}
checkClickTarget(target, mx: number, my: number) {
const rect = target.getBoundingBox();
if (this.checkPointInRect(mx, my, rect)) {
return true;
}
return false;
}
checkPointInRect(x, y, rect) {
if (x >= rect.x && x <= rect.x + rect.width) {
if (y >= rect.y && y <= rect.y + rect.height) {
return true;
}
}
return false;
}
}
\ No newline at end of file
import { Item } from './Item';
import { ShapeRect, MySprite } from './Unit';
export class PageBar extends Item {
bg: ShapeRect;
lastBtn: MySprite;
nextBtn: MySprite;
data;
_pageSize = 4;
_totalSize = 0;
curPage = 0;
totalPage = 0;
showPageBtn = false;
set pageSize(pageSize: number) {
if (pageSize <= 0) {
pageSize = 1;
}
this._pageSize = pageSize;
this.show();
}
get pageSize() {
return this._pageSize;
}
set totalSize(totalSize){
this._totalSize = totalSize;
this.show();
}
get totalSize(){
return this._totalSize;
}
set x(x){
this._x = x;
if(this.bg){
this.bg.x = this._x;
}
}
set y(y){
this._y = y;
if(this.bg){
this.bg.y = this._y;
}
}
init(data, pageSize = 1) {
this.data = data;
this._pageSize = pageSize;
this.width = 100;
this.height = 40;
const bg = new ShapeRect();
bg.setSize(this.width, this.height);
bg.alpha = 0;
bg.x = this._x;
bg.y = this._y;
this.bg = bg;
const lastBtn = this.getPic('last', 0, 0);
lastBtn.x = 0;
lastBtn.y = 0;
lastBtn.alpha = 0;
this.lastBtn = lastBtn;
bg.addChild(lastBtn);
const nextBtn = this.getPic('next', 1, 0);
nextBtn.x = this.width;
nextBtn.y = lastBtn.y;
nextBtn.alpha = 0;
this.nextBtn = nextBtn;
bg.addChild(nextBtn);
}
show() {
if (this.pageSize <= 0) {
this.pageSize = 1;
}
if (this.data) {
this._totalSize = this.data.length;
}
else {
this._totalSize = 0;
}
this.totalPage = Math.ceil(this.data.length / this.pageSize);
}
private showBtn() {
if(this.showPageBtn && this.totalPage > 1){
this.lastBtn.alpha = 1;
this.nextBtn.alpha = 1;
}
else{
if (this.curPage > 1) {
this.lastBtn.alpha = 1;
}
else {
this.lastBtn.alpha = 0;
}
if (this.curPage < this.totalPage) {
this.nextBtn.alpha = 1;
}
else {
this.nextBtn.alpha = 0;
}
}
}
next(callback) {
this.curPage = this.curPage + 1;
if(this.curPage > this.totalPage){
this.curPage = this.totalPage;
}
let tempData = this.getData(this.curPage);
this.showBtn();
if (callback) {
callback(tempData);
}
}
last(callback) {
this.curPage = this.curPage - 1;
if(this.curPage <= 0){
if(this.totalPage === 0){
this.curPage = 0;
}
else{
this.curPage = 1;
}
}
let tempData = this.getData(this.curPage);
this.showBtn();
if (callback) {
callback(tempData);
}
}
private getData(pageNum : number){
if(this.totalPage === 0){
return [];
}
let _pageNum = pageNum;
if(_pageNum > this.totalPage){
_pageNum = this.totalPage;
}
let start = (_pageNum - 1) * this.pageSize;
let end = _pageNum * this.pageSize;
end = end > this.totalSize ? this.totalSize : end;
let tempData = [];
for(let i = start; i < end; ++ i){
tempData.push(this.data[i]);
}
return tempData;
}
}
export class CyclePageBar extends PageBar{
next(callback) {
this.curPage = this.curPage + 1;
if(this.curPage > this.totalPage){
this.curPage = 0;
}
super.next(callback)
}
last(callback) {
this.curPage = this.curPage - 1;
if(this.curPage <= 0){
this.curPage = this.totalPage;
}
super.last(callback);
}
}
\ No newline at end of file
import { Item } from './Item';
import { ShapeRect, MySprite } from './Unit';
export class Palette extends Item {
colorCardArr = [];
bg: ShapeRect;
init() {
const palettePic = this.getPic('palette');
palettePic.x = palettePic.getBoundingBox().width / 2;
palettePic.y = palettePic.getBoundingBox().height / 2;
const bg = new ShapeRect();
this.bg = bg;
bg.setSize(palettePic.getBoundingBox().width, palettePic.getBoundingBox().height);
bg.alpha = 0;
bg.addChild(palettePic);
//初始化颜色卡片
this.initColorCard();
}
private initColorCard() {
const colorCardBg = new ShapeRect();
colorCardBg.setSize(684 * this.scaleX, 76 * this.scaleY);
colorCardBg.alpha = 0;
colorCardBg.x = 12 * this.scaleX;
colorCardBg.y = 19 * this.scaleY;
this.bg.addChild(colorCardBg);
const initCard = (color, x: number, y: number) => {
const colorCard = new ColorCard(this.images, this.audioObj, this.scaleX, this.scaleY);
colorCard.init(color);
colorCard.bg.x = x * this.scaleX;
colorCard.bg.y = y * this.scaleY;
colorCardBg.addChild(colorCard.bg);
return colorCard;
};
let y = 6;
//红色
const red = initCard('red', 24, y);
red.color = '#f3440d';
red.code = '01';
this.colorCardArr.push(red);
//紫色
const purple = initCard('purple', 107, y);
purple.color = '#c80df3';
purple.code = '02';
this.colorCardArr.push(purple);
//绿色
const green = initCard('green', 189, y);
green.color = '#26eb45';
green.code = '03';
this.colorCardArr.push(green);
//蓝色
const blue = initCard('blue', 270, y);
blue.color = '#26eb45';
blue.code = '04';
this.colorCardArr.push(blue);
//桔色
const orange = initCard('orange', 352, y);
orange.color = '#ff9600';
orange.code = '05';
this.colorCardArr.push(orange);
//粉红色
const pink = initCard('pink', 433, y);
pink.color = '#ff6073';
pink.code ='06';
this.colorCardArr.push(pink);
//天蓝色
const skyBlue = initCard('skyBlue', 515, y);
skyBlue.color = '#07d6ff';
skyBlue.code = '07'
this.colorCardArr.push(skyBlue);
//粉紫色
const purplePink = initCard('purplePink', 596, y);
purplePink.color = '#ff07ff';
purplePink.code = '08';
this.colorCardArr.push(purplePink);
}
}
export class ColorCard extends Item {
bg: ShapeRect;
lightPic: MySprite;
touched = false;
_color : string;
_code : string;
set color(color){
this._color = color;
}
get color(){
return this._color;
}
set code(code){
this._code = code;
}
get code(){
return this._code;
}
init(picName) {
const bg = new ShapeRect();
bg.setSize(66 * this.scaleX, 64 * this.scaleY);
bg.alpha = 0;
this.bg = bg;
const getPic = (par: ShapeRect, picName) => {
const pic = new MySprite();
pic.init(this.images.get(picName));
pic.scaleX = this.scaleX;
pic.scaleY = this.scaleY;
pic.x = par.width / 2;
pic.y = par.height / 2;
return pic;
};
const colorCardLight = getPic(bg, 'light');
colorCardLight.alpha = 0;
this.lightPic = colorCardLight;
bg.addChild(colorCardLight);
const colorCardPic = getPic(bg, picName);
bg.addChild(colorCardPic);
}
click(callback = null) {
this.touched = true;
this.lightPic.alpha = 1;
if (callback) {
callback();
}
}
touch(callback = null) {
this.touched = true;
this.lightPic.alpha = 1;
if (callback) {
callback();
}
}
moveout(callback = null) {
this.touched = false;
this.lightPic.alpha = 0;
if (callback) {
callback();
}
}
}
\ No newline at end of file
import {
MySprite,
moveItem,
removeItemFromArr,
rotateItem
} from './Unit';
export class Petal {
renderArr = [];
images;
ctx;
playing = true;
tempRenderArr = [];
constructor(renderArr, images, ctx) {
this.renderArr = renderArr;
this.images = images;
this.ctx = ctx;
this.tempRenderArr = [];
}
stop(callback = null) {
this.playing = false;
const checkFinish = () => {
if (this.tempRenderArr.length == 0) {
if (callback) {
callback();
}
}
else {
setTimeout(() => {
checkFinish();
}, 100);
}
}
checkFinish();
}
/**
* 显示结束花瓣
* @param rect {x,y,width, height} 花瓣显示位置及大小
* @param mapScale
* @param timeout 花瓣显示间隔
* @param kinds 花瓣种类,即花瓣图片样式数组个数
*/
showPetal(rect, mapScale: number, timeout: number, kinds = 9) {
if (!this.playing) {
return;
}
const petal = this.getPetal(rect, mapScale, kinds);
this.renderArr.push(petal);
this.tempRenderArr.push(petal);
let toY = rect.y + rect.height;
moveItem(petal, petal.x, toY + petal.height * petal.scaleY, petal['time'], () => {
removeItemFromArr(this.renderArr, petal);
removeItemFromArr(this.tempRenderArr, petal);
});
rotateItem(petal, petal['tr'], petal['time']);
setTimeout(() => {
this.showPetal(rect, mapScale, timeout);
}, timeout);
}
/**
* 得到花瓣
* @param rect
* @param mapScale
* @param kinds
*/
private getPetal(rect, mapScale, kinds) {
const petal = new MySprite(this.ctx);
const id = Math.ceil(Math.random() * kinds);
petal.init(this.images.get('petal_' + id));
const randomS = (Math.random() * 0.4 + 0.6) * mapScale;
petal.setScaleXY(randomS);
const randomR = Math.random() * 360;
petal.rotation = randomR;
const randomX = rect.x + Math.random() * rect.width;
petal.x = randomX;
petal.y = rect.y - petal.height / 2 * petal.scaleY;
const randomT = 0.5 + Math.random() * 2;
petal['time'] = randomT;
let randomTR = 360 * Math.random(); // - 180;
if (Math.random() < 0.5) { randomTR *= -1; }
petal['tr'] = randomTR;
return petal;
}
}
\ No newline at end of file
import { Item } from './Item';
import { ShapeRect, MySprite, shake } from './Unit';
import { playAudio } from './AudioUtil';
import { Star } from './StarUtil'
import { PageBar, CyclePageBar } from './PageBar';
export class Stage extends Item {
bg: ShapeRect;
data;
spacing = 27;
cardArr = [];
pageBar: PageBar;
tempCardArr = [];
set x(x) {
this._x = x;
if (this.bg) {
this.bg.x = this._x;
}
}
set y(y) {
this._y = y;
if (this.bg) {
this.bg.y = this._y;
}
}
set width(width) {
this._width = width;
if (this.bg) {
this.bg.width = this._width;
}
}
get width() {
return this._width;
}
init(data) {
this.data = data;
this.spacing = this.spacing * this.scaleX;
this.height = 296;
const bg = new ShapeRect();
bg.setSize(this.width, this.height);
bg.alpha = 0;
bg.x = this.x;
bg.y = this.y;
this.bg = bg;
this.initCard();
this.initPageBar();
this.showNextPage();
}
showLastPage(callback = null) {
this.pageBar.last((data) => {
this.showCard(data, callback);
});
}
showNextPage(callback = null) {
this.pageBar.next((data) => {
this.showCard(data, callback);
});
}
isEnd(){
let ended = true;
for(let i = 0; i < this.cardArr.length; ++ i){
let card = this.cardArr[i];
if(!card.answered){
ended = false;
break;
}
}
return ended;
}
private initCard() {
for (let i = 0; i < this.data.picArr.length; ++i) {
let picInfo = this.data.picArr[i];
const card = new Card(this.images, this.audioObj, this.scaleX, this.scaleY);
card.init(picInfo);
this.cardArr.push(card);
}
}
private initPageBar() {
const pageBar = new PageBar(this.images, this.audioObj, this.scaleX, this.scaleY);
pageBar.showPageBtn = true;
pageBar.init(this.cardArr, 4);
pageBar.show();
this.pageBar = pageBar;
this.pageBar.x = (this.bg.width - this.pageBar.bg.width) / 2;
this.pageBar.y = this.bg.height + 5 * this.scaleY;
this.bg.addChild(pageBar.bg);
}
private showCard(cardArr = [], callback = null) {
let width = 0;
let cardWidth = 276 * this.scaleX;
if (this.tempCardArr) {
for (let i = 0; i < this.tempCardArr.length; ++i) {
this.bg.removeChild(this.tempCardArr[i].bg);
}
}
this.tempCardArr = cardArr;
if (cardArr.length > 0) {
width = cardArr.length * cardWidth + (cardArr.length - 1) * this.spacing;
}
let disW = cardWidth + this.spacing;
let x = (this.width - width) / 2;
for (let i = 0; i < cardArr.length; ++i) {
let card = cardArr[i];
card.y = 0;
card.x = x + i * disW;
this.bg.addChild(card.bg);
}
if (callback) {
callback();
}
}
}
export class Card extends Item {
bg: ShapeRect;
picInfo;
answered = false;
cardLight: MySprite;
cardBox: MySprite;
set x(x) {
this._x = x;
if (this.bg) {
this.bg.x = this._x;
}
}
set y(y) {
this._y = y;
if (this.bg) {
this.bg.y = this._y;
}
}
init(picInfo) {
this.picInfo = picInfo;
this.width = 276;
this.height = 296;
const bg = new ShapeRect();
bg.setSize(this._width, this._height);
bg.alpha = 0;
bg.x = this.x;
bg.y = this.y;
this.bg = bg;
const cardBox = this.getPic('card_box');
cardBox.x = bg.width / 2;
cardBox.y = bg.height / 2;
bg.addChild(cardBox, 1);
this.cardBox = cardBox;
const cardLight = this.getPic('card_light');
cardLight.x = bg.width / 2 + 3 * this.scaleX;
cardLight.y = bg.height / 2 + 3 * this.scaleY;
cardLight.alpha = 0;
bg.addChild(cardLight, 3);
this.cardLight = cardLight;
this.initPic();
}
private initPic() {
const setScale = (pW, pH, child) => {
let width = child.width;
let height = child.height;
let sx = pW / width;
let sy = pH / height;
let scale = Math.min(sx, sy);
if (scale < 1) {
child.setScaleXY(scale);
}
}
const pic = this.getPic(this.picInfo.picUrl);
pic.x = this.bg.width / 2;
pic.y = this.bg.height / 2;
setScale(this.bg.width - 45 * this.scaleX, this.bg.height - 45 * this.scaleY, pic);
this.bg.addChild(pic, 2);
}
click(callback = null) {
if (this.answered) {
return;
}
this.cardLight.alpha = 1;
if (callback) {
callback();
}
}
hideLight(){
this.cardLight.alpha = 0;
}
fillColor(color){
this.cardBox.color = color;
}
checkRight(colorCode, color, callback = null, errCallback = null) {
if (!colorCode) {
this.showErr(errCallback);
return false;
}
if (colorCode === this.picInfo.color) {
this.showRight(color, callback);
return true;
}
else {
this.showErr(errCallback);
return false;
}
}
private showErr(callback = null) {
this.cardLight.alpha = 0;
playAudio(this.audioObj['wrong']);
shake(this.bg, 5, callback);
}
private showRight(color, callback = null) {
this.answered = true;
playAudio(this.audioObj['star']);
this.cardBox.color = color;
this.cardLight.alpha = 0;
if(callback){
callback();
}
}
}
\ No newline at end of file
import {
MySprite,
moveItem,
removeItemFromArr,
rotateItem,
hideItem
} from './Unit';
export class Star {
renderArr = [];
images;
ctx;
playing = true;
tempRenderArr = [];
constructor(renderArr, images, ctx) {
this.renderArr = renderArr;
this.images = images;
this.ctx = ctx;
this.tempRenderArr = [];
}
/**
* 显示小星星
* @param rect
* @param mapScale
* @param showTime 每个星星显示时间
* @param timeout 显示频率
* @param number 显示个数
*/
showStar(rect, mapScale: number, showTime = 2, timeout = 500, number = 10) {
if (!this.playing) {
return;
}
const star = this.getStar(rect, mapScale);
this.renderArr.push(star);
this.tempRenderArr.push(star);
hideItem(star, showTime, () => {
removeItemFromArr(this.renderArr, star);
removeItemFromArr(this.tempRenderArr, star);
});
rotateItem(star, star['tr'], star['time']);
setTimeout(() => {
if (this.tempRenderArr.length < number) {
this.showStar(rect, mapScale);
}
}, timeout);
}
stop(callback = null) {
this.playing = false;
const checkFinish = () => {
if (this.tempRenderArr.length == 0) {
if (callback) {
callback();
}
}
else {
setTimeout(() => {
checkFinish();
}, 100);
}
}
checkFinish();
}
/**
* 得到星星
* @param rect
* @param mapScale
*/
private getStar(rect, mapScale) {
//console.log('show star:', rect);
const star = new MySprite(this.ctx);
star.init(this.images.get('icon_star'));
const randomS = (Math.random() * 0.4 + 0.6) * mapScale;
star.setScaleXY(randomS);
const randomR = Math.random() * 360;
star.rotation = randomR;
const randomX = rect.x + Math.random() * rect.width;
star.x = randomX;
star.y = rect.y + Math.random() * rect.width;
const randomT = 0.5 + Math.random() * 2;
star['time'] = randomT;
let randomTR = 360 * Math.random(); // - 180;
if (Math.random() < 0.5) { randomTR *= -1; }
star['tr'] = randomTR;
return star;
}
}
\ No newline at end of file
import { Item } from './Item';
import { Course } from '../form/Course';
import { ShapeRect, MySprite, RichText } from './Unit';
import { AudioComponent } from './AudioUtil';
export class Title extends Item {
private _data;
bg: ShapeRect;
audio: AudioComponent;
set data(data) {
this._data = data;
}
get data() {
return this._data;
}
init(data) {
this._data = data;
if (!this._data) {
this._data = new Course();
this._data.type = '01';
}
this.initBg();
}
private initBg() {
const bg = new ShapeRect();
bg.alpha = 0;
this.bg = bg;
if (this._data.type === '01') {
this.initText();
}
else if (this._data.type === '02') {
this.initAudio();
}
else {
this.initPic();
}
}
private initAudio() {
let width = 528 * this.scaleX;
let height = 121 * this.scaleY;
this.bg.setSize(width, height);
const audio = new AudioComponent(this.images, this.audioObj, this.scaleX, this.scaleY);
audio.init(width, height);
audio.bg.x = 0;
audio.bg.y = 0;
this.audio = audio;
this.audio.setAudio(this.audioObj[this._data.audioUrl]);
this.bg.addChild(audio.bg);
}
private initPic() {
let width = 777 * this.scaleX;
let height = 158 * this.scaleY;
this.bg.setSize(width, height);
const picBg = new MySprite();
picBg.init(this.images.get('pic_bg'), 0, 0);
picBg.scaleX = this.scaleX;
picBg.scaleY = this.scaleY;
picBg.x = 0;
picBg.y = 0;
this.bg.addChild(picBg);
const picBg2 = new ShapeRect();
picBg2.setSize(748 * this.scaleX, 115 * this.scaleY);
picBg2.alpha = 0;
picBg2.x = (this.bg.width - picBg2.width) / 2;
picBg2.y = 33 * this.scaleY;
this.bg.addChild(picBg2);
const setScale = (pW, pH, child) => {
let width = child.width;
let height = child.height;
let sx = pW / width;
let sy = pH / height;
let scale = Math.min(sx, sy);
if (scale < 1) {
child.setScaleXY(scale);
}
}
const getPic = (par: ShapeRect, picUrl) => {
const pic = new MySprite();
pic.init(this.images.get(picUrl));
pic.x = par.width / 2;
pic.y = par.height / 2;
setScale(par.width, par.height, pic);
return pic;
};
const pic = getPic(picBg2, this.data.picUrl);
picBg2.addChild(pic);
}
private initText() {
let width = 730 * this.scaleX;
let height = 150 * this.scaleY;
this.bg.setSize(width, height);
const textBg = new MySprite();
textBg.init(this.images.get('text_bg'), 0, 0);
textBg.scaleX = this.scaleX;
textBg.scaleY = this.scaleY;
textBg.x = 0;
textBg.y = 0;
this.bg.addChild(textBg);
const textBg2 = new ShapeRect();
textBg2.setSize(707 * this.scaleX, 106 * this.scaleY);
textBg2.alpha = 0;
textBg2.x = (this.bg.width - textBg2.width) / 2;
textBg2.y = 31 * this.scaleY;
this.bg.addChild(textBg2);
let text = new RichText();
text.text = this.data.text;
text.fontColor = "#c57500";
text.fontSize = 34;
text.fontName = "BRLNSDB";
text.disH = 0;
text.textAlign = 'middle';
text.scaleX = this.scaleX;
text.scaleY = this.scaleY;
text.width = textBg2.width - 36 * this.scaleX;
text.refreshSize();
text.x = 18 * this.scaleX;
text.y = textBg2.height / 2;
textBg2.addChild(text);
}
}
\ No newline at end of file
......@@ -766,7 +766,55 @@ export class RichText extends Label {
// this.dataArr = dataArr;
}
refreshSize() {
this.ctx.save();
this.ctx.font = `${this.fontSize}px ${this.fontName}`;
this.ctx.textAlign = this.textAlign;
this.ctx.textBaseline = 'middle';
this.ctx.fontWeight = this.fontWeight;
const selfW = this.width;
const chr = this.text.split(' ');
let temp = '';
const row = [];
const w = selfW;
let maxWidth = 0;
const getMaxWidth = (text, maxWidth) => {
let width = this.ctx.measureText(text).width * this.scaleX;
if(maxWidth < width){
return width;
}
else{
return maxWidth;
}
};
for (const c of chr) {
if (this.ctx.measureText(temp).width * this.scaleX < w && this.ctx.measureText(temp + (c)).width * this.scaleX <= w) {
temp += ' ' + c;
maxWidth = getMaxWidth(temp, maxWidth);
} else {
maxWidth = getMaxWidth(temp, maxWidth);
row.push(temp);
temp = ' ' + c;
}
}
if (temp != ' ') {
row.push(temp);
}
this._height = this.fontSize * row.length + (row.length - 1) * this.disH;
this._width = maxWidth;
this.ctx.restore();
}
drawText() {
......@@ -777,55 +825,50 @@ export class RichText extends Label {
this.ctx.font = `${this.fontSize}px ${this.fontName}`;
this.ctx.textAlign = this.textAlign;
this.ctx.textBaseline = 'middle';
this.ctx.textBaseline = 'bottom';
this.ctx.fontWeight = this.fontWeight;
this.ctx.fillStyle = this.fontColor;
const selfW = this.width * this.scaleX;
const selfW = this.width;
const chr = this.text.split(' ');
let temp = '';
const row = [];
const w = selfW - 80;
const disH = (this.fontSize + this.disH) * this.scaleY;
const w = selfW;
const disH = (this.fontSize + this.disH);
for (const c of chr) {
if (this.ctx.measureText(temp).width < w && this.ctx.measureText(temp + (c)).width <= w) {
for (const c of chr) {
if (this.ctx.measureText(temp).width * this.scaleX < w && this.ctx.measureText(temp + (c)).width * this.scaleX <= w) {
temp += ' ' + c;
} else {
row.push(temp);
temp = ' ' + c;
}
}
row.push(temp);
if (temp != ' ') {
row.push(temp);
}
const x = 0;
const y = -row.length * disH / 2;
// for (let b = 0 ; b < row.length; b++) {
// this.ctx.strokeText(row[b], x, y + ( b + 1 ) * disH ); // 每行字体y坐标间隔20
// }
if (this._outlineFlag) {
this.ctx.lineWidth = this._outLineWidth;
this.ctx.strokeStyle = this._outLineColor;
for (let b = 0 ; b < row.length; b++) {
this.ctx.strokeText(row[b], x, y + ( b + 1 ) * disH ); // 每行字体y坐标间隔20
for (let b = 0; b < row.length; b++) {
this.ctx.strokeText(row[b], x, y + (b + 1) * disH); // 每行字体y坐标间隔20
}
// this.ctx.strokeText(this.text, 0, 0);
}
// this.ctx.fillStyle = '#ff7600';
for (let b = 0 ; b < row.length; b++) {
this.ctx.fillText(row[b], x, y + ( b + 1 ) * disH ); // 每行字体y坐标间隔20
for (let b = 0; b < row.length; b++) {
this.ctx.fillText(row[b], x, y + (b + 1) * disH); // 每行字体y坐标间隔20
}
}
......
This diff is collapsed.
const res = [
// ['bg', "assets/play/bg.jpg"],
['btn_left', "assets/play/btn_left.png"],
['btn_right', "assets/play/btn_right.png"],
// ['text_bg', "assets/play/text_bg.png"],
['bg', "assets/play/bg.png"],
['bg_grass', "assets/play/bg_grass.png"],
['bg_grass', "assets/play/bg_grass.png"],
['grass', "assets/play/grass.png"],
['stone', "assets/play/stone.png"],
['flower', "assets/play/flower.png"],
['people_1', "assets/play/people_1.png"],
['people_2', "assets/play/people_2.png"],
['cloud1', "assets/play/cloud1.png"],
['cloud2', "assets/play/cloud2.png"],
['bg_audio', "assets/play/bg_audio.png"],
['bg_audio_progress_bar', "assets/play/bg_audio_progress_bar.png"],
['btn_audio_off', "assets/play/btn_audio_off.png"],
['btn_audio_on', "assets/play/btn_audio_on.png"],
['processBtn', "assets/play/processBtn.png"],
['auto_cover', "assets/play/auto_cover.png"],
['pic_bg', "assets/play/pic_bg.png"],
['text_bg', "assets/play/text_bg.png"],
['last', "assets/play/last.png"],
['next', "assets/play/next.png"],
['palette', "assets/play/palette/palette.png"],
['light', "assets/play/palette/light.png"],
['blue', "assets/play/palette/blue.png"],
['green', "assets/play/palette/green.png"],
['orange', "assets/play/palette/orange.png"],
['pink', "assets/play/palette/pink.png"],
['purple', "assets/play/palette/purple.png"],
['red', "assets/play/palette/red.png"],
['purplePink', "assets/play/palette/purplePink.png"],
['skyBlue', "assets/play/palette/skyBlue.png"],
['card_box', "assets/play/card_box.png"],
['card_light', "assets/play/card_light.png"],
['icon_star', "assets/play/star.png"],
['petal_1', "assets/play/petal_1.png"],
['petal_2', "assets/play/petal_2.png"],
['petal_3', "assets/play/petal_3.png"],
['petal_4', "assets/play/petal_4.png"],
['petal_5', "assets/play/petal_5.png"],
['petal_6', "assets/play/petal_6.png"],
['petal_7', "assets/play/petal_7.png"],
['petal_8', "assets/play/petal_8.png"],
['petal_9', "assets/play/petal_9.png"]
];
......@@ -12,7 +57,10 @@ const res = [
const resAudio = [
['click', "assets/play/music/click.mp3"],
['into', "assets/play/music/into.mp3"],
['star', "assets/play/music/star.wav"],
['win', "assets/play/music/win.mp3"],
['wrong', "assets/play/music/wrong.mp3"],
];
export {res, resAudio};
export { res, resAudio };
src/assets/play/text_bg.png

293 Bytes | W: | H:

src/assets/play/text_bg.png

17.1 KB | W: | H:

src/assets/play/text_bg.png
src/assets/play/text_bg.png
src/assets/play/text_bg.png
src/assets/play/text_bg.png
  • 2-up
  • Swipe
  • Onion skin
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment