Commit 4a413a6e authored by Chen Jiping's avatar Chen Jiping

feat:完成展示页面

parent 38200a85
/**
*
* @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 { getMaxScale, jelly, jellyPop, Label, Label2, LabelText, Line, MySprite, ShapeCircle, ShapeRect, tweenChange } from "./Unit";
export class Exercises {
data;
images;
indexBgColor;
index: number;
bg: ShapeRect;
closePic;
overturnPic;
bigCard : ShapeRect;
leftAnswer;
rightAnswer;
frontCard : ShapeRect;
backCard :ShapeRect;
answerLabel: Label2;
showLetterArr: Array<Label> = [];
scaleX = 1;
scaleY = 1;
indexLabel: Label;
indexLabelBg: ShapeCircle;
canClick = true;
canClickCard = false;
showed = false;
curCard;
init(images, indexBgColor, data, scaleX = 1, scaleY = 1) {
this.images = images;
this.data = data;
this.scaleX = scaleX;
this.scaleY = scaleY;
this.indexBgColor = indexBgColor;
this.initBg();
this.initIndex();
this.initCard();
}
initBg() {
let width = 500 * this.scaleY;
let height = 270 * this.scaleX;
const bg = new ShapeRect();
bg.setSize(width, height);
bg.fillColor = "#ffffff";
bg.setShadow(0, 2, 4, "rgba(0, 0, 0, 0.5)");
this.bg = bg;
let maxW = 400 * this.scaleX;
let maxH = 230 * this.scaleY;
const pic = new MySprite();
pic.init(this.images.get(this.data.picUrl));
pic.x = width / 2;
pic.y = height / 2;
bg.addChild(pic);
let mScale = getMaxScale(pic, maxW, maxH);
pic.setScaleXY(mScale);
}
initIndex() {
let indexBg = new ShapeCircle();
let r = 17.5 * this.scaleX;
indexBg.setRadius(r);
indexBg.fillColor = "#cddce4";
indexBg.x = this.bg.width - 16 * this.scaleX - r;
indexBg.y = 16 * this.scaleY + r;
indexBg.setShadow(0, 1, 3, "rgba(0, 0, 0, 0.5)");
this.bg.addChild(indexBg);
this.indexLabelBg = indexBg;
let index = new Label();
index.text = this.index + "";
index.textAlign = 'center';
index.fontSize = 36;
index.fontName = "GOTHICB";
index.fontColor = "#567790";
index.setScaleXY(this.scaleX);
index.refreshSize();
index.x = 0;
index.y = 0 +4 * this.scaleY;
indexBg.addChild(index);
index.alpha = 1;
this.indexLabel = index;
}
initCard(){
let w = 1000 * this.scaleX;
let h = 600 * this.scaleY
const bigCard = new ShapeRect();
bigCard.setSize(w, h);
bigCard.fillColor = "#ffffff";
bigCard.setShadow(0, 10,20, "rgba(0, 0, 0, 0.5)");
this.bigCard = bigCard;
this.initAnswer();
this.initBackCard();
this.curCard = this.frontCard;
this.closePic = this.getColsePic(bigCard);
this.overturnPic = this.getOverturnPic(bigCard);
bigCard.setScaleXY(0);
}
private getColsePic(parent) {
const closePic = new MySprite();
closePic.init(this.images.get('close'));
closePic.scaleX = this.scaleX;
closePic.scaleY = this.scaleY;
closePic.x = parent.width;
closePic.y = 0;
parent.addChild(closePic);
return closePic;
}
private getOverturnPic(parent) {
const overturnPic = new MySprite();
overturnPic.init(this.images.get('overturn'));
overturnPic.scaleX = this.scaleX;
overturnPic.scaleY = this.scaleY;
overturnPic.x = parent.width - 20 * this.scaleX - overturnPic.getBoundingBox().width / 2;
overturnPic.y = parent.height - 15 * this.scaleY - overturnPic.getBoundingBox().height / 2;
parent.addChild(overturnPic);
return overturnPic;
}
initAnswer() {
let frontCard = new ShapeRect();
frontCard.setSize(this.bigCard.width, this.bigCard.height);
frontCard.alpha = 0;
frontCard.x = 0;
frontCard.y = 0;
this.frontCard = frontCard;
this.bigCard.addChild(frontCard);
let dW = 25 * this.scaleX;
let w = 386 * this.scaleX;
let startX = (this.bigCard.width - (dW + w * 2)) / 2;
let leftAnswer = new ShapeRect();
this.getAnswerView(leftAnswer, this.data.leftAnswer);
leftAnswer.x = startX;
this.leftAnswer = leftAnswer;
frontCard.addChild(leftAnswer);
let rightAnswer = new ShapeRect();
this.getAnswerView(rightAnswer, this.data.rightAnswer);
rightAnswer.x = startX + w + dW;
this.rightAnswer = rightAnswer;
frontCard.addChild(rightAnswer);
}
getTextView(letterArr){
const getLabelText = (letter) => {
const text = new LabelText();
text.val = letter.val;
if (letter.isFill == '1') {
text.fontColor = "#c8161d";
}
else {
text.fontColor = "#000000";
}
text.underLine = false;
return text;
}
let labelTextArr = [];
for (let i = 0; i < letterArr.length; ++i) {
var letter = letterArr[i];
let label = getLabelText(letter);
labelTextArr.push(label);
}
const answer = new Label2();
answer.textArr = labelTextArr;
answer.fontSize = 88;
answer.fontName = "MMB";
answer.setScaleXY(this.scaleX);
answer.refreshSize();
return answer;
}
getAnswerView(answerBg, answerData) {
let w = 386 * this.scaleX;
let h = 514 * this.scaleY;
answerBg.setSize(w, h);
answerBg.fillColor = "#e5edf2";
answerBg.y = (this.bigCard.height - h) / 2;
let maxH = 257 * this.scaleY;
let maxW = w;
const pic = new MySprite();
pic.init(this.images.get(answerData.picUrl));
let scale = Math.min(maxW / pic.width, maxH / pic.height);
//如果小于1,则缩放图片
if (scale < 1) {
pic.setScaleXY(scale);
}
answerBg.addChild(pic);
pic.x = w / 2;
if(answerData.letterArr && answerData.letterArr.length > 0){
pic.y = h / 2 - 195 * this.scaleY + 257 * this.scaleY / 2;
const line = new ShapeRect();
line.setSize(180 * this.scaleX, 7 * this.scaleY);
line.fillColor = "#949494";
line.x = (w - line.width ) / 2;
line.y = h - line.height - 42 * this.scaleY;
answerBg.addChild(line);
answerBg.line = line;
let text = this.getTextView(answerData.letterArr);
text.x = (w - text.getBoundingBox().width) / 2;
text.y = h / 2 - 195 * this.scaleY + 325 * this.scaleY + text.getBoundingBox().height / 2;
text.alpha = 0;
answerBg.addChild(text);
answerBg.text = text;
}
else{
pic.y = h / 2;
}
}
initBackCard(){
let w = 960 * this.scaleX;
let h = 560 * this.scaleY;
let backCard = new ShapeRect();
backCard.setSize(w, h);
backCard.alpha = 0;
backCard.visible = false;
backCard.x = (this.bigCard.width - w)/ 2;
backCard.y = (this.bigCard.height - h) / 2;
this.backCard = backCard;
this.bigCard.addChild(backCard);
const pic = new MySprite();
pic.init(this.images.get(this.data.card.picUrl));
pic.x = w / 2;
pic.y = h / 2;
let scale = Math.min(w / pic.width, h / pic.height);
//如果小于1,则缩放图片
if (scale < 1) {
pic.setScaleXY(scale);
}
backCard.addChild(pic);
}
/**
* 显示大卡片
*/
showBigCard(toX: number, toY: number, callback = null) {
if (this.showed) {
return;
}
this.bigCard.x = this.bg.x;
this.bigCard.y = this.bg.y;
tweenChange(this.bigCard, { scaleX: 1, scaleY: 1, x: toX, y: toY }, 0.5, () => {
this.canClickCard = true;
this.showed = true;
if (callback) {
callback();
}
});
}
overturn(scaleX: number, callback = null) {
if (!this.canClick) {
return;
}
if (!this.canClickCard) {
return;
}
let tempScaleX = scaleX;
this.canClickCard = false;
let tScaleX = this.closePic.scaleX;
let tScaleY = this.closePic.scaleY;
tweenChange(this.closePic, { scaleX: tScaleX * 1.1, scaleY: tScaleY * 1.1 }, 0.1, () => {
tweenChange(this.closePic, { scaleX: 0, scaleY: 0 }, 0.4, () => {
});
});
tweenChange(this.overturnPic, { scaleX: tScaleX * 1.1, scaleY: tScaleY * 1.1 }, 0.1, () => {
tweenChange(this.overturnPic, { scaleX: 0, scaleY: 0 }, 0.4, () => {
});
});
tweenChange(this.bigCard, { scaleX: 0 }, 0.3, () => {
this.curCard.visible = false;
tweenChange(this.bigCard, { scaleX: tempScaleX }, 0.3, () => {
if(this.curCard == this.frontCard){
this.backCard.visible = true;
this.curCard = this.backCard;
}
else{
this.frontCard.visible = true;
this.curCard = this.frontCard;
}
tweenChange(this.closePic, { scaleX: tScaleX * 1.1, scaleY: tScaleY * 1.1 }, 0.4, () => {
tweenChange(this.closePic, { scaleX: tScaleX, scaleY: tScaleY }, 0.1, () => {
});
});
tweenChange(this.overturnPic, { scaleX: tScaleX * 1.1, scaleY: tScaleY * 1.1 }, 0.4, () => {
tweenChange(this.overturnPic, { scaleX: tScaleX, scaleY: tScaleY }, 0.1, () => {
this.canClickCard = true;
callback && callback();
});
});
});
});
}
close(callback = null) {
this.canClickCard = false;
this.showed = false;
let toX = this.bg.x;
let toY = this.bg.y;
tweenChange(this.bigCard, { scaleX: 0, scaleY: 0, x: toX, y: toY }, 0.5, () => {
if (this.backCard.visible) {
this.frontCard.visible = true;
this.backCard.visible = false;
}
if(this.leftAnswer.line){
this.leftAnswer.line.alpha = 1;
this.leftAnswer.text.alpha = 0;
}
if(this.rightAnswer.line){
this.rightAnswer.line.alpha = 1;
this.rightAnswer.text.alpha = 0;
}
this.curCard = this.frontCard;
callback && callback();
});
}
}
\ No newline at end of file
import { Label, ShapeCircle, ShapeRect } from "./Unit";
export class Letter{
data;
images;
bgColor;
scaleX = 1;
scaleY = 1;
bg : ShapeRect;
init(images, data, bgColor, scaleX = 1, scaleY = 1) {
this.images = images;
this.data = data;
this.bgColor = bgColor;
this.scaleX = scaleX;
this.scaleY = scaleY;
this.initBg();
let letter = this.initView();
let w = letter.getBoundingBox().width;
let h = letter.getBoundingBox().height;
this.bg.setSize(w, h);
letter.x = w / 2;
letter.y = h / 2;
}
initBg(){
let bg = new ShapeRect();
bg.alpha = 0;
bg.fillColor = this.bgColor;
this.bg = bg;
}
initView(){
const letter = new Label();
letter.text = this.data.val;
letter.textAlign = 'center';
letter.fontSize = 36;
letter.fontName = "GOTHICB";
letter.fontColor = "#fdcf00";
letter.setScaleXY(this.scaleX);
letter.refreshSize();
this.bg.addChild(letter);
return letter;
}
}
\ 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 = "tt0142m";
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)
}
}
...@@ -709,6 +709,231 @@ export class Label extends MySprite { ...@@ -709,6 +709,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 = [];
...@@ -1235,7 +1460,35 @@ export class MyAnimation extends MySprite { ...@@ -1235,7 +1460,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 =============-------------
......
import {Component, ElementRef, ViewChild, OnInit, Input, OnDestroy, HostListener} from '@angular/core'; import { Component, ElementRef, ViewChild, OnInit, Input, OnDestroy, HostListener } from '@angular/core';
import { import {
jelly,
Label, Label,
MySprite, tweenChange, MySprite, removeItemFromArr, ShapeRect, ShapeRectNew, tweenChange,
} 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 { Letter } from './Letter';
import { Exercises } from './Exercises.spreat';
import { getDefaultExercises } from '../bean/Exercises';
import { getDefaultTile } from '../bean/TitleBean';
...@@ -22,8 +29,8 @@ import TWEEN from '@tweenjs/tween.js'; ...@@ -22,8 +29,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;
...@@ -52,6 +59,9 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -52,6 +59,9 @@ export class PlayComponent implements OnInit, OnDestroy {
audioObj = {}; audioObj = {};
renderArr; renderArr;
bigCardRenderArr;
mapScale = 1; mapScale = 1;
canvasLeft; canvasLeft;
...@@ -61,6 +71,20 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -61,6 +71,20 @@ export class PlayComponent implements OnInit, OnDestroy {
canTouch = true; canTouch = true;
/**标题*/
title: Title;
listening: Listening;
curAudio;
letterArr: Array<Letter>;
exercisesArr: Array<Exercises> = [];
mask: ShapeRect;
curExer;
@HostListener('window:resize', ['$event']) @HostListener('window:resize', ['$event'])
onResize(event) { onResize(event) {
...@@ -73,13 +97,13 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -73,13 +97,13 @@ 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') {
this.data = data; this.data = data;
} }
// console.log('data:' , data); console.log('data:', data);
// 初始化 各事件监听 // 初始化 各事件监听
this.initListener(); this.initListener();
...@@ -290,6 +314,8 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -290,6 +314,8 @@ export class PlayComponent implements OnInit, OnDestroy {
} }
audio.play(); audio.play();
} }
return audio;
} }
...@@ -435,8 +461,25 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -435,8 +461,25 @@ export class PlayComponent implements OnInit, OnDestroy {
* 添加默认数据 便于无数据时的展示 * 添加默认数据 便于无数据时的展示
*/ */
initDefaultData() { initDefaultData() {
if (!this.data.title) {
this.data.title = getDefaultTile();
}
if (!this.data.letterArr) {
this.data.letterArr = [];
}
if (!this.data.exercisesArr) {
this.data.exercisesArr = [];
}
for (let i = this.data.exercisesArr.length; i < 4; ++i) {
let exercises = getDefaultExercises();
this.data.exercisesArr.push(exercises);
}
} }
...@@ -445,7 +488,26 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -445,7 +488,26 @@ export class PlayComponent implements OnInit, OnDestroy {
*/ */
initImg() { initImg() {
for (let i = 0; i < this.data.exercisesArr.length; ++i) {
let exercises = this.data.exercisesArr[i];
if (exercises.picUrl) {
this.addUrlToImages(exercises.picUrl);
}
if (exercises.leftAnswer && exercises.leftAnswer.picUrl) {
this.addUrlToImages(exercises.leftAnswer.picUrl);
}
if (exercises.rightAnswer && exercises.rightAnswer.picUrl) {
this.addUrlToImages(exercises.rightAnswer.picUrl);
}
if (exercises.card && exercises.card.picUrl) {
this.addUrlToImages(exercises.card.picUrl);
}
}
} }
/** /**
...@@ -462,6 +524,44 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -462,6 +524,44 @@ export class PlayComponent implements OnInit, OnDestroy {
this.addUrlToAudioObj('turn', this.rawAudios.get('turn')); this.addUrlToAudioObj('turn', this.rawAudios.get('turn'));
//标题发音
if (this.data.title.audioUrl) {
this.addUrlToAudioObj('titleAudio', this.data.title.audioUrl);
}
//听力材料
if (this.data.audioUrl) {
this.addUrlToAudioObj('listenAudio', this.data.audioUrl);
}
for (let i = 0; i < this.data.letterArr.length; ++i) {
let letter = this.data.letterArr[i];
if (letter.audioUrl) {
this.addUrlToAudioObj(letter.audioUrl);
}
}
//练习题音效
for (let i = 0; i < this.data.exercisesArr.length; ++i) {
let exercises = this.data.exercisesArr[i];
if (exercises.leftAnswer && exercises.leftAnswer.audioUrl) {
this.addUrlToAudioObj(exercises.leftAnswer.audioUrl);
}
if (exercises.rightAnswer && exercises.rightAnswer.audioUrl) {
this.addUrlToAudioObj(exercises.rightAnswer.audioUrl);
}
if (exercises.card && exercises.card.audioUrl) {
this.addUrlToAudioObj(exercises.card.audioUrl);
}
}
} }
...@@ -476,13 +576,20 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -476,13 +576,20 @@ 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.mapScale = sy;
this.renderArr = []; this.renderArr = [];
if (this.curAudio) {
this.curAudio.pause();
}
this.curAudio = null;
this.letterArr = [];
this.bigCardRenderArr = [];
this.exercisesArr = [];
} }
...@@ -494,15 +601,160 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -494,15 +601,160 @@ export class PlayComponent implements OnInit, OnDestroy {
initView() { initView() {
this.initTitle();
this.initBottomPart();
this.initLetter();
this.initExercises();
} }
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);
title.init(this.mapScale, this.mapScale);
title.audio = this.audioObj['titleAudio'];
this.title = title;
title.titleBg.y = 0;
title.titleBg.x = 0;
this.renderArr.push(title.titleBg);
}
initLetter() {
let w = 680 * this.mapScale;
let h = 67.6 * this.mapScale;
let letterBg = new ShapeRect();
letterBg.setSize(w, h);
letterBg.alpha = 0;
letterBg.y = 0;
letterBg.x = this.canvasWidth / 2 - 184 * this.mapScale;
this.renderArr.push(letterBg);
let letterPic = new MySprite();
letterPic.init(this.images.get('letter-bg'));
letterPic.setScaleXY(this.mapScale);
letterPic.x = w / 2;
letterPic.y = h / 2;
letterBg.addChild(letterPic);
let letterArr = this.data.letterArr;
let dW = 27 * this.mapScale;
let tW = (letterArr.length - 1) * dW;
let y = 13 * this.mapScale;
for (let i = 0; i < letterArr.length; ++i) {
let letter = new Letter();
letter.init(this.images, letterArr[i], this.data.backgroudColor, this.mapScale, this.mapScale);
letter.bg.y = y;
letterBg.addChild(letter.bg);
this.letterArr.push(letter);
tW += letter.bg.width;
}
let startX = (letterBg.width - tW) / 2;
for (let i = 0; i < this.letterArr.length; ++i) {
let letter = this.letterArr[i];
letter.bg.x = startX + i * dW;
startX += letter.bg.width;
}
}
initExercises() {
let w = 500 * this.mapScale;
let dW = 44 * this.mapScale;
let dH = 38 * this.mapScale;
let startX = (this.canvasWidth - (w * 2 + dW * (2 - 1))) / 2;
let startY = this.canvasHeight / 2 - 247 * this.mapScale;
let tempStartX = startX;
const getView = (item, index, x = 0, y = 0) => {
let exercises = new Exercises();
exercises.index = index;
exercises.init(this.images, this.data.backgroudColor, item, this.mapScale, this.mapScale);
exercises.bg.x = x;
exercises.bg.y = y;
return exercises;
}
let index = 1;
for (let i = 0; i < this.data.exercisesArr.length; ++i) {
let exercises = getView(this.data.exercisesArr[i], index, startX, startY);
if (index % 2 == 0) {
//到下一行恢复起始x坐标
startX = tempStartX;
startY += exercises.bg.height + dH;
}
else {
startX += exercises.bg.width + dW;
}
this.renderArr.push(exercises.bg);
this.exercisesArr.push(exercises);
index += 1;
}
const mask = new ShapeRect();
mask.setSize(this.canvasWidth, this.canvasHeight);
mask.visible = false;
mask.alpha = 0.3
mask.fillColor = "#000000";
this.renderArr.push(mask);
this.mask = mask;
}
...@@ -512,7 +764,117 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -512,7 +764,117 @@ export class PlayComponent implements OnInit, OnDestroy {
return; return;
} }
if (this.curAudio) {
if (this.curAudio != this.listening.audio) {
this.curAudio.pause();
}
}
if (this.checkClickTarget(this.listening.bg)) {
this.curAudio = this.listening.play(() => {
this.listening.reset();
});
return;
}
if (this.curAudio) {
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;
}
for (let i = 0; i < this.letterArr.length; ++i) {
let letter = this.letterArr[i];
if (this.checkClickTarget(letter.bg)) {
this.curAudio = this.playAudio(letter.data.audioUrl, true);
break;
}
}
for (let i = 0; i < this.exercisesArr.length; ++i) {
let exer = this.exercisesArr[i];
if (!exer.canClick) {
continue;
}
if (this.checkClickTarget(exer.bg) && !exer.showed) {
this.curExer = exer;
this.playAudio('open', true);
this.mask.visible = true;
if (this.bigCardRenderArr.indexOf(exer.bigCard) == -1) {
this.bigCardRenderArr.push(exer.bigCard);
}
exer.showBigCard((this.canvasWidth - exer.bigCard.width) / 2, (this.canvasHeight - exer.bigCard.height) / 2, () => {
//将其它词组设置为不可点击
for (let j = 0; j < this.exercisesArr.length; ++j) {
if (i != j) {
this.exercisesArr[j].canClick = false;
}
}
});
break;
}
}
if (this.curExer && this.curExer.canClickCard) {
let target;
let callback;
if (this.checkClickTarget(this.curExer.overturnPic)) {
target = this.curExer.overturnPic;
callback = this.clickOverTurn.bind(this);
}
else if (this.checkClickTarget(this.curExer.closePic)) {
target = this.curExer.closePic;
callback = this.clickClose.bind(this);
}
else if (this.curExer.frontCard.visible && this.checkClickTarget(this.curExer.leftAnswer)) {
target = this.curExer.leftAnswer;
callback = this.clickLeft.bind(this);
}
else if (this.curExer.frontCard.visible && this.checkClickTarget(this.curExer.rightAnswer)) {
target = this.curExer.rightAnswer;
callback = this.clickRight.bind(this);
}
else if (this.curExer.backCard.visible && this.checkClickTarget(this.curExer.backCard)) {
target = this.curExer.backCard;
callback = this.clickBackCard.bind(this);
}
if (callback) {
callback(target);
}
return;
}
} }
mapMove(event) { mapMove(event) {
...@@ -539,9 +901,89 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -539,9 +901,89 @@ export class PlayComponent implements OnInit, OnDestroy {
this.updateArr(this.renderArr); this.updateArr(this.renderArr);
this.updateArr(this.bigCardRenderArr);
} }
clickOverTurn(item: any) {
if (!this.curExer) {
return;
}
this.playAudio('turn', true);
this.curExer.overturn(1);
}
clickClose(item: any) {
if (!this.curExer) {
return;
}
this.playAudio('turn', true);
this.mask.visible = false;
this.curExer.close(() => {
//将词组设置为可点击
for (let j = 0; j < this.exercisesArr.length; ++j) {
this.exercisesArr[j].canClick = true;
}
removeItemFromArr(this.bigCardRenderArr, this.curExer.bigCard);
this.curExer = null;
});
}
clickLeft(item: any) {
if (!this.curExer) {
return;
}
if (item.line) {
if(item.line.alpha == 1){
item.line.alpha = 0;
tweenChange(item.text, { alpha: 1 }, 0.2, () => {
jelly(item.text);
});
}
else{
this.curAudio = this.playAudio(this.curExer.data.leftAnswer.audioUrl, true);
}
}
else{
this.curAudio = this.playAudio(this.curExer.data.leftAnswer.audioUrl, true);
}
}
clickRight(item: any) {
if (!this.curExer) {
return;
}
if (item.line) {
if(item.line.alpha == 1){
item.line.alpha = 0;
tweenChange(item.text, { alpha: 1 }, 0.2, () => {
jelly(item.text);
});
}
else{
this.curAudio = this.playAudio(this.curExer.data.rightAnswer.audioUrl, true);
}
}
else{
this.curAudio = this.playAudio(this.curExer.data.rightAnswer.audioUrl, true);
}
}
clickBackCard(item: any) {
if (!this.curExer) {
return;
}
this.curAudio = this.playAudio(this.curExer.data.card.audioUrl, true);
}
} }
...@@ -2,7 +2,9 @@ const res = [ ...@@ -2,7 +2,9 @@ const res = [
['play', "assets/play/play.png"], ['play', "assets/play/play.png"],
['stop', "assets/play/stop.png"], ['stop', "assets/play/stop.png"],
['letter-bg', "assets/play/letter-bg.png"],
['close', "assets/play/close.png"],
['overturn', "assets/play/overturn.png"],
]; ];
......
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