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
This diff is collapsed.
/**
*
* @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)
}
}
This diff is collapsed.
......@@ -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
This diff is collapsed.
const res = [
// ['bg', "assets/play/bg.jpg"],
['btn_left', "assets/play/btn_left.png"],
['btn_right', "assets/play/btn_right.png"],
// ['text_bg', "assets/play/text_bg.png"],
['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 diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment