Commit c6f65552 authored by Chen Jiping's avatar Chen Jiping

项目完善

parent 7b9a904b
...@@ -128,5 +128,8 @@ ...@@ -128,5 +128,8 @@
} }
} }
}, },
"defaultProject": "ng-template-generator" "defaultProject": "ng-template-generator",
} "cli": {
"analytics": "b761f036-eb9b-494c-a71d-94b007f7be85"
}
}
\ No newline at end of file
<div class="model-content"> <div class="model-content">
<div nz-row>
<div nz-col nzOffset='4'>
<div style="position: absolute; left: 200px; top: 100px; width: 800px;"> <h1 nz-title>课程练习内容编辑</h1>
</div>
<input type="text" nz-input [(ngModel)]="item.text" (blur)="save()"> </div>
<div nz-row>
<app-upload-image-with-preview <div nz-col [nzSpan]="15" nzOffset="3">
[picUrl]="item.pic_url" <div nz-form>
(imageUploaded)="onImageUploadSuccess($event, 'pic_url')" <div id='title-anchor'>
></app-upload-image-with-preview> <nz-divider nzText="课程名称" nzOrientation="left"></nz-divider>
<nz-form-item>
<app-audio-recorder <nz-form-label [nzSpan]="3" nzFor="part1">标题1</nz-form-label>
[audioUrl]="item.audio_url" <nz-form-control [nzSpan]="6">
(audioUploaded)="onAudioUploadSuccess($event, 'audio_url')" <nz-input-group nzAddOnBefore="Part">
></app-audio-recorder> <input type="text" id="part1" nz-input [(ngModel)]="item.title.part1" (blur)="save()">
<app-custom-hot-zone></app-custom-hot-zone> </nz-input-group>
<app-upload-video></app-upload-video> </nz-form-control>
<app-lesson-title-config></app-lesson-title-config> </nz-form-item>
<nz-form-item>
<nz-form-label [nzSpan]="3" nzFor="part2">标题2</nz-form-label>
<nz-form-control [nzSpan]="6">
<input nz-input type="text" id="part2" [(ngModel)]="item.title.part2" (blur)="save()">
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSpan]="3" nzFor="audio_url">发音</nz-form-label>
<nz-form-control [nzSpan]="6">
<app-audio-recorder
[audioUrl]="item.title.audio_url" id="audio_url"
(audioUploaded)="onAudioUploadSuccess($event, item.title, 'audio_url')">
</app-audio-recorder>
</nz-form-control>
</nz-form-item>
</div>
<div id='listen-anchor'>
<nz-divider nzText="听力材料" nzOrientation="left"></nz-divider>
<nz-form-item>
<nz-form-control [nzSpan]="6" nzOffset="3">
<app-audio-recorder id="item.listenAudioUrl"
[audioUrl]="item.listenAudioUrl"
(audioUploaded)="onAudioUploadSuccess($event, item, 'listenAudioUrl')">
</app-audio-recorder>
</nz-form-control>
</nz-form-item>
</div>
<div id='listen-anchor'>
<nz-divider nzText="练习题皮肤" nzOrientation="left"></nz-divider>
<nz-form-item>
<nz-form-label [nzSpan]="3">皮肤选择</nz-form-label>
<nz-form-control [nzSpan]="6">
<nz-radio-group [(ngModel)]="item.skin" (ngModelChange)="save()">
<label nz-radio nzValue="A">皮肤A</label>
<label nz-radio nzValue="B">皮肤B</label>
</nz-radio-group>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control [nzSpan]="6" nzOffset="3">
<div *ngIf="item.skin == 'A'">
<img src="assets/play/skin_1.jpg" style="width: auto;height: 200px;">
</div>
<div *ngIf="item.skin == 'B'">
<img src="assets/play/skin_2.jpg" style="width: auto;height: 200px;">
</div>
</nz-form-control>
</nz-form-item>
</div>
<div id='listen-anchor'>
<nz-divider nzText="练习题内容" nzOrientation="left"></nz-divider>
<nz-form-item>
<nz-form-label [nzSpan]="6" nzFor="exercises">操作</nz-form-label>
<nz-form-control [nzSpan]="6">
<button nz-button nzType="dashed" class="add-btn" id="add-btn" (click)="addExercisesItem()">
<i nz-icon nzType="plus-circle" nzTheme="outline"></i>添加
</button>
</nz-form-control>
</nz-form-item>
</div>
<div>
<div *ngFor="let data of item.exercisesArr;let j = index" class="card-item" style="padding: 0.5vw;">
<div class="border">
<nz-divider nzText="内容-{{j+1}}" nzOrientation="left"></nz-divider>
<nz-form-item>
<button style="margin: 10px;" nz-button nzType="danger" (click)="delExercisesItem(j)">
<span>删除</span>
</button>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSpan]="6" nzFor="{{j}}.text">文本</nz-form-label>
<nz-form-control [nzSpan]="6">
<input nz-input type="text" id="{{j}}.text" placeholder="请录入内容" [(ngModel)]="data.text"
(blur)="save()">
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSpan]="6" nzFor="{{j}}.text">序号</nz-form-label>
<nz-form-control [nzSpan]="6">
<input nz-input type="text" id="{{j}}.index" placeholder="请录入序号" [(ngModel)]="data.index"
(blur)="save()">
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSpan]="6" nzFor="{{j}}.pic_url">音频</nz-form-label>
<nz-form-control [nzSpan]="6">
<app-audio-recorder id="{{j}}.audio_url" [audioUrl]="data.audio_url"
(audioUploaded)="onAudioUploadSuccess($event, data, 'audio_url')">
</app-audio-recorder>
</nz-form-control>
</nz-form-item>
</div>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
\ No newline at end of file
...@@ -10,7 +10,7 @@ import {Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, Ap ...@@ -10,7 +10,7 @@ import {Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, Ap
export class FormComponent implements OnInit, OnChanges, OnDestroy { export class FormComponent implements OnInit, OnChanges, OnDestroy {
// 储存数据用 // 储存数据用
saveKey = "test_0011"; saveKey = "YM-28";
// 储存对象 // 储存对象
item; item;
...@@ -24,6 +24,12 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -24,6 +24,12 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
this.item = {}; this.item = {};
this.item.title = this.getDefaultTile();
this.item.exercisesArr = [];
console.log('item:', this.item);
// 获取存储的数据 // 获取存储的数据
(<any> window).courseware.getData((data) => { (<any> window).courseware.getData((data) => {
...@@ -50,7 +56,14 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -50,7 +56,14 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
init() { init() {
if(!this.item.title){
this.item.title = this.getDefaultTile();
}
//设置默认皮肤
if(!this.item.skin){
this.item.skin = "A";
}
} }
...@@ -58,19 +71,19 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -58,19 +71,19 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
* 储存图片数据 * 储存图片数据
* @param e * @param e
*/ */
onImageUploadSuccess(e, key) { onImageUploadSuccess(e, item, key) {
this.item[key] = e.url; item[key] = e.url;
this.save(); this.save();
} }
/** /**
* 储存音频数据 * 储存音频数据
* @param e * @param e
*/ */
onAudioUploadSuccess(e, key) { onAudioUploadSuccess(e, item, key) {
this.item[key] = e.url; item[key] = e.url;
this.save(); this.save();
} }
...@@ -81,6 +94,7 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -81,6 +94,7 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
*/ */
save() { save() {
(<any> window).courseware.setData(this.item, null, this.saveKey); (<any> window).courseware.setData(this.item, null, this.saveKey);
this.changeDetectorRef.detectChanges();
this.refresh(); this.refresh();
} }
...@@ -93,5 +107,48 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -93,5 +107,48 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
}, 1); }, 1);
} }
/**
* 获取缺省的练习题内容
*/
getDefaultExercisesItem(){
const exercises = {
text:'',
index:'',
audio_url:''
};
return exercises;
}
getDefaultTile(){
const title = {
part1:'',
part2:'',
audio_url:''
};
return title;
}
/**
* 添加练习
*/
addExercisesItem(){
let exercises = this.getDefaultExercisesItem();
this.item.exercisesArr.push(exercises);
this.save();
}
delExercisesItem(index){
if (index !== -1) {
this.item.exercisesArr.splice(index, 1);
this.save();
}
}
} }
/**
*
* @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 {
Label,
MySprite, ShapeRectNew,
ShapeCircle,
tweenChange,
ShapeRect
} from './Unit';
import {
playAudio,
pauseAudio
} from './AudioUtil';
import{
Skin
} from './Skin'
export class Exercises {
audio;
images;
exercisesData;
bg;
//隐藏背景
bg2;
textLabel;
indexLabel;
indexBg;
index;
scaleX = 1;
scaleY = 1;
constructor(exercisesData, images) {
this.exercisesData = exercisesData;
this.images = images;
this.index = exercisesData.index;
}
init(skin : Skin, i){
skin.initExercises(this, i);
}
initBg2(width, height){
console.log(width, height);
//最底部背景
const bg2 = new ShapeRect();
bg2.alpha = 0;
bg2.addChild(this.bg);
bg2.setSize(width, height);
if(this.bg instanceof ShapeRect){
this.bg.x = 0;
this.bg.y = 0;
}
else{
this.bg.x = width / 2;
this.bg.y = height - this.bg.getBoundingBox().height / 2;
}
this.bg2 = bg2;
}
checkRight(curIndex){
if(!curIndex){
return;
}
if(curIndex == this.index){
this.indexLabel.alpha = 1;
return true;
}
else{
return false;
}
}
playAudio(callback = null){
playAudio(this.audio);
return this.audio;
}
getHeight(){
return this.bg.getBoundingBox().height;
}
getWidth(){
return this.bg.getBoundingBox().width;
}
}
\ 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;
}
playAudio(callback = null){
this.btnPlay.alpha = 0;
this.btnStop.alpha = 1;
playAudio(this.audio, false, callback);
this.playing = true;
return this.audio;
}
pauseAudio(callback){
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, ShapeRectNew,
ShapeCircle,
tweenChange,
ShapeRect
} from './Unit';
import {
Exercises
} from './Exercises';
export class Skin {
skinType;
images;
scaleX = 1;
scaleY = 1;
bg;
intervalHeight = 0;
intervalWidth = 0;
contentBgWidth = 0;
constructor(skinType, images) {
this.skinType = skinType;
this.images = images;
}
setScaleXY(sacle: number) {
this.scaleX = this.scaleY = sacle;
if (this.skinType == 'B') {
this.intervalHeight = 56 * this.scaleY;
this.intervalWidth = 28 * this.scaleX;
this.contentBgWidth = 348 * this.scaleX;
}
else{
this.intervalHeight = 110 * this.scaleY;
this.intervalWidth = 63 * this.scaleX;
this.contentBgWidth = 320 * this.scaleX;
}
}
initBg(renderArr, canvasWidth: number, canvasHeight: number) {
if (this.skinType == 'B') {
const bg = new MySprite();
bg.init(this.images.get('skin_2_bg'));
let bgScale = Math.max(canvasWidth / bg.width, canvasHeight / bg.height);
bg.setScaleXY(bgScale);
bg.x = canvasWidth / 2;
bg.y = canvasHeight / 2;
this.bg = bg;
renderArr.push(bg);
const grass = new MySprite();
grass.init(this.images.get('grass'));
grass.scaleX = this.scaleX;
grass.scaleY = this.scaleY;
grass.x = canvasWidth - grass.getBoundingBox().width / 2;
grass.y = canvasHeight - grass.getBoundingBox().height / 2;
renderArr.push(grass);
}
}
initExercises(exercises: Exercises, i) {
if (this.skinType == 'B') {
this.setExercisesSkinB(exercises);
}
else {
this.setExercisesSkinA(exercises, i);
}
}
private setExercisesSkinA(exercises: Exercises, i) {
const getColor = (i) => {
if (i % 2 == 0) {
return { bgColor: "#E5E4E3" };
}
else {
return { bgColor: "#C7C8CB" };
}
}
//背景
const bg = new ShapeRect();
exercises.bg = bg;
bg.fillColor = getColor(i).bgColor;
bg.setSize(320 * this.scaleX, 88 * this.scaleY);
const textLabel = new Label();
exercises.textLabel = textLabel;
textLabel.text = exercises.exercisesData.text;
textLabel.textAlign = 'middle';
textLabel.fontSize = 48;
textLabel.fontName = "FUTURAB";
textLabel.fontColor = "#626262";
textLabel.setMaxSize(bg.width);
textLabel.refreshSize();
textLabel.x = (bg.width - textLabel.width) / 2;
textLabel.y = bg.height / 2;
bg.addChild(textLabel);
const indexBg = new MySprite();
indexBg.init(this.images.get('skin_2_index_bg'));
indexBg.scaleX = this.scaleX;
indexBg.scaleY = this.scaleY;
indexBg.x = bg.width / 2;
indexBg.y = - indexBg.getBoundingBox().height / 2 + 14 * this.scaleY;
exercises.indexBg = indexBg;
bg.addChild(indexBg);
const indexLabel = new Label();
exercises.indexLabel = indexLabel;
indexLabel.text = exercises.exercisesData.index;
indexLabel.textAlign = 'middle';
indexLabel.fontSize = 48;
indexLabel.fontName = "BRLNSDB";
indexLabel.fontColor = "#000000";
indexLabel.setMaxSize(indexBg.getBoundingBox().width);
indexLabel.refreshSize();
indexLabel.x = - indexLabel.width / 2 + 6 * this.scaleX;
indexLabel.y = - 6 * this.scaleY;
indexLabel.alpha = 0;
indexBg.addChild(indexLabel);
}
private setExercisesSkinB(exercises: Exercises) {
const textLabel = new Label();
exercises.textLabel = textLabel;
textLabel.text = exercises.exercisesData.text;
textLabel.textAlign = 'middle';
textLabel.fontSize = 48;
textLabel.fontName = "GOTHIC";
textLabel.fontColor = "#000000";
textLabel.refreshSize();
const indexLabel = new Label();
exercises.indexLabel = indexLabel;
indexLabel.text = exercises.exercisesData.index;
indexLabel.textAlign = 'middle';
indexLabel.fontSize = 36;
indexLabel.fontName = "BRLNSDB";
indexLabel.fontColor = "#316900";
indexLabel.alpha = 0;
indexLabel.refreshSize();
const indexBg = new ShapeRect();
indexBg.setSize(40 * this.scaleX, 40 * this.scaleY);
indexBg.visible = false;
indexBg.childDepandVisible = false;
indexBg.addChild(indexLabel);
exercises.indexBg = indexBg;
indexLabel.x = (indexBg.width - indexLabel.getBoundingBox().width )/ 2;
indexLabel.y = indexBg.height / 2
//树桩
const stump = new MySprite();
exercises.bg = stump;
//默认大树桩
let imageKey = "stump_b";
let textMargin = { marginTop: 37 * this.scaleY, marginLeft: 70 * this.scaleX, maxWidth: 219 * this.scaleX };
let indexMargin = { marginTop: 93 * this.scaleY, marginLeft: 164 * this.scaleX };
if (textLabel.width < 110 * this.scaleX) {
//取小树桩
imageKey = "stump_s"
indexMargin.marginLeft = 109 * this.scaleX;
indexMargin.marginTop = 91 * this.scaleY;
textMargin.marginLeft = 71 * this.scaleX;
textMargin.marginTop = 31 * this.scaleY;
textMargin.maxWidth = 110 * this.scaleX;
}
else if (textLabel.width <= 153 * this.scaleX) {
//取中等树桩
imageKey = "stump_m"
indexMargin.marginLeft = 151 * this.scaleX;
indexMargin.marginTop = 90 * this.scaleY;
textMargin.marginLeft = 89 * this.scaleX;
textMargin.marginTop = 28 * this.scaleY;
textMargin.maxWidth = 153 * this.scaleX;
}
else {
//设置最大宽度
textLabel.setMaxSize(219 * this.scaleX);
}
stump.init(this.images.get(imageKey));
stump.scaleX = this.scaleX;
stump.scaleY = this.scaleY;
let width = stump.getBoundingBox().width;
let height = stump.getBoundingBox().height
textLabel.x = -width / 2 + textMargin.marginLeft + (textMargin.maxWidth - textLabel.getBoundingBox().width) / 2;
textLabel.y = -height / 2 + textMargin.marginTop + textLabel.getBoundingBox().height / 2;
stump.addChild(textLabel);
indexBg.x = -width / 2 + indexMargin.marginLeft;
indexBg.y = -height / 2 + indexMargin.marginTop;
stump.addChild(indexBg);
}
getIntervalHeight(){
return this.intervalHeight;
}
getIntervalWidth(){
return this.intervalWidth;
}
getContentBgWidth(){
return this.contentBgWidth;
}
}
\ 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) {
//初始化标题1背景
const titePart1Bg = new MySprite();
titePart1Bg.init(this.images.get('titlePart1Bg'));
titePart1Bg.scaleX = mapScaleX;
titePart1Bg.scaleY = mapScaleY;
titePart1Bg.x = titePart1Bg.getBoundingBox().width / 2;
//标题1内容
const part1 = new Label();
part1.text = this.titleData.part1;
part1.textAlign = 'middle';
part1.fontSize = 48;
part1.fontName = "BRLNSDB";
part1.fontColor = "#AB5B22";
part1.refreshSize();
part1.x = - part1.getBoundingBox().width / 2;
titePart1Bg.addChild(part1);
//标题2内容
const part2 = new Label();
part2.text = this.titleData.part2;
part2.fontSize = 36;
part2.fontName = "FUTURAB";
part2.fontColor = "#000000";
part2.refreshSize();
part2.x = titePart1Bg.getBoundingBox().width + 11 * mapScaleX;
part2.y = 10 * 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;
let titleBg = new ShapeRect();
titleBg.setSize(width, height);
titleBg.alpha = 0;
titePart1Bg.y = height / 2;
titleBg.addChild(titePart1Bg);
part2.y = height / 2;
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)
}
}
export function getDefaultTile() {
let title = {
part1: 'A',
part2: 'Read and point',
audio_url: ''
};
return title;
}
\ No newline at end of file
...@@ -17,3 +17,14 @@ ...@@ -17,3 +17,14 @@
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") ;
}
\ 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 { import {
Label, Label,
MySprite, tweenChange, MySprite, 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 { playAudio, pauseAudio } from './AudioUtil';
import { Title, getDefaultTile } from './Title';
import { Listening } from './Listening';
import { Skin } from './Skin';
import { Exercises } from './Exercises';
@Component({ @Component({
...@@ -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;
...@@ -57,17 +64,23 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -57,17 +64,23 @@ export class PlayComponent implements OnInit, OnDestroy {
canvasLeft; canvasLeft;
canvasTop; canvasTop;
saveKey = 'test_0011'; saveKey = 'YM-28';
btnLeft;
btnRight;
pic1;
pic2;
canTouch = true; canTouch = true;
/**标题*/
title;
listening;
exercisesArr = [];
/**当前播放的音频 */
curAudio;
curPic; skin;
curAnswerIndex = 1;
@HostListener('window:resize', ['$event']) @HostListener('window:resize', ['$event'])
onResize(event) { onResize(event) {
...@@ -80,13 +93,13 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -80,13 +93,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();
...@@ -431,11 +444,15 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -431,11 +444,15 @@ export class PlayComponent implements OnInit, OnDestroy {
* 添加默认数据 便于无数据时的展示 * 添加默认数据 便于无数据时的展示
*/ */
initDefaultData() { initDefaultData() {
if (!this.data.title) {
this.data.title = getDefaultTile();
}
if (!this.data.pic_url) { //设置默认皮肤
this.data.pic_url = 'assets/play/default/pic.jpg'; if (!this.data.skin) {
this.data.pic_url_2 = 'assets/play/default/pic.jpg'; this.data.skin = 'A';
} }
} }
...@@ -444,9 +461,6 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -444,9 +461,6 @@ export class PlayComponent implements OnInit, OnDestroy {
*/ */
initImg() { initImg() {
this.addUrlToImages(this.data.pic_url);
this.addUrlToImages(this.data.pic_url_2);
} }
/** /**
...@@ -454,13 +468,24 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -454,13 +468,24 @@ 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('right', this.rawAudios.get('right'));
//标题发音
this.addUrlToAudioObj('titleAudio', this.data.title.audio_url);
//听力材料
this.addUrlToAudioObj('listenAudio', this.data.listenAudioUrl);
//练习题音效
for (let i = 0; i < this.data.exercisesArr.length; ++i) {
let exercises = this.data.exercisesArr[i];
this.addUrlToAudioObj('exercises_' + i, exercises.audio_url);
}
} }
...@@ -481,7 +506,9 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -481,7 +506,9 @@ export class PlayComponent implements OnInit, OnDestroy {
this.renderArr = []; this.renderArr = [];
this.exercisesArr = [];
this.curAnswerIndex = 1;
} }
...@@ -492,127 +519,193 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -492,127 +519,193 @@ export class PlayComponent implements OnInit, OnDestroy {
*/ */
initView() { initView() {
this.initBg();
this.initPic(); this.initTitle();
this.initBottomPart(); this.initBottomPart();
this.initExercises();
} }
initBottomPart() { 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 = 60;
this.renderArr.push(title.titleBg);
}
const btnLeft = new MySprite(); initBottomPart() {
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); const listening = new Listening(this.audioObj['listenAudio'], this.images);
listening.init(this.mapScale, this.mapScale);
this.renderArr.push(btnLeft); 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.btnLeft = btnLeft; this.renderArr.push(listening.bg);
}
initBg() {
const btnRight = new MySprite(); const skin = new Skin(this.data.skin, this.images);
btnRight.init(this.images.get('btn_right')); skin.setScaleXY(this.mapScale);
btnRight.x = this.canvasWidth - 50 * this.mapScale;
btnRight.y = this.canvasHeight - 100 * this.mapScale;
btnRight.setScaleXY(this.mapScale);
this.renderArr.push(btnRight); skin.initBg(this.renderArr, this.canvasWidth, this.canvasHeight);
this.btnRight = btnRight; this.skin = skin;
} }
initPic() { /**
* 初始化练习题
*/
initExercises() {
for (let i = 0; i < this.data.exercisesArr.length; ++i) {
const maxW = this.canvasWidth * 0.7; let exercises = this.data.exercisesArr[i];
const pic1 = new MySprite(); let exercisesObj = new Exercises(exercises, this.images);
pic1.init(this.images.get(this.data.pic_url)); exercises.audio = this.audioObj['exercises_' + i];
pic1.x = this.canvasWidth / 2; exercisesObj.scaleX = this.mapScale;
pic1.y = this.canvasHeight / 2; exercisesObj.scaleY = this.mapScale;
pic1.setScaleXY(maxW / pic1.width); exercisesObj.init(this.skin, i);
this.renderArr.push(pic1); this.exercisesArr.push(exercisesObj);
this.pic1 = pic1;
}
const label1 = new Label(); let intervalHeight = this.skin.getIntervalHeight();
label1.text = this.data.text;
label1.textAlign = 'center';
label1.fontSize = 50;
label1.fontName = 'BRLNSDB';
label1.fontColor = '#ffffff';
pic1.addChild(label1); let intervalWidth = this.skin.getIntervalWidth();
//背景固定宽度
let bgWidth = this.skin.getContentBgWidth();
console.log(intervalHeight, intervalWidth, bgWidth);
//显示行
let row = 0;
//显示列
let col = 0;
if (this.exercisesArr.length <= 3) {
row = 1;
col = this.exercisesArr.length;
}
else if (this.exercisesArr.length == 4) {
row = 2;
col = 2;
}
else {
col = 3;
row = Math.ceil(this.exercisesArr.length / col);
}
const pic2 = new MySprite(); //最大宽度
pic2.init(this.images.get(this.data.pic_url_2)); let maxWidth = col * bgWidth + (col - 1) * intervalWidth;
pic2.x = this.canvasWidth / 2 + this.canvasWidth;
pic2.y = this.canvasHeight / 2;
pic2.setScaleXY(maxW / pic2.width);
this.renderArr.push(pic2); //起始x坐标
this.pic2 = pic2; let startX = (this.canvasWidth - maxWidth) / 2;
this.curPic = pic1;
}
//最大高度
let tempMaxHeight = 0;
btnLeftClicked() { let maxHeightArr = [];
this.lastPage(); //计算每一行的最大高度
} for (let i = 0; i < this.exercisesArr.length; ++i) {
btnRightClicked() { let index = i + 1;
this.nextPage(); if (tempMaxHeight < this.exercisesArr[i].getHeight()) {
} tempMaxHeight = this.exercisesArr[i].getHeight();
}
lastPage() { if (index % col == 0) {
//行结尾
maxHeightArr.push(tempMaxHeight);
tempMaxHeight = 0;
}
else if (index % col != 0 && index == this.exercisesArr.length) {
//最后一个
maxHeightArr.push(tempMaxHeight);
tempMaxHeight = 0;
}
if (this.curPic == this.pic1) {
return;
} }
this.canTouch = false;
const moveLen = this.canvasWidth; for (let i = 0; i < this.exercisesArr.length; ++i) {
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 j = Math.floor(i / col);
if (this.curPic == this.pic2) { let height = maxHeightArr[j];
return;
this.exercisesArr[i].initBg2(bgWidth, height);
} }
this.canTouch = false; let totalHeight = 0;
const moveLen = this.canvasWidth; for (let i = 0; i < maxHeightArr.length; ++i) {
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() { totalHeight += maxHeightArr[i];
this.playAudio(this.data.audio_url);
} //如果不是最后一行,则增加间隔
if (i != maxHeightArr.length - 1) {
totalHeight += intervalHeight;
}
}
//起始y坐标
let startY = (this.canvasHeight - totalHeight) / 2;
let tempStartX = startX;
//循环设置显示坐标
for (let i = 0; i < this.exercisesArr.length; ++i) {
let index = i + 1;
let exercisesObj = this.exercisesArr[i];
exercisesObj.bg2.x = tempStartX;
exercisesObj.bg2.y = startY;
//最后一列
if (index % col == 0) {
//y坐标增加
startY += exercisesObj.bg2.height + intervalHeight;
//x坐标复位
tempStartX = startX;
}
else if (index % col != 0 && index == this.exercisesArr.length) {
//y坐标增加
startY += exercisesObj.bg2.height + intervalHeight;
}
else {
//x坐标增加
tempStartX += exercisesObj.bg2.width + intervalWidth;
}
this.renderArr.push(exercisesObj.bg2);
}
pic2Clicked() {
this.playAudio(this.data.audio_url_2);
} }
...@@ -625,26 +718,53 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -625,26 +718,53 @@ 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();
return; return;
} }
if ( this.checkClickTarget(this.pic1) ) { if (this.curAudio) {
this.pic1Clicked(); if (this.curAudio == this.listening.audio) {
return; this.listening.pauseAudio();
}
else {
this.curAudio.pause();
}
} }
if ( this.checkClickTarget(this.pic2) ) { if (this.checkClickTarget(this.title.titleBg)) {
this.pic2Clicked(); this.curAudio = this.title.playAudio();
return; return;
} }
for(let i = 0; i < this.exercisesArr.length; ++ i){
let exercisesObj = this.exercisesArr[i];
if(this.checkClickTarget(exercisesObj.indexBg)){
let flag = exercisesObj.checkRight(this.curAnswerIndex);
if(flag){
this.playAudio('right', true);
this.curAnswerIndex += 1;
}
}
if(this.checkClickTarget(exercisesObj.textLabel)){
this.curAudio = exercisesObj.playAudio();
return;
}
}
} }
mapMove(event) { mapMove(event) {
......
const res = [ const res = [
// ['bg', "assets/play/bg.jpg"], ['skin_2_bg', "assets/play/skin_2_bg.png"],
['btn_left', "assets/play/btn_left.png"], ['play', "assets/play/play.png"],
['btn_right', "assets/play/btn_right.png"], ['stop', "assets/play/stop.png"],
// ['text_bg', "assets/play/text_bg.png"], ['titlePart1Bg', "assets/play/title-part1-bg.png"],
['grass', "assets/play/grass.png"],
['skin_2_index_bg', "assets/play/skin_2_index_bg.png"],
['stump_b', "assets/play/stump_b.png"],
['stump_s', "assets/play/stump_s.png"],
['stump_m', "assets/play/stump_m.png"],
]; ];
...@@ -12,7 +16,7 @@ const res = [ ...@@ -12,7 +16,7 @@ const res = [
const resAudio = [ const resAudio = [
['click', "assets/play/music/click.mp3"], ['click', "assets/play/music/click.mp3"],
['right', "assets/play/music/right.mp3"],
]; ];
export {res, resAudio}; 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