Commit 39b85803 authored by Chen Jiping's avatar Chen Jiping

feat:完成配置页面开发

parent 9f3a2900
......@@ -128,5 +128,8 @@
}
}
},
"defaultProject": "ng-template-generator"
}
"defaultProject": "ng-template-generator",
"cli": {
"analytics": "a3be0365-39e6-4d8c-9ca7-730e87c6d81d"
}
}
\ No newline at end of file
import { Obj } from "./ObjBean";
export class ExercisesBean extends Obj {
answerArr = [];
index
}
export function getDefaultExercises() {
let exercises = new ExercisesBean();
exercises.answerArr.push(getDefaultAnswer());
exercises.answerArr.push(getDefaultAnswer());
return exercises;
}
export class AnswerBean extends Obj {
letterArr = [];
}
export function getDefaultAnswer(){
let answer = new AnswerBean();
return answer;
}
export class LetterBean extends Obj {
key = '';
bold = '0';
fontColor = '#363333';
isFill = '0';
}
export function getDefaultLetter() {
let letter = new LetterBean();
letter.key = 'K-' + new Date().getTime();
return letter;
}
export class Obj{
/**音频材料 */
audioUrl: String;
/**图片材料 */
picUrl:String;
val : String;
}
\ No newline at end of file
import { Obj } from "./ObjBean";
export class TitleBean extends Obj{
part1 : String;
part2: String;
}
export function getDefaultTile(){
let title = new TitleBean();
title.part1 = "C";
title.part2 = "Read and point";
return title;
}
\ No newline at end of file
......@@ -6,3 +6,6 @@
height: 100%;
}
.gridStyle {
width: '50%'
}
\ No newline at end of file
<div class="model-content">
<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>
<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 nz-row>
<div nz-col [nzSpan]="24">
<nz-form-item>
<nz-form-label [nzSpan]="2" nzFor="part1">标题1</nz-form-label>
<nz-form-control [nzSpan]="4">
<nz-input-group nzAddOnBefore="Part">
<input type="text" id="part1" nz-input [(ngModel)]="item.title.part1" (blur)="save()">
</nz-input-group>
</nz-form-control>
<nz-form-label [nzSpan]="2" nzFor="part2">标题2</nz-form-label>
<nz-form-control [nzSpan]="4">
<input nz-input type="text" id="part2" [(ngModel)]="item.title.part2" (blur)="save()">
</nz-form-control>
<nz-form-label [nzSpan]="2" nzFor="audioUrl">发音</nz-form-label>
<nz-form-control [nzSpan]="4">
<app-audio-recorder [audioUrl]="item.title.audioUrl" id="audioUrl"
(audioUploaded)="onAudioUploadSuccess($event, item.title, 'audioUrl')">
</app-audio-recorder>
</nz-form-control>
</nz-form-item>
</div>
</div>
</div>
\ No newline at end of file
<!--练习题-->
<div nz-row>
<div nz-col [nzSpan]="24">
<nz-card [nzExtra]="actionAdd" [nzActions]="[actionSetting]" nzTitle="语句">
<div *ngFor="let data of item.exercisesArr; let i=index" style="padding: 0.5vw;">
<nz-card nzTitle="语句-{{i+1}}" [nzHoverable]="true" [nzExtra]="actionAddWord">
<nz-form-item>
<nz-form-label [nzSpan]="2">音频</nz-form-label>
<nz-form-control [nzSpan]="3">
<app-audio-recorder [audioUrl]="data.audioUrl"
(audioUploaded)="onAudioUploadSuccess($event, data, 'audioUrl')">
</app-audio-recorder>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSpan]="2">图片</nz-form-label>
<nz-form-control [nzSpan]="3">
<app-upload-image-with-preview style="width: 100%" [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]="2">语句</nz-form-label>
<nz-form-control [nzSpan]="10">
<textarea rows="4" nz-input [(ngModel)]="data.val" (ngModelChange)="check(data.val, 20)"
(blur)="saveContent(data)"></textarea>
</nz-form-control>
</nz-form-item>
<div *ngFor="let answer of data.answerArr; let m=index">
<nz-card nzType="inner" nzTitle="{{ m == 0 ? '正确选项': '错误选项'}}">
<nz-form-item *ngIf="m == 0">
<nz-form-label [nzSpan]="2">音频</nz-form-label>
<nz-form-control [nzSpan]="3">
<app-audio-recorder [audioUrl]="answer.audioUrl"
(audioUploaded)="onAudioUploadSuccess($event, answer, 'audioUrl')">
</app-audio-recorder>
</nz-form-control>
</nz-form-item>
<nz-divider nzText="点击下方字母选择{{ m == 0 ? '点击单词选择正确选项':'点击单词选择错误选项'}}" nzOrientation="left"></nz-divider>
<nz-form-item>
<nz-form-control [nzSpan]="20">
<div *ngFor="let letter of answer.letterArr; let j = index" style="float: left;">
<div *ngIf="(letter.bold == '0')" style="float: left;">
<a style="float: left;font-size: 42px;font-family: FuturaBT-Bold; color:#363333; margin-right: 2px"
(click)="clickLetter(data, answer, j)">{{letter.val == ' ' ? '&nbsp;' : letter.val}}</a>
</div>
<div *ngIf="(letter.bold == '1')" style="float: left;">
<a style="float: left;font-size: 42px;font-family: FuturaBT-Bold; color:#581578; margin-right: 2px;font-weight: bold;"
(click)="clickLetter(data, answer, j)">{{letter.val == ' ' ? '&nbsp;' : letter.val}}</a>
</div>
</div>
</nz-form-control>
</nz-form-item>
<nz-divider nzText="点击字母变绿" nzOrientation="left"></nz-divider>
<nz-form-item>
<nz-form-control [nzSpan]="20">
<div *ngFor="let letter of answer.letterArr; let j = index" style="float: left;">
<div *ngIf="(answer.from &lt;= j && answer.to &gt;= j)" style="float: left;">
<a [ngStyle]="{'float': 'left','font-size': '42px','font-family': 'FuturaBT-Bold','color':letter.fontColor, 'margin-right': '2px','font-weight': 'bold'}"
(click)="clickLetter2( answer, j)">{{letter.val == ' ' ? '&nbsp;' : letter.val}}</a>
</div>
</div>
</nz-form-control>
</nz-form-item>
</nz-card>
</div>
</nz-card>
<ng-template #actionAddWord>
<button nz-button nzType="danger" (click)="delExercisesItem(item,i)">
<i nz-icon nzType="delete" nzTheme="outline"></i>删除
</button>
</ng-template>
</div>
</nz-card>
<ng-template #actionAdd>
<button nz-button nzType="dashed" [disabled]="item.exercisesArr.length == 4 ? true : false" class="add-btn"
id="add-btn" (click)="addExercisesItem(item)">
<i nz-icon nzType="plus-circle" nzTheme="outline"></i>添加
</button>
</ng-template>
<ng-template #actionSetting>
<button nz-button nzType="dashed" [disabled]="item.exercisesArr.length == 4 ? true : false" class="add-btn"
id="add-btn" (click)="addExercisesItem(item)">
<i nz-icon nzType="plus-circle" nzTheme="outline"></i>添加
</button>
</ng-template>
</div>
</div>
\ No newline at end of file
import {Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, ApplicationRef, ChangeDetectorRef} from '@angular/core';
import { Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, ApplicationRef, ChangeDetectorRef } from '@angular/core';
import { SSL_OP_SSLEAY_080_CLIENT_DH_BUG } from 'constants';
import { NzMessageService } from 'ng-zorro-antd/message';
import { getDefaultAnswer, getDefaultExercises, getDefaultLetter } from '../bean/Exercises';
import { getDefaultTile } from '../bean/TitleBean';
......@@ -10,12 +14,14 @@ import {Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, Ap
export class FormComponent implements OnInit, OnChanges, OnDestroy {
// 储存数据用
saveKey = "test_0011";
saveKey = "YM5-15";
// 储存对象
item;
length = 0;
constructor(private appRef: ApplicationRef,private changeDetectorRef: ChangeDetectorRef) {
constructor(private appRef: ApplicationRef, private changeDetectorRef: ChangeDetectorRef, private message: NzMessageService) {
}
......@@ -24,13 +30,16 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
this.item = {};
this.item.title = getDefaultTile();
// 获取存储的数据
(<any> window).courseware.getData((data) => {
(<any>window).courseware.getData((data) => {
if (data) {
this.item = data;
}
console.log(data);
this.init();
this.changeDetectorRef.markForCheck();
this.changeDetectorRef.detectChanges();
......@@ -51,26 +60,43 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
init() {
if (!this.item.title) {
this.item.title = getDefaultTile();
}
if (!this.item.exercisesArr) {
this.item.exercisesArr = [];
}
for (let i = 0; i < this.item.exercisesArr.length; ++i) {
let exercises = this.item.exercisesArr[i];
let answerArr = exercises.answerArr;
for (let j = 0; j < answerArr.length; ++j) {
answerArr[j].start = -1;
}
}
}
/**
* 储存图片数据
* @param e
*/
onImageUploadSuccess(e, key) {
* 储存图片数据
* @param e
*/
onImageUploadSuccess(e, item, key) {
this.item[key] = e.url;
this.save();
item[key] = e.url;
this.save();
}
/**
* 储存音频数据
* @param e
*/
onAudioUploadSuccess(e, key) {
onAudioUploadSuccess(e, item, key) {
this.item[key] = e.url;
item[key] = e.url;
this.save();
}
......@@ -80,7 +106,7 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
* 储存数据
*/
save() {
(<any> window).courseware.setData(this.item, null, this.saveKey);
(<any>window).courseware.setData(this.item, null, this.saveKey);
this.refresh();
}
......@@ -93,5 +119,391 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
}, 1);
}
addLetterItem(item) {
let letter = getDefaultLetter();
item.letterArr.push(letter);
item.letterArr = [...item.letterArr];
this.save();
}
delLetter(item, index) {
if (index !== -1) {
item.letterArr.splice(index, 1);
item.letterArr = [...item.letterArr];
this.save();
}
}
saveContent(item) {
const reset = (answer) => {
answer.letterArr = [];
answer.from = -1;
answer.to = -1;
answer.letterFrom = -1;
answer.letterTo = -1;
}
let val = item.val;
let oldVal = item.oldVal;
if (val) {
if (val != oldVal) {
item.oldVal = val;
for (let i = 0; i < item.answerArr.length; ++i) {
let answer = item.answerArr[i];
reset(answer);
for (let j = 0; j < val.length; ++j) {
let letter = getDefaultLetter();
letter.val = val.charAt(j);
answer.letterArr.push(letter);
}
}
}
}
else {
for (let i = 0; i < item.answerArr.length; ++i) {
let answer = item.answerArr[i];
reset(answer);
}
}
this.save();
}
addExercisesItem(item) {
let exercises = getDefaultExercises();
item.exercisesArr.push(exercises);
this.length = item.exercisesArr.length;
exercises.index = this.length;
this.save();
}
delExercisesItem(item, index) {
if (index !== -1) {
item.exercisesArr.splice(index, 1);
item.exercisesArr = [...item.exercisesArr];
this.save();
}
}
clickLetter(exercises, item, i) {
if(!this.checkIntersection(exercises, item, i)){
return;
}
let letterArr = item.letterArr;
if (!item.start || item.start == -1) {
for (let i = 0; i < letterArr.length; ++i) {
letterArr[i].bold = '0';
letterArr[i].fontColor = '#363333';
}
item.start = i;
letterArr[i].bold = '1';
letterArr[i].fontColor = '#581578';
}
else {
let start = item.start;
let end = item.start;
if (i > item.start) {
end = i;
} else {
start = i;
}
item.from = start;
item.to = end;
for (let i = 0; i < letterArr.length; ++i) {
if (i >= start && i <= end) {
letterArr[i].bold = '1';
letterArr[i].fontColor = '#581578';
}
else {
letterArr[i].bold = '0';
letterArr[i].fontColor = '#363333';
}
}
item.start = -1;
}
this.save();
}
private checkIntersection(exercises, item, index){
let result = false;
for (let i = 0; i < exercises.answerArr.length; ++i) {
let answer = exercises.answerArr[i];
if(answer == item){
continue;
}
if(answer.from <= index && answer.to >= index){
result = true;
}
}
if(result){
let id = this.message.error('所选内容有交叉,请重新选择', { nzDuration: 0 }).messageId;
setTimeout(() => {
this.message.remove(id);
}, 2000);
return false;
}
return true;
}
clickLetter2(item, i) {
let letterArr = item.letterArr;
if (!item.letterStart || item.letterStart == -1) {
for (let i = item.from; i < item.to; ++i) {
letterArr[i].fontColor = '#581578';
}
item.letterStart = i;
letterArr[i].fontColor = '#0fad51';
}
else {
let start = item.letterStart;
let end = item.letterStart;
if (i > item.letterStart) {
end = i;
} else {
start = i;
}
item.letterFrom = start;
item.letterTo = end;
for (let i = item.from; i < item.to; ++i) {
if (i >= start && i <= end) {
letterArr[i].fontColor = '#0fad51';
}
else {
letterArr[i].fontColor = '#581578';
}
}
item.letterStart = -1;
}
this.save();
}
boldOptionChange(item) {
if (item.bold == '0') {
item.fontColor = "#363333";
}
else {
item.fontColor = "#0fad51";
}
this.save();
}
letterOptionChange(item) {
if (item.letterFlag == '0') {
item.letterArr = [];
}
else {
item.letterArr = [];
}
this.save();
}
private setOptionArr(exercises) {
const getOptionArr = (flag) => {
let tempArr = [];
for (let i = 0; i < this.item.letterArr.length; ++i) {
let letter = this.item.letterArr[i];
if (!letter || !letter.val) {
continue;
}
let index = letter.val.indexOf("-");
if (index == -1) {
tempArr.push(letter);
}
else {
let pattern;
if (flag == 'r') {
pattern = /^-.+(?<!-)$/;
}
else if (flag == 'm') {
pattern = /^-.+-$/;
}
else {
pattern = /^(?!-).+-$/;
}
if (pattern.test(letter.val)) {
tempArr.push(letter);
}
}
}
return tempArr;
}
if (!exercises.optionArr) {
exercises.optionArr = [];
}
let tempArr = [];
let val = exercises.val ? exercises.val : "";
const chr = val.split(/\s+|\?|\.|\,|\!/);
for (const c of chr) {
let index = c.indexOf("_");
if (index == -1) {
continue;
}
if (index == 0) {
tempArr = getOptionArr('l')
}
else if (index > 0 && index < c.length - 1) {
tempArr = getOptionArr('m');
}
else {
tempArr = getOptionArr('r');
}
}
exercises.optionArr = [...tempArr];
}
check(value, maxLength: number) {
if (!value) {
return true;
}
const chr = value.split(/\s+|\?|\.|\,|\!/);
let count = 0;
for (const c of chr) {
if (c) {
count += 1;
}
}
if (count <= maxLength) {
return true;
}
else {
let id = this.message.error('超过' + maxLength + '个单词', { nzDuration: 0 }).messageId;
setTimeout(() => {
this.message.remove(id);
}, 2000);
return false;
}
}
private refreshExercises(item, letter, flag) {
let key = letter.key;
//改变单词对应的值
let letterArr = item.letterArr;
if (!letterArr) {
return;
}
for (let j = 0; j < letterArr.length; ++j) {
let tLetter = letterArr[j];
if (tLetter.isFill != '1') {
continue;
}
if (flag == 'R') {
tLetter.val = letter.val.replace(/\-/g, '');
tLetter.key = key;
item.key = key;
}
else {
if (tLetter.key == key && letter.val) {
if (flag == 'U') {
tLetter.val = letter.val.replace(/\-/g, '');
}
else if (flag == 'D') {
tLetter.val = '_';
tLetter.key = '';
tLetter.isFill = '1';
item.key = '';
}
}
}
}
}
}
/**
*
* @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 { faAlignRight } from "@fortawesome/free-solid-svg-icons";
import { Listening } from "./Listening";
import { getMaxScale, jelly, jellyPop, Label, Label2, LabelText, Line, MySprite, RichText, ShapeCircle, ShapeRect, ShapeRectNew, tweenChange } from "./Unit";
export class Exercises {
data;
images;
indexBgColor;
index: number;
bg: ShapeRect;
answer: ShapeRect;
answerLabel;
scaleX = 1;
scaleY = 1;
indexLabel: Label;
indexLabelBg: ShapeCircle;
answered = false;
showed = false;
underline : Line;
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.initExercises();
let w = 1280 * this.scaleX;
let h = 140 * this.scaleY;
h = this.answer.height > h ? this.answer.height : h;
this.bg.setSize(w, h);
}
initBg() {
const bg = new ShapeRect();
bg.alpha = 0;
this.bg = bg;
}
initIndex() {
let indexBg = new ShapeCircle();
let r = 20 * this.scaleX;
indexBg.alpha = 1;
indexBg.fillColor = "#763c92";
indexBg.setRadius(r);
indexBg.x = 56 * this.scaleX + r;
indexBg.y = r + 43 * this.scaleY;
this.bg.addChild(indexBg);
this.indexLabelBg = indexBg;
let index = new Label();
index.text = this.data.index + "";
index.textAlign = 'center';
index.fontSize = 36;
index.fontName = "TCB";
index.fontColor = "#ffffff";
index.setScaleXY(this.scaleX);
index.refreshSize();
index.x = 0;
index.y = 0;
indexBg.addChild(index);
this.indexLabel = index;
}
initExercises() {
let startX = 17 * this.scaleX + this.indexLabelBg.width / 2 + this.indexLabelBg.x;
let y = 0;
let answer = this.getAnswerView(this.data.answer);
answer.x = startX;
answer.y = y;
this.answer = answer;
this.bg.addChild(answer);
}
getAnswerView(answerData) {
const text = new RichText();
text.fontColor = "#363333";
text.fontSize = 48;
text.fontName = "MMB";
text.text = this.data.val;
text.disH = 20 * this.scaleX;
text.width = 1056 * this.scaleX;
text.setScaleXY(this.scaleX);
text.refreshSize();
this.answerLabel = text;
const bg = new ShapeRect();
bg.setSize(text.getBoundingBox().width, text.getBoundingBox().height);
bg.fillColor="#432300"
bg.alpha = 0;
text.y = bg.height / 2;
text.x = 0;
bg.addChild(text);
return bg;
}
check(curLetterItem, mx, my) {
const 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;
}
if (!curLetterItem) {
return false;
}
let rect = this.answer.getBoundingBox();
let width = 60 * this.scaleX;
let x = this.answerLabel.linePos.x * this.scaleX;
rect.x += x;
rect.width = width;
//console.log(rect, fillText);
if (checkPointInRect(mx, my, rect) && curLetterItem.data.key == this.data.key) {
this.answered = true;
this.answerLabel.fillVal = curLetterItem.data.val.replace(/\-/g, '');
this.answerLabel.answered = true;
if(this.underline){
this.underline.visible = false;
}
return true;
}
else {
return false;
}
}
}
\ No newline at end of file
import { Label, ShapeCircle, ShapeRect, ShapeRectNew } from "./Unit";
export class Letter{
data;
images;
bgColor;
lineColor;
scaleX = 1;
scaleY = 1;
bg : ShapeRectNew;
dragLabel : Label;
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 = 128 * this.scaleX
let h = 90 * this.scaleY;
this.bg.setSize(w, h, 0);
letter.x = w / 2;
letter.y = h / 2;
}
initBg(){
let bg = new ShapeRectNew();
bg.fillColor = this.bgColor;
bg.setOutLine(this.lineColor, 6 * this.scaleX)
this.bg = bg;
}
initView(){
const letter = new Label();
letter.text = this.data.val;
letter.textAlign = 'center';
letter.fontSize = 52;
letter.fontName = "FUTURAB";
letter.fontColor = "#2b292e";
letter.setScaleXY(this.scaleX);
letter.refreshSize();
this.bg.addChild(letter);
const dragLabel = new Label();
dragLabel.text = this.data.val;
dragLabel.textAlign = 'center';
dragLabel.fontSize = 52;
dragLabel.fontName = "FUTURAB";
dragLabel.fontColor = "#c8161d";
dragLabel.setScaleXY(this.scaleX);
this.dragLabel = dragLabel;
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, playPic = 'play', stopPic = 'stop') {
const bg = new ShapeRect();
const btnPlay = new MySprite();
btnPlay.init(this.images.get(playPic));
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(stopPic));
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="#763c92";
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,265 @@ export class Label extends MySprite {
}
export class LabelText {
private _val: string;
private _fontColor = "#000000";
private _underLine: boolean = false;
private _visiable = true;
private _fill = false;
private _width = 0;
private _x = 0;
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;
}
set fill(file){
this._fill = file;
}
get fill(){
return this._fill;
}
set width(width){
this._width = width;
}
get width(){
return this._width;
}
set x(val){
this._x = val;
}
get x(){
return this._x;
}
}
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;
text.width = width;
text.x = startX;
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 {
textArr = [];
......@@ -822,8 +1081,30 @@ export class RichTextOld extends Label {
export class RichText extends Label {
disH = 30;
offW = 10;
disH = 10;
offW = 0;
underlineWidth = 0;
underlineHeight = 0;
underlineColor = "#000000";
linePos = {x : 0, y : 0};
fillIndex = 0;
fillFontColor = "#000000";
text1 = "";
text2 = ""
answered = false;
fillVal = "";
audioPos = {x : 0, y : 0};
constructor(ctx?: any) {
super(ctx);
......@@ -833,6 +1114,94 @@ export class RichText extends Label {
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 - 2 * this.offW;
for (const c of chr) {
let index = c.indexOf("_");
if(index != -1){
let w1 = this.ctx.measureText(c.substring(0, index)).width;
let w2 = this.ctx.measureText(c.substring(index + 1)).width;
let w3 = this.ctx.measureText(c.substring(index + 1) + c).width;
let tW1 = w1 + this.underlineWidth + w2;
let tW2 = w1 + this.underlineWidth + w3;
if(tW1 * this.scaleX < w && tW2 * this.scaleX <= w){
temp += ' ' + c;
}
else{
row.push(temp);
temp = ' ' + c;
}
}
else{
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;
}
}
}
if (temp != ' ') {
row.push(temp);
}
this._height = this.fontSize * row.length + (row.length - 1) * this.disH;
const disH = (this.fontSize + this.disH);
const x = 0;
for (let b = 0; b < row.length; b++) {
let index = row[b].indexOf("_");
if(index != -1){
this.fillIndex = b;
let text1 = row[b].substring(0, index);
this.text1 = text1;
this.text2 = row[b].substring(index + 1);
let w = this.ctx.measureText(text1).width;
this.linePos.x = x + w;
this.linePos.y = (b + 1) * disH;
}
//最后一行,取末尾坐标
if(b == row.length - 1){
this.audioPos.x = this.ctx.measureText(row[b]).width;
this.audioPos.y = b * disH;
if(this.answered && this.fillIndex == b){
let val = this.text1 + this.fillVal + this.text2;
this.audioPos.x = this.ctx.measureText(val).width;
}
}
}
this.ctx.restore();
}
drawText() {
if (!this.text) {
......@@ -842,53 +1211,122 @@ 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 - this.offW * 2;
const disH = (this.fontSize + this.disH) * this.scaleY;
const w = selfW - 2 * this.offW;
const disH = (this.fontSize + this.disH);
for (const c of chr) {
let index = c.indexOf("_");
if(index != -1){
let w1 = this.ctx.measureText(c.substring(0, index)).width;
let w2 = this.ctx.measureText(c.substring(index + 1)).width;
let w3 = this.ctx.measureText(c.substring(index + 1) + c).width;
let tW1 = w1 + this.underlineWidth + w2;
let tW2 = w1 + this.underlineWidth + w3;
for (const c of chr) {
if (this.ctx.measureText(temp).width < w && this.ctx.measureText(temp + (c)).width <= w) {
temp += ' ' + c;
} else {
row.push(temp);
temp = ' ' + c;
if(tW1 * this.scaleX < w && tW2 * this.scaleX <= w){
temp += ' ' + c;
}
else{
row.push(temp);
temp = ' ' + c;
}
}
else{
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坐标间隔
}
// 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++) {
if(this.answered){
if(b == this.fillIndex){
let w = this.ctx.measureText(this.text1).width;
this.ctx.fillText(this.text1, x, y + (b + 1) * disH); // 每行字体y坐标间隔
this.ctx.fillStyle = this.fillFontColor;
this.ctx.fillText(this.fillVal, x + w, y + (b + 1) * disH); // 每行字体y坐标间隔
let w2 = this.ctx.measureText(this.fillVal).width;
this.ctx.fillStyle = this.fontColor;
this.ctx.fillText(this.text2, x + w + w2, y + (b + 1) * disH); // 每行字体y坐标间隔
}
else{
this.ctx.fillText(row[b], x, y + (b + 1) * disH); // 每行字体y坐标间隔
}
}
else{
let index = row[b].indexOf("_");
if(index != -1){
let text1 = row[b].substring(0, index);
let w = this.ctx.measureText(text1).width;
let text2 = row[b].substring(index + 1);
this.ctx.fillText(text1, x, y + (b + 1) * disH); // 每行字体y坐标间隔
this.ctx.fillText(text2, x + w + this.underlineWidth, y + (b + 1) * disH); // 每行字体y坐标间隔
this.linePos.x = x + w;
this.linePos.y = y + (b + 1) * disH;
let lineY = y + (b + 1) * disH;
this.ctx.save();
this.ctx.beginPath();
this.ctx.moveTo(x + w, lineY);
this.ctx.lineTo(x + w + this.underlineWidth, lineY);
this.ctx.lineWidth = this.underlineHeight;
this.ctx.strokeStyle = this.underlineColor;
this.ctx.stroke();
this.ctx.restore();
}
else{
this.ctx.fillText(row[b], x, y + (b + 1) * disH); // 每行字体y坐标间隔
}
}
}
}
......@@ -1235,7 +1673,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 =============-------------
......
......@@ -17,3 +17,32 @@
src: url("../../assets/font/BRLNSDB.TTF") ;
}
@font-face
{
font-family: 'tt0142m';
src: url("../../assets/font/tt0142m.ttf") ;
}
@font-face
{
font-family: 'GOTHICB';
src: url("../../assets/font/GOTHICB.TTF") ;
}
@font-face
{
font-family: 'MMB';
src: url("../../assets/font/MMTextBook-Bold.otf") ;
}
@font-face
{
font-family: 'FUTURAB';
src: url("../../assets/font/FUTURAB.TTF") ;
}
@font-face
{
font-family: 'TCB';
src: url("../../assets/font/TCB.TTF") ;
}
\ No newline at end of file
import {Component, ElementRef, ViewChild, OnInit, Input, OnDestroy, HostListener} from '@angular/core';
import { Component, ElementRef, ViewChild, OnInit, Input, OnDestroy, HostListener } from '@angular/core';
import {
Label,
MySprite, tweenChange,
removeItemFromArr, ShapeRect, tweenChange,
} from './Unit';
import {res, resAudio} from './resources';
import { res, resAudio } from './resources';
import {Subject} from 'rxjs';
import {debounceTime} from 'rxjs/operators';
import { Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
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';
import { exception } from 'console';
......@@ -22,8 +28,8 @@ import TWEEN from '@tweenjs/tween.js';
})
export class PlayComponent implements OnInit, OnDestroy {
@ViewChild('canvas', {static: true }) canvas: ElementRef;
@ViewChild('wrap', {static: true }) wrap: ElementRef;
@ViewChild('canvas', { static: true }) canvas: ElementRef;
@ViewChild('wrap', { static: true }) wrap: ElementRef;
// 数据
data;
......@@ -52,22 +58,34 @@ export class PlayComponent implements OnInit, OnDestroy {
audioObj = {};
renderArr;
mapScale = 1;
canvasLeft;
canvasTop;
saveKey = 'test_0011';
saveKey = 'YM5-15';
canTouch = true;
btnLeft;
btnRight;
pic1;
pic2;
/**标题*/
title: Title;
canTouch = true;
curAudio;
exercisesArr: Array<Exercises> = [];
oldPos;
itemOldPos;
curPic;
lastClickTime: Date;
curListening: Listening;
listening: Listening;
listeningArr: Array<Listening> = [];
@HostListener('window:resize', ['$event'])
onResize(event) {
......@@ -80,13 +98,17 @@ export class PlayComponent implements OnInit, OnDestroy {
this.data = {};
// 获取数据
const getData = (<any> window).courseware.getData;
const getData = (<any>window).courseware.getData;
getData((data) => {
if (data && typeof data == 'object') {
this.data = data;
}
// console.log('data:' , data);
else {
let defaultData = '{"title":{"part1":"C","part2":"Read and point"},"letterArr":[{"key":"K-1612945850419","isFill":"0","val":"-dis"},{"key":"K-1612945972128","isFill":"0","val":"-aw-"},{"key":"K-1612947526926","isFill":"0","val":"ph"},{"key":"K-1612947527364","isFill":"0","val":"-aw-"},{"key":"K-1612947541415","isFill":"0","val":"-ch"},{"key":"K-1612947545454","isFill":"0","val":"-ed"},{"key":"K-1612947548919","isFill":"0","val":"pre-"}],"exercisesArr":[{"letterArr":[{"key":"K-1613141016560","isFill":"0","val":"Hello,My name is chenjp.Hello My n"},{"key":"K-1613141016560","isFill":"1","val":"_"},{"key":"K-1613141016560","isFill":"0","val":"e is chenjp.Hello,"}],"key":"K-1612947526926","answer":{"letterArr":[{"key":"","isFill":"0","val":"name"},{"key":"K-1612705253202","isFill":"1","val":"pah","val2":"pah"}]},"index":1,"val":"Hello,My name is chenjp.Hello My n_e is chenjp.Hello,","audioUrl":"http://staging-teach.cdn.ireadabc.com/8970ccce02d3a37640c80e02626fefb8.mp3"},{"key":"K-1612945850419","answer":{},"index":2,"val":"I _agree with my dad about it.","letterArr":[{"key":"K-1612946396917","isFill":"0","val":"I "},{"key":"K-1612945850419","isFill":"1","val":"dis"},{"key":"K-1612946396917","isFill":"0","val":"agree with my dad about it."}],"audioUrl":"http://staging-teach.cdn.ireadabc.com/ef597f87e534ab2c73f4f9ed34eb26fa.mp3"},{"key":"K-1612947545454","answer":{},"index":3,"val":"He received the best treat_ for a cold yesterday.","letterArr":[{"key":"K-1613141079966","isFill":"0","val":"He received the best treat"},{"key":"K-1613141079966","isFill":"1","val":"_"},{"key":"K-1613141079966","isFill":"0","val":" for a cold yesterday."}],"audioUrl":"http://staging-teach.cdn.ireadabc.com/55addbbc6a4da4a63bc22988063bdded.mp3"},{"key":"K-1612947541415","answer":{},"index":4,"val":"He received the best treat_ for a cold yesterday.","letterArr":[{"key":"K-1613141080944","isFill":"0","val":"He received the best treat"},{"key":"K-1612947541415","isFill":"1","val":"ch"},{"key":"K-1613141080944","isFill":"0","val":" for a cold yesterday."}],"audioUrl":"http://staging-teach.cdn.ireadabc.com/71eb8fcc0895873363840db7bc0c5883.mp3"}]}';
this.data = JSON.parse(defaultData);
}
//console.log('data:', JSON.stringify(data));
// 初始化 各事件监听
this.initListener();
......@@ -297,6 +319,8 @@ export class PlayComponent implements OnInit, OnDestroy {
}
audio.play();
}
return audio;
}
......@@ -341,7 +365,7 @@ export class PlayComponent implements OnInit, OnDestroy {
return new Promise((resolve, reject) => {
const audio = new Audio();
audio.oncanplay = (a) => {
resolve();
resolve(a);
};
audio.onerror = () => {
reject();
......@@ -442,10 +466,12 @@ export class PlayComponent implements OnInit, OnDestroy {
* 添加默认数据 便于无数据时的展示
*/
initDefaultData() {
if (!this.data.title) {
this.data.title = getDefaultTile();
}
if (!this.data.pic_url) {
this.data.pic_url = 'assets/play/default/pic.jpg';
this.data.pic_url_2 = 'assets/play/default/pic.jpg';
if (!this.data.exercisesArr) {
this.data.exercisesArr = [];
}
}
......@@ -455,8 +481,6 @@ export class PlayComponent implements OnInit, OnDestroy {
*/
initImg() {
this.addUrlToImages(this.data.pic_url);
this.addUrlToImages(this.data.pic_url_2);
}
......@@ -465,12 +489,35 @@ export class PlayComponent implements OnInit, OnDestroy {
*/
initAudio() {
// 音频资源
this.addUrlToAudioObj(this.data.audio_url);
this.addUrlToAudioObj(this.data.audio_url_2);
// 音效
this.addUrlToAudioObj('click', this.rawAudios.get('click'), 0.3);
this.rawAudios.forEach((item, key) => {
// 音效
this.addUrlToAudioObj(key, item);
})
//标题发音
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.exercisesArr.length; ++i) {
let exercises = this.data.exercisesArr[i];
if (exercises.answer && exercises.audioUrl) {
this.addUrlToAudioObj(exercises.audioUrl);
}
}
}
......@@ -486,14 +533,18 @@ export class PlayComponent implements OnInit, OnDestroy {
const s = Math.min(sx, sy);
this.mapScale = s;
// this.mapScale = sx;
// this.mapScale = sy;
this.renderArr = [];
if (this.curAudio) {
this.curAudio.pause();
}
this.curAudio = null;
this.exercisesArr = [];
this.listeningArr = [];
}
......@@ -503,130 +554,113 @@ export class PlayComponent implements OnInit, OnDestroy {
*/
initView() {
this.initPic();
this.initTitle();
this.initBottomPart();
this.initExercises();
}
initBottomPart() {
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;
initTitle() {
btnLeft.setScaleXY(this.mapScale);
const title = new Title(this.data.title, this.images);
this.renderArr.push(btnLeft);
title.init(this.mapScale, this.mapScale);
title.audio = this.audioObj['titleAudio'];
this.title = title;
this.btnLeft = btnLeft;
title.titleBg.y = 0;
title.titleBg.x = 0;
this.renderArr.push(title.titleBg);
}
initBottomPart() {
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);
if (!this.data.audioUrl) {
return;
}
const listening = new Listening(this.audioObj['listenAudio'], this.images);
listening.init(this.mapScale, this.mapScale);
this.renderArr.push(btnRight);
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.btnRight = btnRight;
this.renderArr.push(listening.bg);
}
initPic() {
const maxW = this.canvasWidth * 0.7;
private initExercises() {
const pic1 = new MySprite();
pic1.init(this.images.get(this.data.pic_url));
pic1.x = this.canvasWidth / 2;
pic1.y = this.canvasHeight / 2;
pic1.setScaleXY(maxW / pic1.width);
const getView = (item, index) => {
this.renderArr.push(pic1);
this.pic1 = pic1;
let exercises = new Exercises();
exercises.index = index;
const label1 = new Label();
label1.text = this.data.text;
label1.textAlign = 'center';
label1.fontSize = 50;
label1.fontName = 'BRLNSDB';
label1.fontColor = '#ffffff';
exercises.init(this.images, this.data.backgroudColor, item, this.mapScale, this.mapScale);
pic1.addChild(label1);
return exercises;
}
let exercisesArr = this.data.exercisesArr;
let col = 1;
let row = Math.ceil(exercisesArr.length / col);
let dW = 0 * this.mapScale;
const pic2 = new MySprite();
pic2.init(this.images.get(this.data.pic_url_2));
pic2.x = this.canvasWidth / 2 + this.canvasWidth;
pic2.y = this.canvasHeight / 2;
pic2.setScaleXY(maxW / pic2.width);
let dH = 35 * this.mapScale;
this.renderArr.push(pic2);
this.pic2 = pic2;
let w = 1280 * this.mapScale;
this.curPic = pic1;
}
let h = 0 * this.mapScale;
let totalWidth = col * w + (col - 1) * dW;
btnLeftClicked() {
let totalHeight = row * h + (row - 1) * dH;
this.lastPage();
}
let startX = (this.canvasWidth - totalWidth) / 2;
btnRightClicked() {
for (let i = 0; i < exercisesArr.length; ++i) {
this.nextPage();
}
lastPage() {
let exercises = getView(exercisesArr[i], i + 1);
if (this.curPic == this.pic1) {
return;
}
totalHeight += exercises.bg.height;
this.canTouch = false;
this.renderArr.push(exercises.bg);
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;
});
}
this.exercisesArr.push(exercises);
}
nextPage() {
if (this.curPic == this.pic2) {
return;
}
let startY = this.canvasHeight / 2 - 254 * this.mapScale;
this.canTouch = false;
let tempY = startY;
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.pic2;
});
}
for (let i = 0; i < this.exercisesArr.length; ++i) {
pic1Clicked() {
this.playAudio(this.data.audio_url);
}
let exercises = this.exercisesArr[i];
pic2Clicked() {
this.playAudio(this.data.audio_url_2);
}
exercises.bg.x = startX;
exercises.bg.y = startY;
//换行
if ((i + 1) % row != 0) {
startY += dH + exercises.bg.height;
}
else {
startX += dW + w;
startY = tempY;
}
}
}
......@@ -636,26 +670,86 @@ export class PlayComponent implements OnInit, OnDestroy {
return;
}
if ( this.checkClickTarget(this.btnLeft) ) {
this.btnLeftClicked();
return;
if (this.curAudio) {
if (!this.listening || this.curAudio != this.listening.audio) {
this.curAudio.pause();
}
}
if ( this.checkClickTarget(this.btnRight) ) {
this.btnRightClicked();
if (this.listening && this.checkClickTarget(this.listening.bg)) {
this.curAudio = this.listening.play(() => {
this.listening.reset();
});
return;
}
if ( this.checkClickTarget(this.pic1) ) {
this.pic1Clicked();
if (this.curAudio) {
if (this.listening && this.curAudio == this.listening.audio) {
this.listening.pauseAudio();
}
else {
this.curAudio.pause();
}
}
if (this.checkClickTarget(this.title.titleBg)) {
this.curAudio = this.title.playAudio();
return;
}
if ( this.checkClickTarget(this.pic2) ) {
this.pic2Clicked();
this.oldPos = { x: this.mx, y: this.my };
let clicked = false;
if (clicked) {
this.itemOldPos = { x: this.mx, y: this.my };
return;
}
let listening;
for (let i = 0; i < this.listeningArr.length; ++i) {
listening = this.listeningArr[i];
if (this.checkClickTarget(listening.bg)) {
clicked = true;
break;
}
}
if (clicked) {
if (listening == this.curListening) {
if (listening.playing) {
listening.pauseAudio();
}
else {
this.curAudio = listening.play(() => {
listening.reset();
});
}
}
else {
if (this.curListening) {
this.curListening.pauseAudio();
}
this.curListening = listening;
this.curAudio = listening.play(() => {
listening.reset();
});
}
}
}
mapMove(event) {
......@@ -664,6 +758,7 @@ export class PlayComponent implements OnInit, OnDestroy {
mapUp(event) {
}
......@@ -682,9 +777,21 @@ export class PlayComponent implements OnInit, OnDestroy {
this.updateArr(this.renderArr);
}
private clickExercies(curExer) {
if (!curExer) {
return;
}
if (curExer.answered) {
if (this.checkClickTarget(curExer.answer)) {
this.playAudio(curExer.data.audioUrl, true);
}
return;
}
}
}
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"],
['play', "assets/play/play.png"],
['stop', "assets/play/stop.png"],
['play_1', "assets/play/play_1.png"],
['stop_1', "assets/play/stop_1.png"],
['index_bg', "assets/play/index_bg.png"],
];
......@@ -12,7 +12,8 @@ const res = [
const resAudio = [
['click', "assets/play/music/click.mp3"],
['right', "assets/play/music/right.mp3"],
['back', "assets/play/music/back.mp3"],
];
export {res, resAudio};
This source diff could not be displayed because it is too large. You can view the blob instead.
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