Commit 35300e0c authored by Chen Jiping's avatar Chen Jiping

perf:完成模板开发

parent 00dd4eef
...@@ -186,6 +186,14 @@ ...@@ -186,6 +186,14 @@
</nz-input-number> </nz-input-number>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item>
<nz-form-label [nzSpan]="6" nzFor="{{j}}.audioUrl">序号音频</nz-form-label>
<nz-form-control [nzSpan]="6">
<app-audio-recorder id="{{j}}.audioUrl" [audioUrl]="data.audioUrl"
(audioUploaded)="onAudioUploadSuccess($event, data, 'audioUrl')">
</app-audio-recorder>
</nz-form-control>
</nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="6">图片</nz-form-label> <nz-form-label [nzSpan]="6">图片</nz-form-label>
<nz-form-control [nzSpan]="6"> <nz-form-control [nzSpan]="6">
......
import {
Item
} from './Item'
import {
Label,
MySprite, tweenChange, ShapeRect, MyAnimation, ShapeRectNew
} from './Unit';
export class AudioComponent extends Item {
bg: ShapeRect;
curAudio;
btnPlay: MySprite;
btnStop: MySprite;
totalTimeLabel: Label;
curTimeLabel: Label;
paused = false;
ended = false;
progress: ShapeRectNew;
progressVal = 0;
progressBtn: MySprite;
touched = false;
touchX = 0;
/**进度条按钮当前坐标 */
curX = 0
progressInitX = 0;
init(width: number, height: number) {
const bg = new ShapeRect();
bg.setSize(width, height);
bg.alpha = 0;
this.bg = bg;
const audioPic = new MySprite();
audioPic.init(this.images.get("bg_audio"));
audioPic.scaleX = this.scaleX;
audioPic.scaleY = this.scaleY;
audioPic.x = bg.width / 2;
audioPic.y = bg.height / 2;
bg.addChild(audioPic);
const btnPlay = new MySprite();
btnPlay.init(this.images.get("btn_audio_off"), 0, 0);
btnPlay.scaleX = this.scaleX;
btnPlay.scaleY = this.scaleY;
btnPlay.x = 0;
btnPlay.y = 0;
const btnPlayBg = new ShapeRect();
btnPlayBg.setSize(btnPlay.getBoundingBox().width, btnPlay.getBoundingBox().height);
btnPlayBg.alpha = 0;
btnPlayBg.x = 429 * this.scaleX;
btnPlayBg.y = 31 * this.scaleY;
btnPlayBg.addChild(btnPlay);
bg.addChild(btnPlayBg);
this.btnPlay = btnPlayBg;
const btnStop = new MySprite();
btnStop.init(this.images.get("btn_audio_on"), 0, 0);
btnStop.scaleX = this.scaleX;
btnStop.scaleY = this.scaleY;
btnStop.x = btnPlay.x;
btnStop.y = btnPlay.y;
const btnStopBg = new ShapeRect();
btnStopBg.setSize(btnPlayBg.width, btnPlayBg.height);
btnStopBg.alpha = 0;
btnStopBg.x = btnPlayBg.x;
btnStopBg.y = btnPlayBg.y;
btnStopBg.addChild(btnStop);
bg.addChild(btnStopBg);
btnStopBg.visible = false;
this.btnStop = btnStopBg;
this.progressInitX = 42 * this.scaleX;
const progressBar = new MySprite();
progressBar.init(this.images.get("bg_audio_progress_bar"));
progressBar.scaleX = this.scaleX;
progressBar.scaleY = this.scaleY;
progressBar.x = this.progressInitX + progressBar.getBoundingBox().width / 2;
progressBar.y = 37 * this.scaleY + progressBar.getBoundingBox().height / 2;
bg.addChild(progressBar);
this.progressVal = progressBar.getBoundingBox().width;
const progress = new ShapeRectNew();
progress.setSize(0, progressBar.getBoundingBox().height, 13 * this.scaleX);
progress.x = this.progressInitX;
progress.y = 37 * this.scaleY;
progress.fillColor = "#c80df3";
bg.addChild(progress);
this.progress = progress;
const progressBtn = new MySprite();
progressBtn.init(this.images.get("processBtn"), 0.5, 0);
progressBtn.scaleX = this.scaleX;
progressBtn.scaleY = this.scaleY;
progressBtn.x = this.progressInitX;
progressBtn.y = progress.y - (progressBtn.getBoundingBox().height - progress.height) / 2;
bg.addChild(progressBtn);
this.progressBtn = progressBtn;
this.curX = progressBtn.x;
const timeLabel = () => {
const timeLabel = new Label();
timeLabel.text = "0:00";
timeLabel.fontColor = "#dc8300";
timeLabel.fontSize = 26;
timeLabel.fontName = "BRLNSR";
timeLabel.scaleX = this.scaleX;
timeLabel.scaleY = this.scaleY;
timeLabel.textAlign = 'middle';
timeLabel.refreshSize();
return timeLabel;
}
const totalTime = timeLabel();
totalTime.x = 343 * this.scaleX;
totalTime.y = 70 * this.scaleY + totalTime.getBoundingBox().height / 2;
bg.addChild(totalTime);
this.totalTimeLabel = totalTime;
const curTime = timeLabel();
curTime.x = 55 * this.scaleX;
curTime.y = totalTime.y;
bg.addChild(curTime);
this.curTimeLabel = curTime;
const autoCover = new MySprite();
autoCover.init(this.images.get("auto_cover"), 0, 0);
autoCover.scaleX = this.scaleX;
autoCover.scaleY = this.scaleY;
autoCover.x = (bg.width - autoCover.getBoundingBox().width) / 2;
autoCover.y = bg.height - autoCover.getBoundingBox().height - 17 * this.scaleY;
bg.addChild(autoCover);
}
setAudio(audio) {
if (!audio) {
this.bg.visible = false;
}
else {
this.bg.visible = true;
this.btnPlay.visible = true;
this.btnStop.visible = false;
audio.currentTime = 0;
}
this.curAudio = audio;
let playingTime = this.getPlayingTime();
let time = this.getTimeStr(playingTime.totalTime);
this.totalTimeLabel.text = time;
this.setPlayInfo(playingTime);
}
/**
*
* @param now true-重新开始播放,flase-继续播放
* @param callback
*/
playAudio(now = false, callback = null) {
if (!this.curAudio) {
return;
}
this.ended = false;
this.paused = false;
this.showPlayStatus();
this.showTime();
playAudio(this.curAudio, now, () => {
this.ended = true;
this.showPlayStatus();
if (callback) {
callback();
}
});
}
/**
* 暂停播放音频
* @param reset 暂停是否重置:true-是,false-否
* @param callback
*/
pauseAudio(reset = false, callback = null) {
if (!this.paused) {
if (!this.curAudio) {
return;
}
pauseAudio(this.curAudio, reset);
this.paused = true;
this.showPlayStatus();
}
if (callback) {
callback();
}
}
getPlayingTime() {
if (!this.curAudio) {
return { totalTime: 0, curTime: 0 };
}
return { totalTime: this.curAudio.duration, curTime: this.curAudio.currentTime }
}
getTotalTime() {
if (!this.curAudio) {
return 0;
}
return this.curAudio.duration;
}
touchProBtn(mx: number) {
this.touchX = mx;
this.curX = this.progressBtn.x;
this.touched = true;
}
drag2(toX: number, callback = null) {
let dis = toX - this.touchX;
this.drag(dis, callback);
}
/**
* 滚动条拖动
* @param dis 拖动距离
* @param callback 拖动后执行函数
*/
drag(dis: number, callback = null) {
let newX = this.curX + dis;
if (newX < this.progressInitX) {
newX = this.progressInitX;
}
else if (newX > this.progressInitX + this.progressVal) {
newX = this.progressInitX + this.progressVal;
}
this.progressBtn.x = newX;
let distence = newX - this.progressInitX;
this.setTimeByPercent(distence / this.progressVal);
this.setPlayInfo(this.getPlayingTime());
if (callback) {
callback();
}
}
/**
* 根据百分设置当前播放时间
* @param percent 百分比
* @param play 是否立即播放
*/
setTimeByPercent(percent: number, play = false) {
if (!this.curAudio) {
return;
}
let curTime = 0
if (percent > 1) {
curTime = this.curAudio.duration;
}
else if (percent < 0) {
curTime = 0;
}
else {
curTime = percent * this.curAudio.duration;
}
this.setTime(curTime, play);
}
/**
* 设置播放时间
* @param time 当前播放时间
* @param play 是否立即播放
*/
setTime(time: number, play = false) {
if (!this.curAudio) {
return;
}
let curTime = 0
if (time > this.curAudio.duration) {
curTime = this.curAudio.duration;
}
else if (time < 0) {
curTime = 0;
}
else {
curTime = time;
}
this.curAudio.currentTime = curTime;
if (play) {
this.curAudio.play();
}
}
showPlayStatus() {
this.btnPlay.visible = !this.btnPlay.visible;
this.btnStop.visible = !this.btnPlay.visible;
}
showTime() {
if (this.ended || this.paused) {
return;
}
setTimeout(() => {
let playingTime = this.getPlayingTime();
this.setPlayInfo(playingTime);
this.showTime();
}, 100);
}
setPlayInfo(playingTime) {
this.progressBtn.x = this.progressInitX + playingTime.curTime / playingTime.totalTime * this.progressVal;
this.progress.width = this.progressVal * playingTime.curTime / playingTime.totalTime;
let time = this.getTimeStr(playingTime.curTime);
this.curTimeLabel.text = time;
}
private getTimeStr(time: number) {
if (!time) {
return "0:00";
}
let sec = Math.ceil(time % 60);
let timeStr = Math.floor(time / 60) + ":" + (sec < 10 ? "0" + sec : sec);
return timeStr;
}
}
/**
*
* @param audio 音频
* @param now true-重新开始播放,flase-继续播放
* @param callback
*/
export function playAudio(audio, now = false, callback = null) {
if (audio) {
if (now) {
audio.pause();
audio.currentTime = 0;
}
if (callback) {
audio.onended = () => {
callback();
};
}
audio.play();
}
}
/**
* 暂停播放音频
* @param audio 音频
* @param reset 暂停是否重置:true-是,false-否
* @param callback
*/
export function pauseAudio(audio, reset = false, callback = null) {
if (audio) {
if (reset) {
audio.currentTime = 0;
}
audio.pause();
if (callback) {
callback();
}
}
}
\ No newline at end of file
import { text } from '@fortawesome/fontawesome-svg-core';
import { start } from 'repl';
import { LetterBean } from '../bean/ExercisesBean';
import { Label, Label2, ShapeRectNew, ShapeRect, LineRect, MySprite, Line, LabelText, ShapeCircle } from './Unit';
export class Exercises {
data;
bg: ShapeRectNew;
indexLabel: Label;
indexBg1: MySprite;
images;
index: number;
answered: Boolean = false;
wordBgArr: Array<Word> = [];
shown = false;
init(images, data) {
this.images = images;
this.data = data;
let height = 248;
let width = 470;
const bg = new ShapeRectNew();
bg.alpha = 0;
bg.fillColor = "#000000";
bg.setSize(width, height, 0);
this.bg = bg;
const textBg = new ShapeRect();
textBg.setSize(width, 82);
textBg.alpha = 0;
textBg.x = 0;
textBg.y = bg.height - textBg.height;
bg.addChild(textBg);
const textBgPic = new MySprite();
textBgPic.init(this.images.get('content_bg'));
textBgPic.x = bg.width / 2;
textBgPic.y = textBg.height / 2;
textBg.addChild(textBgPic);
this.initIndex(textBg);
//初始化单词
this.initContent(textBg);
//初始化图片
this.initPic();
this.answered = false;
}
private initIndex(parent: ShapeRect) {
const indexBg1 = new MySprite();
indexBg1.init(this.images.get('index_bg'));
indexBg1.x = 18 + indexBg1.width / 2;
indexBg1.y = parent.getBoundingBox().height / 2 - 4;
parent.addChild(indexBg1);
this.indexBg1 = indexBg1;
const indexLabel = new Label();
indexLabel.fontName = "FUTURAB";
indexLabel.fontSize = 36;
indexLabel.text = '' + this.index;
indexLabel.fontColor = "#567790";
indexLabel.alpha = 0;
indexLabel.refreshSize();
indexLabel.x = 18 + (50 - indexLabel.getBoundingBox().width) / 2;
indexLabel.y = parent.height / 2;
parent.addChild(indexLabel);
this.indexLabel = indexLabel;
}
private initPic() {
const pic = new MySprite();
pic.init(this.images.get(this.data.picUrl));
let w = pic.width;
let h = pic.height;
let scaleX = this.bg.width / w;
let scaleY = 150 / h;
let mapScale = Math.min(scaleX, scaleY);
//如果超过最大,则进行缩小
if (mapScale < 1) {
pic.setScaleXY(mapScale);
}
pic.x = this.bg.width / 2;
pic.y = 150 / 2;
console.log(pic.y);
this.bg.addChild(pic);
}
private initContent(parent: ShapeRect) {
const getLetterLabel = (letter) => {
const label = new Label();
label.fontName = "GOTHIC";
label.fontSize = 32;
label.text = letter.val;
if (letter.isFill == '1') {
label.fontColor = "#c8161e";
}
else {
label.fontColor = "#dcdddd";
}
label.refreshSize();
label.y = parent.height / 2;
return label;
}
const wordLabelArr = [];
let startX = 89;
for (let i = 0; i < this.data.wordArr.length; ++i) {
let word = this.data.wordArr[i];
let tX = startX;
let totalW = 0;
let tH = 0;
const wordObj = new Word();
for (let j = 0; j < word.letterArr.length; ++j) {
let letter = word.letterArr[j]
let label = getLetterLabel(letter);
parent.addChild(label);
let letterObj = new Letter();
letterObj.letter = label;
letterObj.isFill = letter.isFill;
wordObj.letterArr.push(letterObj);
let w = Math.ceil(label.getBoundingBox().width);
tH = Math.ceil(label.getBoundingBox().height);
let dw = 3;
//如果是填空,则增加下划线
if (letter.isFill == '1') {
startX += dw;
label.x = startX;
let underLine = new Line();
underLine.lineColor = "#858585";
underLine.lineWidth = 3;
underLine.y = label.y + label.getBoundingBox().height / 2;
underLine.x = startX;
underLine.setLine(w);
parent.addChild(underLine);
w += dw;
label.alpha = 0;
wordLabelArr.push(label);
}
else {
if (word.letterArr[j - 1] && word.letterArr[j - 1].isFill == '1') {
startX += dw;
}
label.x = startX;
}
startX += w;
totalW += w;
}
//不是末位,增加空格
if (i != this.data.wordArr.length - 1) {
let blank = new LetterBean();
blank.val = " ";
let label = getLetterLabel(blank);
wordLabelArr.push(label);
startX += label.getBoundingBox().width;
}
const wordBg = new ShapeRect();
wordBg.alpha = 0;
wordBg.setSize(totalW, tH);
wordBg.x = tX;
wordBg.y = (parent.height - tH) / 2;
wordObj.bg = wordBg
this.wordBgArr.push(wordObj);
parent.addChild(wordBg);
}
}
checkAnswer(answerIndex) {
if (this.data.answerIndex == answerIndex) {
this.indexLabel.alpha = 1;
this.answered = true;
return true;
}
return false;
}
showWord(index){
let word = this.wordBgArr[index];
if(!word){
return;
}
if(this.shown){
return;
}
for(let i =0; i < word.letterArr.length; ++ i){
word.letterArr[i].letter.alpha = 1;
}
let exsit = false;
for(let i = 0; i < this.wordBgArr.length; ++ i){
let tWord = this.wordBgArr[i];
for(let j =0; j < tWord.letterArr.length; ++ j){
if(tWord.letterArr[j].letter.alpha == 0){
exsit = true;
break;
}
}
//如果存在,则直接跳出
if(exsit){
break;
}
}
if(!exsit){
this.shown = true;
//处理单词显示
for(let i = 0; i < this.wordBgArr.length; ++ i){
let tWord = this.wordBgArr[i];
for(let j =0; j < tWord.letterArr.length; ++ j){
let letter = tWord.letterArr[j];
//修改字体颜色
if(letter.isFill == '0'){
letter.letter.fontColor = '#000000';
}
}
}
}
}
}
export class Word{
bg : ShapeRect;
letterArr : Array<Letter> = [];
}
export class Letter{
letter : Label;
isFill : String = '0';
}
\ No newline at end of file
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 {
Label,
MySprite, ShapeRectNew,
ShapeCircle,
tweenChange,
ShapeRect
} from './Unit';
import {
playAudio,
pauseAudio
} from './AudioUtil';
export class Listening {
audio;
images;
bg;
btnPlay;
btnStop;
playing = false;
constructor(audio, images) {
this.audio = audio;
this.images = images;
}
init(scaleX = 1, scaleY = 1) {
const bg = new ShapeRect();
const btnPlay = new MySprite();
btnPlay.init(this.images.get('play'));
btnPlay.scaleX = scaleX;
btnPlay.scaleY = scaleY;
btnPlay.x = btnPlay.getBoundingBox().width / 2
btnPlay.y = btnPlay.getBoundingBox().height / 2
this.btnPlay = btnPlay;
bg.addChild(btnPlay);
const btnStop = new MySprite();
btnStop.init(this.images.get('stop'));
btnStop.x = btnPlay.x;
btnStop.y = btnPlay.y;
btnStop.alpha = 0;
btnStop.scaleX = scaleX;
btnStop.scaleY = scaleY;
this.btnStop = btnStop;
bg.addChild(btnStop);
bg.setSize(btnPlay.getBoundingBox().width, btnPlay.getBoundingBox().height);
bg.alpha = 0;
this.bg = bg;
}
play(callback = null){
console.log('playing:', this.playing);
if(!this.playing){
this.playAudio(callback);
return this.audio;
}
else{
this.pauseAudio(callback);
}
return null;
}
reset(){
this.btnPlay.alpha = 1;
this.btnStop.alpha = 0;
this.playing = false;
}
playAudio(callback = null){
this.btnPlay.alpha = 0;
this.btnStop.alpha = 1;
playAudio(this.audio, false, callback);
this.playing = true;
return this.audio;
}
pauseAudio(callback = null){
this.btnPlay.alpha = 1;
this.btnStop.alpha = 0;
this.playing = false;
pauseAudio(this.audio, false, callback)
}
}
\ No newline at end of file
import {
Label,
MySprite, ShapeRect,
} from './Unit';
import {
playAudio,
pauseAudio
} from './AudioUtil';
export class Title {
titleBg: ShapeRect;
audio;
images;
titleData;
constructor(titleData, images) {
this.titleData = titleData;
this.images = images;
}
init(mapScaleX = 1, mapScaleY = 1) {
let titleBg = new ShapeRect();
//初始化标题1背景
const titePart1Bg = new ShapeRect();
titePart1Bg.fillColor="#567790";
let pWidth = 117 * mapScaleX;
let pHeight = 65 * mapScaleY;
titePart1Bg.setSize(pWidth, pHeight);
titePart1Bg.setShadow(4,4,0, 'rgba(0, 0, 0, 0.2)');
titePart1Bg.x = 0;
titleBg.addChild(titePart1Bg);
//标题1内容
const part1 = new Label();
part1.text = this.titleData.part1;
part1.textAlign = 'left';
part1.fontSize = 48;
part1.fontName = "BRLNSDB";
part1.fontColor = "#ffffff";
part1.setScaleXY(mapScaleX);
part1.refreshSize();
part1.x = pWidth - part1.getBoundingBox().width - 13 * mapScaleX;
part1.y = 5 * mapScaleY + part1.getBoundingBox().height / 2;
titleBg.addChild(part1);
//标题2内容
const part2 = new Label();
part2.text = this.titleData.part2;
part2.fontSize = 36;
part2.fontName = "FUTURA";
part2.fontColor = "#000000";
part2.setScaleXY(mapScaleX);
part2.refreshSize();
part2.x = titePart1Bg.getBoundingBox().width + 11 * mapScaleX;
part2.y = 16 * mapScaleY + part2.getBoundingBox().height / 2;
let height = Math.max(titePart1Bg.getBoundingBox().height, part2.getBoundingBox().height);
let width = titePart1Bg.getBoundingBox().width + part2.getBoundingBox().width + 11 * mapScaleX;
titePart1Bg.y = (height - pHeight)/2;
titleBg.setSize(width, height);
titleBg.alpha = 0;
titleBg.addChild(part2);
this.titleBg = titleBg;
}
getTitleBg(){
return this.titleBg;
}
setAudio(audio){
this.audio = audio;
}
playAudio(callback = null){
playAudio(this.audio, true, callback);
return this.audio;
}
pasueAudio(callback){
pauseAudio(this.audio, true, callback)
}
}
\ No newline at end of file
import TWEEN from '@tweenjs/tween.js'; import TWEEN from '@tweenjs/tween.js';
interface AirWindow extends Window { interface AirWindow extends Window {
air: any; air: any;
curCtx: any; curCtx: any;
} }
...@@ -188,7 +188,7 @@ export class MySprite extends Sprite { ...@@ -188,7 +188,7 @@ export class MySprite extends Sprite {
if (this.children.length <= 0) { return; } if (this.children.length <= 0) { return; }
for (const child of this.children) { for (const child of this.children) {
if (child === this) { if (child === this) {
if (this.visible) { if (this.visible) {
this.drawSelf(); this.drawSelf();
...@@ -243,14 +243,14 @@ export class MySprite extends Sprite { ...@@ -243,14 +243,14 @@ export class MySprite extends Sprite {
if (this.children[i]) { if (this.children[i]) {
if (this.children[i] !== this) { if (this.children[i] !== this) {
this.children.splice(i, 1); this.children.splice(i, 1);
i --; i--;
} }
} }
} }
} }
_changeChildAlpha(alpha) { _changeChildAlpha(alpha) {
for (const child of this.children) { for (const child of this.children) {
if (child !== this) { if (child !== this) {
child.alpha = alpha; child.alpha = alpha;
} }
...@@ -331,7 +331,7 @@ export class MySprite extends Sprite { ...@@ -331,7 +331,7 @@ export class MySprite extends Sprite {
} }
return {px, py, sx, sy}; return { px, py, sx, sy };
}; };
...@@ -348,7 +348,7 @@ export class MySprite extends Sprite { ...@@ -348,7 +348,7 @@ export class MySprite extends Sprite {
// const width = this.width * Math.abs(this.scaleX); // const width = this.width * Math.abs(this.scaleX);
// const height = this.height * Math.abs(this.scaleY); // const height = this.height * Math.abs(this.scaleY);
return {x, y, width, height}; return { x, y, width, height };
} }
} }
...@@ -378,10 +378,10 @@ export class ColorSpr extends MySprite { ...@@ -378,10 +378,10 @@ export class ColorSpr extends MySprite {
const c = this.ctx.getImageData(rect.x, rect.y, rect.width, rect.height); const c = this.ctx.getImageData(rect.x, rect.y, rect.width, rect.height);
for ( let i = 0; i < c.height; i++) { for (let i = 0; i < c.height; i++) {
for ( let j = 0; j < c.width; j++) { for (let j = 0; j < c.width; j++) {
const x = (i * 4) * c.width + ( j * 4 ); const x = (i * 4) * c.width + (j * 4);
const r = c.data[x]; const r = c.data[x];
const g = c.data[x + 1]; const g = c.data[x + 1];
const b = c.data[x + 2]; const b = c.data[x + 2];
...@@ -424,10 +424,10 @@ export class GrayscaleSpr extends MySprite { ...@@ -424,10 +424,10 @@ export class GrayscaleSpr extends MySprite {
const rect = this.getBoundingBox(); const rect = this.getBoundingBox();
const c = this.ctx.getImageData(rect.x, rect.y, rect.width, rect.height); const c = this.ctx.getImageData(rect.x, rect.y, rect.width, rect.height);
for ( let i = 0; i < c.height; i++) { for (let i = 0; i < c.height; i++) {
for ( let j = 0; j < c.width; j++) { for (let j = 0; j < c.width; j++) {
const x = (i * 4) * c.width + ( j * 4 ); const x = (i * 4) * c.width + (j * 4);
const r = c.data[x]; const r = c.data[x];
const g = c.data[x + 1]; const g = c.data[x + 1];
const b = c.data[x + 2]; const b = c.data[x + 2];
...@@ -484,7 +484,7 @@ export class BitMapLabel extends MySprite { ...@@ -484,7 +484,7 @@ export class BitMapLabel extends MySprite {
this.height = h; this.height = h;
let offX = -totalW / 2; let offX = -totalW / 2;
for (const label of labelArr) { for (const label of labelArr) {
label.x = offX; label.x = offX;
offX += label.width; offX += label.width;
} }
...@@ -645,6 +645,231 @@ export class Label extends MySprite { ...@@ -645,6 +645,231 @@ export class Label extends MySprite {
} }
export class LabelText {
private _val: string;
private _fontColor = "#000000";
private _underLine: boolean = false;
private _visiable = true;
set val(val) {
this._val = val;
}
get val() {
return this._val;
}
set fontColor(fontColor) {
this._fontColor = fontColor;
}
get fontColor() {
return this._fontColor;
}
set underLine(underLine) {
this._underLine = underLine;
}
get underLine() {
return this._underLine;
}
set visiable(visiable){
this._visiable = visiable;
}
get visiable(){
return this._visiable;
}
}
export class Label2 extends MySprite {
textArr: Array<LabelText> = [];
fontName = 'Verdana';
textAlign = 'left';
fontSize = 40;
fontColor = '#000000';
fontWeight = 900;
_maxWidth;
outline = 0;
outlineColor = '#ffffff';
_outlineFlag = false;
_outLineWidth;
_outLineColor;
underLineWidth: number;
underLineColor = "#000000";
constructor(ctx = null) {
super(ctx);
this.init();
}
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;
let text = "";
let count = 0;
for (let i = 0; i < this.textArr.length; ++i) {
if(this.textArr[i].underLine){
count ++;
continue;
}
text += this.textArr[i].val;
}
if(count > 0){
this._width = this.ctx.measureText(text).width + 36 * count + 4 * (count - 1);
}
else{
this._width = this.ctx.measureText(text).width;
}
this._height = this.fontSize;
this.refreshAnchorOff();
this.ctx.restore();
}
setMaxSize(w) {
this._maxWidth = w;
this.refreshSize();
if (this.width >= w) {
this.scaleX *= w / this.width;
this.scaleY *= w / this.width;
}
}
show(callBack = null) {
this.visible = true;
if (this.alpha >= 1) {
return;
}
const tween = new TWEEN.Tween(this)
.to({ alpha: 1 }, 800)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(() => {
if (callBack) {
callBack();
}
})
.start(); // Start the tween immediately.
}
setOutline(width = 5, color = '#ffffff') {
this._outlineFlag = true;
this._outLineWidth = width;
this._outLineColor = color;
}
drawText() {
if (!this.textArr) { return; }
this.ctx.font = `${this.fontSize}px ${this.fontName}`;
this.ctx.textAlign = this.textAlign;
this.ctx.textBaseline = 'middle';
this.ctx.fontWeight = this.fontWeight;
var startX = 0;
for (let i = 0; i < this.textArr.length; ++i) {
var text = this.textArr[i];
let width = this.ctx.measureText(text.val).width;
let tempStartX = startX;
let dW = 0;
if (text.underLine && this.underLineWidth > 0) {
this.ctx.save();
this.ctx.lineWidth = this.underLineWidth;
this.ctx.strokeStyle = this.underLineColor;
let lineY = this.fontSize / 2;
this.ctx.moveTo(tempStartX, lineY);
this.ctx.lineTo(tempStartX + 36, lineY);
this.ctx.stroke();
this.ctx.restore();
tempStartX += (36 - width) / 2;
dW = 36 ;
if(this.textArr[i + 1] && this.textArr[i + 1].underLine){
dW += 4 ;
}
}
else{
dW = width;
}
if (this._outlineFlag) {
this.ctx.lineWidth = this._outLineWidth;
this.ctx.strokeStyle = this._outLineColor;
this.ctx.strokeText(text.val, tempStartX, 0);
}
if (this.outline > 0) {
this.ctx.lineWidth = this.outline;
this.ctx.strokeStyle = this.outlineColor;
this.ctx.strokeText(text.val, tempStartX, 0);
}
this.ctx.fillStyle = text.fontColor ? text.fontColor : this.fontColor;
if(text.visiable){
this.ctx.fillText(text.val, tempStartX, 0);
}
startX += dW;
}
}
drawSelf() {
super.drawSelf();
this.drawText();
}
}
export class RichTextOld extends Label { export class RichTextOld extends Label {
textArr = []; textArr = [];
...@@ -656,7 +881,7 @@ export class RichTextOld extends Label { ...@@ -656,7 +881,7 @@ export class RichTextOld extends Label {
for (const word of words) { for (const word of words) {
const re = new RegExp(word, 'g'); const re = new RegExp(word, 'g');
newText = newText.replace( re, `#${word}#`); newText = newText.replace(re, `#${word}#`);
// newText = newText.replace(word, `#${word}#`); // newText = newText.replace(word, `#${word}#`);
} }
...@@ -758,7 +983,7 @@ export class RichTextOld extends Label { ...@@ -758,7 +983,7 @@ export class RichTextOld extends Label {
export class RichText extends Label { export class RichText extends Label {
disH = 30; disH = 30;
constructor(ctx?: any) { constructor(ctx?: any) {
super(ctx); super(ctx);
...@@ -794,7 +1019,7 @@ export class RichText extends Label { ...@@ -794,7 +1019,7 @@ export class RichText extends Label {
for (const c of chr) { for (const c of chr) {
if (this.ctx.measureText(temp).width < w && this.ctx.measureText(temp + (c)).width <= w) { if (this.ctx.measureText(temp).width < w && this.ctx.measureText(temp + (c)).width <= w) {
temp += ' ' + c; temp += ' ' + c;
} else { } else {
...@@ -814,16 +1039,16 @@ export class RichText extends Label { ...@@ -814,16 +1039,16 @@ export class RichText extends Label {
if (this._outlineFlag) { if (this._outlineFlag) {
this.ctx.lineWidth = this._outLineWidth; this.ctx.lineWidth = this._outLineWidth;
this.ctx.strokeStyle = this._outLineColor; this.ctx.strokeStyle = this._outLineColor;
for (let b = 0 ; b < row.length; b++) { for (let b = 0; b < row.length; b++) {
this.ctx.strokeText(row[b], x, y + ( b + 1 ) * disH ); // 每行字体y坐标间隔20 this.ctx.strokeText(row[b], x, y + (b + 1) * disH); // 每行字体y坐标间隔20
} }
// this.ctx.strokeText(this.text, 0, 0); // this.ctx.strokeText(this.text, 0, 0);
} }
// this.ctx.fillStyle = '#ff7600'; // this.ctx.fillStyle = '#ff7600';
for (let b = 0 ; b < row.length; b++) { for (let b = 0; b < row.length; b++) {
this.ctx.fillText(row[b], x, y + ( b + 1 ) * disH ); // 每行字体y坐标间隔20 this.ctx.fillText(row[b], x, y + (b + 1) * disH); // 每行字体y坐标间隔20
} }
} }
...@@ -1089,7 +1314,7 @@ export class MyAnimation extends MySprite { ...@@ -1089,7 +1314,7 @@ export class MyAnimation extends MySprite {
} }
showAllFrame() { showAllFrame() {
for (const frame of this.frameArr ) { for (const frame of this.frameArr) {
frame.alpha = 1; frame.alpha = 1;
} }
} }
...@@ -1119,7 +1344,7 @@ export class MyAnimation extends MySprite { ...@@ -1119,7 +1344,7 @@ export class MyAnimation extends MySprite {
this.frameArr[this.frameIndex].visible = false; this.frameArr[this.frameIndex].visible = false;
} }
this.frameIndex ++; this.frameIndex++;
if (this.frameIndex >= this.frameArr.length) { if (this.frameIndex >= this.frameArr.length) {
if (this.loop) { if (this.loop) {
this.frameIndex = 0; this.frameIndex = 0;
...@@ -1127,7 +1352,7 @@ export class MyAnimation extends MySprite { ...@@ -1127,7 +1352,7 @@ export class MyAnimation extends MySprite {
this.restartFlag = false; this.restartFlag = false;
this.frameIndex = 0; this.frameIndex = 0;
} else { } else {
this.frameIndex -- ; this.frameIndex--;
this.playEnd(); this.playEnd();
return; return;
} }
...@@ -1169,7 +1394,35 @@ export class MyAnimation extends MySprite { ...@@ -1169,7 +1394,35 @@ export class MyAnimation extends MySprite {
} }
export class Line extends MySprite{
lineColor = '#ffffff';
lineWidth = 10;
setLine(length){
this.width = length;
}
drawLine() {
this.ctx.save();
this.ctx.beginPath();
this.ctx.lineWidth = this.lineWidth;
this.ctx.strokeStyle = this.lineColor;
this.ctx.moveTo(this._offX, this._offY);
this.ctx.lineTo(this._offX + this.width, this._offY);
this.ctx.stroke();
this.ctx.restore();
}
drawSelf() {
super.drawSelf();
this.drawLine();
}
}
// --------=========== util func =============------------- // --------=========== util func =============-------------
...@@ -1188,7 +1441,7 @@ export function tweenChange(item, obj, time = 0.8, callBack = null, easing = nul ...@@ -1188,7 +1441,7 @@ export function tweenChange(item, obj, time = 0.8, callBack = null, easing = nul
tween.easing(easing); tween.easing(easing);
} }
if (update) { if (update) {
tween.onUpdate( (a, b) => { tween.onUpdate((a, b) => {
update(a, b); update(a, b);
}); });
} }
...@@ -1220,7 +1473,7 @@ export function rotateItem(item, rotation, time = 0.8, callBack = null, easing = ...@@ -1220,7 +1473,7 @@ export function rotateItem(item, rotation, time = 0.8, callBack = null, easing =
export function scaleItem(item, scale, time = 0.8, callBack = null, easing = null) { export function scaleItem(item, scale, time = 0.8, callBack = null, easing = null) {
const tween = new TWEEN.Tween(item).to({ scaleX: scale, scaleY: scale}, time * 1000); const tween = new TWEEN.Tween(item).to({ scaleX: scale, scaleY: scale }, time * 1000);
if (callBack) { if (callBack) {
tween.onComplete(() => { tween.onComplete(() => {
...@@ -1238,7 +1491,7 @@ export function scaleItem(item, scale, time = 0.8, callBack = null, easing = nul ...@@ -1238,7 +1491,7 @@ export function scaleItem(item, scale, time = 0.8, callBack = null, easing = nul
export function moveItem(item, x, y, time = 0.8, callBack = null, easing = null) { export function moveItem(item, x, y, time = 0.8, callBack = null, easing = null) {
const tween = new TWEEN.Tween(item).to({ x, y}, time * 1000); const tween = new TWEEN.Tween(item).to({ x, y }, time * 1000);
if (callBack) { if (callBack) {
tween.onComplete(() => { tween.onComplete(() => {
...@@ -1281,7 +1534,7 @@ export function hideItem(item, time = 0.8, callBack = null, easing = null) { ...@@ -1281,7 +1534,7 @@ export function hideItem(item, time = 0.8, callBack = null, easing = null) {
} }
const tween = new TWEEN.Tween(item) const tween = new TWEEN.Tween(item)
.to({alpha: 0}, time * 1000) .to({ alpha: 0 }, time * 1000)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth. // .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(() => { .onComplete(() => {
if (callBack) { if (callBack) {
...@@ -1308,7 +1561,7 @@ export function showItem(item, time = 0.8, callBack = null, easing = null) { ...@@ -1308,7 +1561,7 @@ export function showItem(item, time = 0.8, callBack = null, easing = null) {
item.visible = true; item.visible = true;
const tween = new TWEEN.Tween(item) const tween = new TWEEN.Tween(item)
.to({alpha: 1}, time * 1000) .to({ alpha: 1 }, time * 1000)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth. // .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(() => { .onComplete(() => {
if (callBack) { if (callBack) {
...@@ -1328,7 +1581,7 @@ export function alphaItem(item, alpha, time = 0.8, callBack = null, easing = nul ...@@ -1328,7 +1581,7 @@ export function alphaItem(item, alpha, time = 0.8, callBack = null, easing = nul
const tween = new TWEEN.Tween(item) const tween = new TWEEN.Tween(item)
.to({alpha}, time * 1000) .to({ alpha }, time * 1000)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth. // .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(() => { .onComplete(() => {
if (callBack) { if (callBack) {
...@@ -1348,7 +1601,7 @@ export function showStar(item, time = 0.8, callBack = null, easing = null) { ...@@ -1348,7 +1601,7 @@ export function showStar(item, time = 0.8, callBack = null, easing = null) {
const tween = new TWEEN.Tween(item) const tween = new TWEEN.Tween(item)
.to({alpha: 1, scale: 1}, time * 1000) .to({ alpha: 1, scale: 1 }, time * 1000)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth. // .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(() => { .onComplete(() => {
if (callBack) { if (callBack) {
...@@ -1368,7 +1621,7 @@ export function randomSortByArr(arr) { ...@@ -1368,7 +1621,7 @@ export function randomSortByArr(arr) {
const newArr = []; const newArr = [];
const tmpArr = arr.concat(); const tmpArr = arr.concat();
while (tmpArr.length > 0) { while (tmpArr.length > 0) {
const randomIndex = Math.floor( tmpArr.length * Math.random() ); const randomIndex = Math.floor(tmpArr.length * Math.random());
newArr.push(tmpArr[randomIndex]); newArr.push(tmpArr[randomIndex]);
tmpArr.splice(randomIndex, 1); tmpArr.splice(randomIndex, 1);
} }
...@@ -1392,7 +1645,7 @@ export function getPosByAngle(angle, len) { ...@@ -1392,7 +1645,7 @@ export function getPosByAngle(angle, len) {
const x = Math.sin(radian) * len; const x = Math.sin(radian) * len;
const y = Math.cos(radian) * len; const y = Math.cos(radian) * len;
return {x, y}; return { x, y };
} }
...@@ -1448,12 +1701,12 @@ export function circleMove(item, x0, y0, time = 2, addR = 360, xPer = 1, yPer = ...@@ -1448,12 +1701,12 @@ export function circleMove(item, x0, y0, time = 2, addR = 360, xPer = 1, yPer =
const r = getPosDistance(item.x, item.y, x0, y0); const r = getPosDistance(item.x, item.y, x0, y0);
let a = getAngleByPos(item.x, item.y, x0, y0); let a = getAngleByPos(item.x, item.y, x0, y0);
a += 90; a += 90;
const obj = {r, a}; const obj = { r, a };
item._circleAngle = a; item._circleAngle = a;
const targetA = a + addR; const targetA = a + addR;
const tween = new TWEEN.Tween(item).to({_circleAngle: targetA}, time * 1000); const tween = new TWEEN.Tween(item).to({ _circleAngle: targetA }, time * 1000);
if (callBack) { if (callBack) {
tween.onComplete(() => { tween.onComplete(() => {
...@@ -1464,7 +1717,7 @@ export function circleMove(item, x0, y0, time = 2, addR = 360, xPer = 1, yPer = ...@@ -1464,7 +1717,7 @@ export function circleMove(item, x0, y0, time = 2, addR = 360, xPer = 1, yPer =
tween.easing(easing); tween.easing(easing);
} }
tween.onUpdate( (item, progress) => { tween.onUpdate((item, progress) => {
// console.log(item._circleAngle); // console.log(item._circleAngle);
const r = obj.r; const r = obj.r;
...@@ -1487,7 +1740,7 @@ export function getPosDistance(sx, sy, ex, ey) { ...@@ -1487,7 +1740,7 @@ export function getPosDistance(sx, sy, ex, ey) {
const _x = ex - sx; const _x = ex - sx;
const _y = ey - sy; const _y = ey - sy;
const len = Math.sqrt( Math.pow(_x, 2) + Math.pow(_y, 2) ); const len = Math.sqrt(Math.pow(_x, 2) + Math.pow(_y, 2));
return len; return len;
} }
...@@ -1518,8 +1771,9 @@ export function formatTime(fmt, date) { ...@@ -1518,8 +1771,9 @@ export function formatTime(fmt, date) {
}; };
if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); } if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); }
for (const k in o) { for (const k in o) {
if (new RegExp('(' + k + ')').test(fmt)) { fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) if (new RegExp('(' + k + ')').test(fmt)) {
? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length))); fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1)
? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)));
} }
} }
return fmt; return fmt;
...@@ -1552,8 +1806,8 @@ export function jelly(item, time = 0.7) { ...@@ -1552,8 +1806,8 @@ export function jelly(item, time = 0.7) {
return; return;
} }
const data = arr[index]; const data = arr[index];
const t = tweenChange(item, {scaleX: data[0], scaleY: data[1]}, data[2], () => { const t = tweenChange(item, { scaleX: data[0], scaleY: data[1] }, data[2], () => {
index ++; index++;
run(); run();
}, TWEEN.Easing.Sinusoidal.InOut); }, TWEEN.Easing.Sinusoidal.InOut);
item.jellyTween = t; item.jellyTween = t;
...@@ -1576,7 +1830,7 @@ export function jelly(item, time = 0.7) { ...@@ -1576,7 +1830,7 @@ export function jelly(item, time = 0.7) {
export function showPopParticle(img, pos, parent, num = 20, minLen = 40, maxLen = 80, showTime = 0.4) { export function showPopParticle(img, pos, parent, num = 20, minLen = 40, maxLen = 80, showTime = 0.4) {
for (let i = 0; i < num; i ++) { for (let i = 0; i < num; i++) {
const particle = new MySprite(); const particle = new MySprite();
particle.init(img); particle.init(img);
......
...@@ -17,3 +17,39 @@ ...@@ -17,3 +17,39 @@
src: url("../../assets/font/BRLNSDB.TTF") ; src: url("../../assets/font/BRLNSDB.TTF") ;
} }
@font-face
{
font-family: 'FUTURAB';
src: url("../../assets/font/FUTURAB.TTF") ;
}
@font-face
{
font-family: 'GOTHIC';
src: url("../../assets/font/GOTHIC.TTF") ;
}
@font-face
{
font-family: 'GOTHICB';
src: url("../../assets/font/GOTHICB.TTF") ;
}
@font-face
{
font-family: 'TCB';
src: url("../../assets/font/TCB.TTF") ;
}
@font-face
{
font-family: 'FUTURA';
src: url("../../assets/font/Futura.ttc") ;
}
@font-face
{
font-family: 'FuturaStd';
src: url("../../assets/font/FuturaStd-Medium.otf") ;
}
import {Component, ElementRef, ViewChild, OnInit, Input, OnDestroy, HostListener} from '@angular/core'; import { Component, ElementRef, ViewChild, OnInit, Input, OnDestroy, HostListener } from '@angular/core';
import { import {
Label, MySprite,
MySprite, tweenChange, ShapeRectNew
} from './Unit'; } from './Unit';
import {res, resAudio} from './resources'; import { res, resAudio } from './resources';
import {Subject} from 'rxjs'; import { Subject } from 'rxjs';
import {debounceTime} from 'rxjs/operators'; import { debounceTime } from 'rxjs/operators';
import TWEEN from '@tweenjs/tween.js'; import TWEEN from '@tweenjs/tween.js';
import { Title } from './Title';
import { Listening } from './Listening';
import { Exercises} from './Exercises';
import { getDefaultExercisesBean, getDefaultLetterBean } from '../bean/ExercisesBean';
import { getDefaultTitle } from '../bean/TitleBean';
@Component({ @Component({
...@@ -22,8 +27,8 @@ import TWEEN from '@tweenjs/tween.js'; ...@@ -22,8 +27,8 @@ import TWEEN from '@tweenjs/tween.js';
}) })
export class PlayComponent implements OnInit, OnDestroy { export class PlayComponent implements OnInit, OnDestroy {
@ViewChild('canvas', {static: true }) canvas: ElementRef; @ViewChild('canvas', { static: true }) canvas: ElementRef;
@ViewChild('wrap', {static: true }) wrap: ElementRef; @ViewChild('wrap', { static: true }) wrap: ElementRef;
// 数据 // 数据
data; data;
...@@ -51,23 +56,29 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -51,23 +56,29 @@ export class PlayComponent implements OnInit, OnDestroy {
audioObj = {}; audioObj = {};
renderArr; //A皮肤显示框
skinRenderArr = [];
renderArr = [];
mapScale = 1; mapScale = 1;
canvasLeft; canvasLeft;
canvasTop; canvasTop;
saveKey = 'test_0011'; saveKey = 'YM4-10';
canTouch = true;
btnLeft; /**标题*/
btnRight; title: Title;
pic1;
pic2;
canTouch = true; listening: Listening;
curAudio;
exercisesArr: Array<Exercises> = [];
curPic; curIndex = 0;
@HostListener('window:resize', ['$event']) @HostListener('window:resize', ['$event'])
onResize(event) { onResize(event) {
...@@ -80,7 +91,7 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -80,7 +91,7 @@ export class PlayComponent implements OnInit, OnDestroy {
this.data = {}; this.data = {};
// 获取数据 // 获取数据
const getData = (<any> window).courseware.getData; const getData = (<any>window).courseware.getData;
getData((data) => { getData((data) => {
if (data && typeof data == 'object') { if (data && typeof data == 'object') {
...@@ -127,6 +138,10 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -127,6 +138,10 @@ export class PlayComponent implements OnInit, OnDestroy {
this.initCtx(); this.initCtx();
this.initData(); this.initData();
this.initView(); this.initView();
this.canTouch = true;
this.playAudio('page', true);
} }
initCtx() { initCtx() {
...@@ -288,7 +303,19 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -288,7 +303,19 @@ export class PlayComponent implements OnInit, OnDestroy {
} }
} }
pauseAudio(key, callback = null) {
const audio = this.audioObj[key];
if (audio) {
if (callback) {
audio.onended = () => {
callback();
};
}
audio.pause();
}
}
loadResources() { loadResources() {
const pr = []; const pr = [];
...@@ -354,7 +381,7 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -354,7 +381,7 @@ export class PlayComponent implements OnInit, OnDestroy {
checkClickTarget(target) { checkClickTarget(target) {
const rect = target.getBoundingBox(); const rect = target.getBoundingBox();
if (this.checkPointInRect(this.mx, this.my, rect)) { if (this.checkPointInRect(this.mx, this.my, rect)) {
return true; return true;
} }
...@@ -395,6 +422,10 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -395,6 +422,10 @@ export class PlayComponent implements OnInit, OnDestroy {
url = key; url = key;
} }
if (!key) {
return;
}
this.rawAudios.set(key, url); this.rawAudios.set(key, url);
const audio = new Audio(); const audio = new Audio();
...@@ -416,7 +447,13 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -416,7 +447,13 @@ export class PlayComponent implements OnInit, OnDestroy {
this.rawImages.set(url, url); this.rawImages.set(url, url);
} }
addUrlToImage(url, key) {
if (!key) {
key = url;
}
this.rawImages.set(key, url);
}
...@@ -432,9 +469,30 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -432,9 +469,30 @@ export class PlayComponent implements OnInit, OnDestroy {
*/ */
initDefaultData() { initDefaultData() {
if (!this.data.pic_url) { if (!this.data.exercisesArr) {
this.data.pic_url = 'assets/play/default/pic.jpg';
this.data.pic_url_2 = 'assets/play/default/pic.jpg'; this.data.exercisesArr = [];
for (let i = 0; i < 4; ++i) {
let exercises = getDefaultExercisesBean();
exercises.answerIndex = i + 1;
this.data.exercisesArr.push(exercises);
}
}
if (!this.data.title) {
this.data.title = getDefaultTitle();
}
//设置默认皮肤
if (!this.data.skin) {
this.data.skin = 'A';
} }
} }
...@@ -444,8 +502,58 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -444,8 +502,58 @@ export class PlayComponent implements OnInit, OnDestroy {
*/ */
initImg() { initImg() {
this.addUrlToImages(this.data.pic_url); //练习题图片
this.addUrlToImages(this.data.pic_url_2); for (let i = 0; i < this.data.exercisesArr.length; ++i) {
let exercises = this.data.exercisesArr[i];
if (exercises.picUrl) {
this.addUrlToImages(exercises.picUrl);
}
}
const loadBg = (skin, skinType) => {
if (skin.lt.picUrl) {
this.addUrlToImage(skin.lt.picUrl, skinType + "_" + skin.lt.picUrl);
}
if (skin.lm.picUrl) {
this.addUrlToImage(skin.lm.picUrl, skinType + "_" + skin.lm.picUrl);
}
if (skin.lb.picUrl) {
this.addUrlToImage(skin.lb.picUrl, skinType + "_" + skin.lb.picUrl);
}
if (skin.mt.picUrl) {
this.addUrlToImage(skin.mt.picUrl, skinType + "_" + skin.mt.picUrl);
}
if (skin.mb.picUrl) {
this.addUrlToImage(skin.mb.picUrl, skinType + "_" + skin.mb.picUrl);
}
if (skin.rt.picUrl) {
this.addUrlToImage(skin.rt.picUrl, skinType + "_" + skin.rt.picUrl);
}
if (skin.rm.picUrl) {
this.addUrlToImage(skin.rm.picUrl, skinType + "_" + skin.rm.picUrl);
}
if (skin.rb.picUrl) {
this.addUrlToImage(skin.rb.picUrl, skinType + "_" + skin.rb.picUrl);
}
}
if (this.data.skinA) {
loadBg(this.data.skinA, 'A');
}
if (this.data.skinB) {
loadBg(this.data.skinB, 'B');
}
} }
...@@ -454,13 +562,40 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -454,13 +562,40 @@ export class PlayComponent implements OnInit, OnDestroy {
*/ */
initAudio() { initAudio() {
// 音频资源
this.addUrlToAudioObj(this.data.audio_url);
this.addUrlToAudioObj(this.data.audio_url_2);
// 音效 // 音效
this.addUrlToAudioObj('click', this.rawAudios.get('click'), 0.3); this.addUrlToAudioObj('click', this.rawAudios.get('click'), 0.3);
this.addUrlToAudioObj('page', this.rawAudios.get('page'));
this.addUrlToAudioObj('right', this.rawAudios.get('right'));
//标题发音
if (this.data.title.audioUrl) {
this.addUrlToAudioObj('titleAudio', this.data.title.audioUrl);
}
//听力材料
if (this.data.listenAudioUrl) {
this.addUrlToAudioObj('listenAudio', this.data.listenAudioUrl);
}
//练习题音效
for (let i = 0; i < this.data.exercisesArr.length; ++i) {
let exercises = this.data.exercisesArr[i];
this.addUrlToAudioObj('index_' + i, exercises.audioUrl);
let wordArr = exercises.wordArr;
for(let j = 0; j < wordArr.length; ++ j){
this.addUrlToAudioObj('word_' + i + '_' + j, wordArr[j].audioUrl);
}
}
} }
...@@ -475,12 +610,21 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -475,12 +610,21 @@ export class PlayComponent implements OnInit, OnDestroy {
const s = Math.min(sx, sy); const s = Math.min(sx, sy);
this.mapScale = s; this.mapScale = s;
// this.mapScale = sx; this.renderArr = [];
// this.mapScale = sy;
this.skinRenderArr = [];
this.renderArr = []; this.listening = null;
this.curIndex = 0;
if (this.curAudio) {
this.curAudio.pause();
}
this.curAudio = null;
this.exercisesArr = [];
} }
...@@ -493,129 +637,167 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -493,129 +637,167 @@ export class PlayComponent implements OnInit, OnDestroy {
initView() { initView() {
this.initPic(); this.initBg();
this.initTitle();
this.initBottomPart(); this.initBottomPart();
this.initExercises();
} }
initBottomPart() { initBg() {
const btnLeft = new MySprite();
btnLeft.init(this.images.get('btn_left'));
btnLeft.x = this.canvasWidth - 150 * this.mapScale;
btnLeft.y = this.canvasHeight - 100 * this.mapScale;
btnLeft.setScaleXY(this.mapScale);
this.renderArr.push(btnLeft);
this.btnLeft = btnLeft; const getPic = (key, anchorX: number = 0.5, anchorY: number = 0.5) => {
const pic = new MySprite();
pic.init(this.images.get(key), anchorX, anchorY);
pic.setScaleXY(this.mapScale);
this.skinRenderArr.push(pic);
return pic;
}
const initBg = (skin, skinType) => {
//左上
if (skin.lt.picUrl) {
const pic = getPic(skinType + '_' + skin.lt.picUrl, 0, 0);
pic.x = 0;
pic.y = 0;
const btnRight = new MySprite(); }
btnRight.init(this.images.get('btn_right'));
btnRight.x = this.canvasWidth - 50 * this.mapScale;
btnRight.y = this.canvasHeight - 100 * this.mapScale;
btnRight.setScaleXY(this.mapScale);
this.renderArr.push(btnRight); //左中
if (skin.lm.picUrl) {
const pic = getPic(skinType + '_' + skin.lm.picUrl, 0);
pic.x = 0;
pic.y = (this.canvasHeight - pic.getBoundingBox().height) / 2;
}
this.btnRight = btnRight; //左下
} if (skin.lb.picUrl) {
const pic = getPic(skinType + '_' + skin.lb.picUrl, 0, 1);
pic.x = 0;
pic.y = this.canvasHeight;
}
initPic() { //中上
if (skin.mt.picUrl) {
const pic = getPic(skinType + '_' + skin.mt.picUrl, 0.5, 0);
pic.x = this.canvasWidth / 2;
pic.y = 0;
}
const maxW = this.canvasWidth * 0.7; //中下
if (skin.mb.picUrl) {
const pic = getPic(skinType + '_' + skin.mb.picUrl, 0.5, 1);
pic.x = this.canvasWidth / 2;
pic.y = this.canvasHeight;
}
const pic1 = new MySprite(); //右上
pic1.init(this.images.get(this.data.pic_url)); if (skin.rt.picUrl) {
pic1.x = this.canvasWidth / 2; const pic = getPic(skinType + '_' + skin.rt.picUrl, 1, 0);
pic1.y = this.canvasHeight / 2; pic.x = this.canvasWidth;
pic1.setScaleXY(maxW / pic1.width); pic.y = 0;
}
this.renderArr.push(pic1); //右中
this.pic1 = pic1; if (skin.rm.picUrl) {
const pic = getPic(skinType + '_' + skin.rm.picUrl, 1, 0.5);
pic.x = this.canvasWidth;
pic.y = this.canvasHeight / 2;
}
//右下
if (skin.rb.picUrl) {
const pic = getPic(skinType + '_' + skin.rb.picUrl, 1, 1);
pic.x = this.canvasWidth;
pic.y = this.canvasHeight;
}
}
const label1 = new Label(); if (this.data.skin === 'A') {
label1.text = this.data.text; if (this.data.skinA) {
label1.textAlign = 'center'; initBg(this.data.skinA, 'A');
label1.fontSize = 50; }
label1.fontName = 'BRLNSDB'; }
label1.fontColor = '#ffffff'; else {
if (this.data.skinB) {
initBg(this.data.skinB, 'B');
}
}
}
pic1.addChild(label1); initBottomPart() {
const listening = new Listening(this.audioObj['listenAudio'], this.images);
listening.init(this.mapScale, this.mapScale);
listening.bg.x = this.canvasWidth - listening.bg.width - 10 * this.mapScale;
listening.bg.y = this.canvasHeight - listening.bg.height - 8 * this.mapScale;
this.listening = listening;
this.renderArr.push(listening.bg);
}
initTitle() {
const title = new Title(this.data.title, this.images);
const pic2 = new MySprite(); title.init(this.mapScale, this.mapScale);
pic2.init(this.images.get(this.data.pic_url_2)); title.audio = this.audioObj['titleAudio'];
pic2.x = this.canvasWidth / 2 + this.canvasWidth; this.title = title;
pic2.y = this.canvasHeight / 2;
pic2.setScaleXY(maxW / pic2.width);
this.renderArr.push(pic2); title.titleBg.y = 0;
this.pic2 = pic2; title.titleBg.x = 0;
this.curPic = pic1; this.renderArr.push(title.titleBg);
} }
initExercises() {
btnLeftClicked() {
this.lastPage(); var dW = 586 * this.mapScale;
}
btnRightClicked() { var dH = 311 * this.mapScale;
this.nextPage(); let col = 2;
}
lastPage() { let rows = Math.ceil(this.data.exercisesArr.length / col);
if (this.curPic == this.pic1) { let startX = (this.canvasWidth - (col - 1) * dW) / 2;
return;
}
this.canTouch = false; let startY = 7 * this.mapScale + (this.canvasHeight - 7 * this.mapScale - ((rows - 1) * 63 * this.mapScale + rows * 248 * this.mapScale)) / 2;
const moveLen = this.canvasWidth;
tweenChange(this.pic1, {x: this.pic1.x + moveLen}, 1);
tweenChange(this.pic2, {x: this.pic2.x + moveLen}, 1, () => {
this.canTouch = true;
this.curPic = this.pic1;
});
}
nextPage() { let tempX = startX;
if (this.curPic == this.pic2) { for (let i = 0; i < this.data.exercisesArr.length; ++i) {
return;
}
this.canTouch = false; let item = this.data.exercisesArr[i];
let exercises = new Exercises();
exercises.index = i + 1;
exercises.init(this.images, item);
exercises.bg.setScaleXY(this.mapScale);
this.renderArr.push(exercises.bg);
const moveLen = this.canvasWidth; this.exercisesArr.push(exercises);
tweenChange(this.pic1, {x: this.pic1.x - moveLen}, 1);
tweenChange(this.pic2, {x: this.pic2.x - moveLen}, 1, () => {
this.canTouch = true;
this.curPic = this.pic2;
});
}
pic1Clicked() { exercises.bg.x = startX - exercises.bg.getBoundingBox().width / 2;
this.playAudio(this.data.audio_url); exercises.bg.y = startY;
}
pic2Clicked() { //换行
this.playAudio(this.data.audio_url_2); if ((i + 1) % col == 0) {
} startX = tempX;
startY += dH;
}
else {
startX += dW;
}
}
}
...@@ -625,23 +807,48 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -625,23 +807,48 @@ export class PlayComponent implements OnInit, OnDestroy {
return; return;
} }
if ( this.checkClickTarget(this.btnLeft) ) { if (this.curAudio) {
this.btnLeftClicked(); if (this.curAudio != this.listening.audio) {
return; this.curAudio.pause();
}
} }
if ( this.checkClickTarget(this.btnRight) ) { if (this.checkClickTarget(this.listening.bg)) {
this.btnRightClicked();
this.curAudio = this.listening.play(() => {
this.listening.reset();
});
return; return;
} }
if ( this.checkClickTarget(this.pic1) ) { if (this.curAudio) {
this.pic1Clicked(); if (this.curAudio == this.listening.audio) {
this.listening.pauseAudio();
}
else {
this.curAudio.pause();
}
}
if (this.checkClickTarget(this.title.titleBg)) {
this.curAudio = this.title.playAudio();
return; return;
} }
if ( this.checkClickTarget(this.pic2) ) { let clicked = false;
this.pic2Clicked();
for (let i = 0; i < this.exercisesArr.length; ++i) {
let exercises = this.exercisesArr[i];
if(this.checkClickTarget(exercises.bg)){
this.clickExercises(exercises, i);
}
}
if (clicked) {
return; return;
} }
...@@ -667,13 +874,63 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -667,13 +874,63 @@ export class PlayComponent implements OnInit, OnDestroy {
TWEEN.update(); TWEEN.update();
// ---------------------------------------------------------- // ----------------------------------------------------------
this.updateArr(this.skinRenderArr);
this.updateArr(this.renderArr); this.updateArr(this.renderArr);
} }
clickExercises(exercises: Exercises, index:number){
if(!exercises){
return;
}
if(!exercises.answered){
if(this.checkClickTarget(exercises.indexBg1)){
let flag = exercises.checkAnswer(this.curIndex + 1);
if(flag){
this.curIndex ++;
this.playAudio('right', true, ()=>{
let key = 'index_' + index;
this.curAudio = this.audioObj[key];
this.playAudio(key, true);
});
}
}
}
else{
if(this.checkClickTarget(exercises.indexBg1)){
let key = 'index_' + index;
this.curAudio = this.audioObj[key];
this.playAudio(key, true);
return;
}
for(let i = 0; i < exercises.wordBgArr.length; ++ i){
let wordBg = exercises.wordBgArr[i];
if(this.checkClickTarget(wordBg.bg)){
exercises.showWord(i);
let key = 'word_' + index + '_' + i;
this.curAudio = this.audioObj[key];
this.playAudio(key, true);
break;
}
}
}
}
} }
const res = [ const res = [
// ['bg', "assets/play/bg.jpg"], ['play', "assets/play/play.png"],
['btn_left', "assets/play/btn_left.png"], ['stop', "assets/play/stop.png"],
['btn_right', "assets/play/btn_right.png"], ['index_bg', "assets/play/index_bg.png"],
// ['text_bg', "assets/play/text_bg.png"], ['content_bg', "assets/play/content_bg.png"],
]; ];
...@@ -12,7 +11,8 @@ const res = [ ...@@ -12,7 +11,8 @@ const res = [
const resAudio = [ const resAudio = [
['click', "assets/play/music/click.mp3"], ['click', "assets/play/music/click.mp3"],
['right', "assets/play/music/right.mp3"],
['page', "assets/play/music/page.mp3"],
]; ];
export {res, resAudio}; export {res, resAudio};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment