Commit beec69e8 authored by Chen Jiping's avatar Chen Jiping

perf:完成配置界面开发

parent fa703d42
...@@ -128,5 +128,8 @@ ...@@ -128,5 +128,8 @@
} }
} }
}, },
"defaultProject": "ng-template-generator" "defaultProject": "ng-template-generator",
"cli": {
"analytics": "7ae231a8-358a-4ce6-9597-2bc03da77a3e"
}
} }
\ No newline at end of file
class Obj{
/**音频材料 */
audioUrl: String;
/**图片材料 */
picUrl:String;
/**值 */
val : String;
}
export class Answer extends Obj{
/**是否正确:0-否,1-是 */
isRight:String;
}
export class Exercises extends Obj{
/**备选择答案:3-5个 */
answers :Array<Answer> = [];
/**序列帧 */
frames : Array<Frame> = [];
hotZoneItemArr = [];
}
export class Frame extends Obj{
}
export class Backgroud extends Obj{
rect = {};
}
export class Title extends Obj{
}
export class Item{
bg : Backgroud;
title : Title;
//练习题
exercisesArr : Array<Exercises> = [];
}
export function getDefaultItem(){
const item = new Item();
item.bg = new Backgroud();
item.title = new Title();
item.title.val = 'Find Body Part'
return item;
}
export function getDefaultExercises(){
const exercises = new Exercises();
for(let i = 0; i < 3; ++ i){
const answer = new Answer();
answer.isRight = '0';
exercises.answers.push(answer);
}
return exercises;
}
\ No newline at end of file
...@@ -7,18 +7,19 @@ ...@@ -7,18 +7,19 @@
</div> </div>
<div nz-row nzType="flex" nzAlign="middle"> <div nz-row nzType="flex" nzAlign="middle">
<!--
<div nz-col nzSpan="5" nzOffset="1"> <div nz-col nzSpan="5" nzOffset="1">
<h5> add background: </h5> <h5> add background: </h5>
<div class="bg-box"> <div class="bg-box">
<app-upload-image-with-preview <app-upload-image-with-preview
[picUrl]="bgItem?.url" [picUrl]="bgItem?.picUrl"
(imageUploaded)="onBackgroundUploadSuccess($event)"> (imageUploaded)="onBackgroundUploadSuccess($event)">
</app-upload-image-with-preview> </app-upload-image-with-preview>
</div> </div>
</div> </div>
-->
<div nz-col nzSpan="5" nzOffset="1" class="img-box" <div nz-col nzSpan="5" nzOffset="1" class="img-box"
*ngFor="let it of hotZoneArr; let i = index"> *ngFor="let it of hotZoneArr; let i = index">
...@@ -35,7 +36,8 @@ ...@@ -35,7 +36,8 @@
<div style="margin-top: -20px; margin-bottom: 5px"> <div style="margin-top: -20px; margin-bottom: 5px">
<nz-radio-group [ngModel]="it.itemType" (ngModelChange)="radioChange($event, it)"> <nz-radio-group [ngModel]="it.itemType" (ngModelChange)="radioChange($event, it)">
<label *ngIf="isHasRect" nz-radio nzValue="rect">矩形</label> <!--<label *ngIf="isHasRect" nz-radio nzValue="rect">矩形</label>
-->
<label *ngIf="isHasPic" nz-radio nzValue="pic">图片</label> <label *ngIf="isHasPic" nz-radio nzValue="pic">图片</label>
<label *ngIf="isHasText" nz-radio nzValue="text">文本</label> <label *ngIf="isHasText" nz-radio nzValue="text">文本</label>
</nz-radio-group> </nz-radio-group>
......
...@@ -129,7 +129,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -129,7 +129,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
onBackgroundUploadSuccess(e) { onBackgroundUploadSuccess(e) {
console.log('e: ', e); console.log('e: ', e);
this.bgItem.url = e.url; this.bgItem.picUrl = e.url;
this.refreshBackground(); this.refreshBackground();
} }
...@@ -148,12 +148,13 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -148,12 +148,13 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
if (!this.bg) { if (!this.bg) {
this.bg = new MySprite(this.ctx); this.bg = new MySprite(this.ctx);
this.renderArr.push(this.bg); this.renderArr.push(this.bg);
console.log(this.renderArr)
} }
const bg = this.bg; const bg = this.bg;
if (this.bgItem.url) { if (this.bgItem.picUrl) {
bg.load(this.bgItem.url).then(() => { bg.load(this.bgItem.picUrl).then(() => {
const rate1 = this.canvasWidth / bg.width; const rate1 = this.canvasWidth / bg.width;
const rate2 = this.canvasHeight / bg.height; const rate2 = this.canvasHeight / bg.height;
...@@ -382,6 +383,14 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -382,6 +383,14 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
} }
initItem() { initItem() {
//定时刷新背景图片
const refreshBg = () =>{
setInterval(()=>{
this.refreshBackground();
}, 2000);
}
if (!this.bgItem) { if (!this.bgItem) {
this.bgItem = {}; this.bgItem = {};
} else { } else {
...@@ -401,6 +410,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -401,6 +410,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
this.initHotZoneArr(); this.initHotZoneArr();
} }
refreshBg();
}); });
} }
...@@ -506,7 +516,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -506,7 +516,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
initData() { initData() {
console.log(this.wrap.nativeElement)
this.canvasWidth = this.wrap.nativeElement.clientWidth; this.canvasWidth = this.wrap.nativeElement.clientWidth;
this.canvasHeight = this.wrap.nativeElement.clientHeight; this.canvasHeight = this.wrap.nativeElement.clientHeight;
this.mapScale = this.canvasWidth / this.canvasBaseW; this.mapScale = this.canvasWidth / this.canvasBaseW;
......
<div class="model-content"> <div class="model-content">
<div nz-row>
<div style="padding: 10px;"> <div nz-col nzOffset='4'>
<h1 nz-title>课程练习内容编辑</h1>
<div style="width: 300px;" align='center'> </div>
<span>图1: </span> </div>
<app-upload-image-with-preview <div nz-row>
[picUrl]="item.pic_url" <div nz-col [nzSpan]="20" nzOffset="2">
(imageUploaded)="onImageUploadSuccess($event, 'pic_url')"> <div nz-form>
<div id='title-anchor'>
<nz-divider nzText="基本信息" nzOrientation="left"></nz-divider>
<nz-form-item>
<nz-form-label [nzSpan]="3" nzFor="title">标题</nz-form-label>
<nz-form-control [nzSpan]="6">
<nz-input-group nzAddOnBefore="Part">
<input type="text" id="title" nz-input [(ngModel)]="item.title.val" (blur)="save()">
</nz-input-group>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSpan]="3" nzFor="audioUrl">发音</nz-form-label>
<nz-form-control [nzSpan]="6">
<app-audio-recorder [audioUrl]="item.title.audioUrl" id="audioUrl"
(audioUploaded)="onAudioUploadSuccess($event, item.title, 'audioUrl')">
</app-audio-recorder>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSpan]="3">背景图片</nz-form-label>
<nz-form-control [nzSpan]="6">
<app-upload-image-with-preview style="width: 100%" [picUrl]="item.bg.picUrl"
(imageUploaded)="onImageUploadSuccess($event,item.bg, 'picUrl')">
</app-upload-image-with-preview> </app-upload-image-with-preview>
</nz-form-control>
</nz-form-item>
</div>
</div>
</div> </div>
</div>
<div style="width: 300px; margin-top: 5px;" align='center'> <div nz-row>
<span>图2: </span> <div id='listen-anchor' nz-col [nzSpan]="20" nzOffset="2">
<app-upload-image-with-preview <nz-divider nzText="练习题" nzOrientation="left"></nz-divider>
[picUrl]="item.pic_url_2" <nz-form-item>
(imageUploaded)="onImageUploadSuccess($event, 'pic_url_2')"> <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 nz-col [nzSpan]="20" nzOffset="2" class='border'>
<div *ngFor="let data of item.exercisesArr;let i = index">
<div class='border-lite'>内容:{{i+1}}
<button style="margin: 10px;" nz-button nzType="danger" (click)="delExercisesItem(i)">
<span>删除</span>
</button>
</div>
<app-custom-hot-zone [bgItem]="item.bg" [hotZoneItemArr]="data.hotZoneItemArr"
(save)="saveData($event, i)"></app-custom-hot-zone>
<nz-form-item>
<nz-form-label [nzSpan]="6">序列帧动画</nz-form-label>
<nz-form-control [nzSpan]="6">
<button nz-button nzType="dashed" class="add-btn" id="add-btn"
(click)="addFrame(data, 'frames')">
<i nz-icon nzType="plus-circle" nzTheme="outline"></i>添加
</button>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control [nzOffset]="2" [nzSpan]="18">
<div nz-col [nzSpan]="6" *ngFor="let frame of data.frames;let m = index">
<app-upload-image-with-preview style="width: 100%" [picUrl]="frame.picUrl"
(imageUploaded)="onImageUploadSuccess($event,frame, 'picUrl')">
</app-upload-image-with-preview> </app-upload-image-with-preview>
<button style="margin: 10px;" nz-button nzType="danger"
(click)="delFrame(data, 'frames', m)">
<span>删除</span>
</button>
</div> </div>
</nz-form-control>
<div style="width: 300px; margin-top: 15px;"> </nz-form-item>
<span>文本: </span> <nz-form-item>
<input type="text" nz-input [(ngModel)]="item.text" (blur)="save()"> <nz-form-label [nzSpan]="6">备选答案</nz-form-label>
<nz-form-control [nzSpan]="6">
<button nz-button nzType="dashed" class="add-btn" id="add-btn"
(click)="addAnswer(data, 'answers')" [disabled]="data.answers.length == 5 ? true : false">
<i nz-icon nzType="plus-circle" nzTheme="outline"></i>添加
</button>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control [nzOffset]="2" [nzSpan]="18">
<nz-table #answerTable nzBordered nzTitle="备选答案" [nzData]="data.answers"
[nzShowPagination]=false>
<thead>
<tr>
<th>序号</th>
<th>音频</th>
<th>图片</th>
<th>是否正确答案</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let answer of answerTable.data;let j = index">
<td>{{ j+1 }}</td>
<td>
<app-audio-recorder [audioUrl]="answer.audioUrl"
(audioUploaded)="onAudioUploadSuccess($event, answer, 'audioUrl')">
</app-audio-recorder>
</td>
<td>
<app-upload-image-with-preview [picUrl]="answer.picUrl"
(imageUploaded)="onImageUploadSuccess($event, answer, 'picUrl')">
</app-upload-image-with-preview>
</td>
<td>
<nz-radio-group [(ngModel)]="answer.isRight" (ngModelChange)="save()">
<label nz-radio nzValue="1"></label>
<label nz-radio nzValue="0"></label>
</nz-radio-group>
</td>
<td>
<button nz-button nzType="danger" (click)="delAnswer(data, 'answers', j)"
[disabled]="data.answers.length == 3 ? true : false">
<span>删除</span>
</button>
</td>
</tr>
</tbody>
</nz-table>
</nz-form-control>
</nz-form-item>
</div> </div>
<div style="margin-top: 5px">
<span>音频: </span>
<app-audio-recorder
[audioUrl]="item.audio_url"
(audioUploaded)="onAudioUploadSuccess($event, 'audio_url')"
></app-audio-recorder>
</div> </div>
</div> </div>
</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 { JsonPipe } from '@angular/common'; import { JsonPipe } from '@angular/common';
import { Answer, Frame, getDefaultExercises, getDefaultItem } from '../bean/ObjBean';
@Component({ @Component({
...@@ -10,32 +11,18 @@ import { JsonPipe } from '@angular/common'; ...@@ -10,32 +11,18 @@ import { JsonPipe } from '@angular/common';
export class FormComponent implements OnInit, OnChanges, OnDestroy { export class FormComponent implements OnInit, OnChanges, OnDestroy {
// 储存数据用 // 储存数据用
saveKey = "test_001"; saveKey = "FT-01";
// 储存对象 // 储存对象
item; item;
constructor(private appRef: ApplicationRef, private changeDetectorRef: ChangeDetectorRef) {
}
createShell() { constructor(private appRef: ApplicationRef, private changeDetectorRef: ChangeDetectorRef) {
this.item.wordList.push({
word: '',
audio: '',
backWord: '',
backWordAudio: '',
});
this.save();
}
removeShell(idx) {
this.item.wordList.splice(idx, 1);
this.save();
} }
ngOnInit() { ngOnInit() {
this.item = {}; this.item = getDefaultItem();
// 获取存储的数据 // 获取存储的数据
(<any>window).courseware.getData((data) => { (<any>window).courseware.getData((data) => {
...@@ -67,20 +54,21 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -67,20 +54,21 @@ 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();
} }
onWordAudioUploadSuccess(e, idx) { onWordAudioUploadSuccess(e, idx) {
this.item.wordList[idx].audio = e.url; this.item.wordList[idx].audio = e.url;
...@@ -111,4 +99,65 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -111,4 +99,65 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
}, 1); }, 1);
} }
/**
* 添加练习
*/
addExercisesItem() {
let exercises = getDefaultExercises();
this.item.exercisesArr.push(exercises);
this.save();
}
delExercisesItem(index) {
if (index !== -1) {
this.item.exercisesArr.splice(index, 1);
this.save();
}
}
addAnswer(exercises, key){
let answer = new Answer();
exercises[key] = [...exercises[key], answer];
this.save();
}
delAnswer(exercises, key, index) {
if (index !== -1) {
exercises[key].splice(index, 1);
exercises[key] = [...exercises[key]];
this.save();
}
}
addFrame(exercises, key){
let frame = new Frame();
exercises[key] = [...exercises[key], frame];
this.save();
}
delFrame(exercises, key, index) {
if (index !== -1) {
exercises[key].splice(index, 1);
exercises[key] = [...exercises[key]];
this.save();
}
}
saveData(e, i) {
console.log('savedata e:', e);
this.item.bg = e.bgItem;
this.item.exercisesArr[i].hotZoneItemArr = e.hotZoneItemArr;
this.save();
}
} }
\ No newline at end of file
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