Commit c32632dd authored by 李维's avatar 李维

ready for dev

parent a970169f
This diff is collapsed.
......@@ -3,9 +3,13 @@
"version": 1,
"newProjectRoot": "projects",
"projects": {
"ng-template-generator": {
"ng-one": {
"projectType": "application",
"schematics": {},
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
......@@ -13,26 +17,39 @@
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/ng-template-generator",
"outputPath": "dist",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": true,
"aot": false,
"assets": [
"src/favicon.ico",
"src/assets",
{ "glob": "**/*", "input": "src/assets/libs/service-worker/", "output": "/" },
{
"glob": "**/*",
"input": "./node_modules/@ant-design/icons-angular/src/inline-svg/",
"output": "/assets/"
},
{
"glob": "**/*",
"input": "./dist/game/",
"output": "/assets/cocos/"
}
],
"styles": [
"src/styles.scss",
"./node_modules/ng-zorro-antd/ng-zorro-antd.min.css",
"src/styles.css"
"./node_modules/font-awesome/css/font-awesome.css",
"./node_modules/bootstrap/dist/css/bootstrap.min.css",
"./node_modules/animate.css/animate.min.css"
],
"scripts": []
"scripts": [
"src/assets/libs/audio-recorder/lame.min.js",
"src/assets/libs/audio-recorder/worker.js",
"src/assets/libs/audio-recorder/recorder.js"
]
},
"configurations": {
"production": {
......@@ -47,39 +64,28 @@
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
"buildOptimizer": true
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "ng-template-generator:build"
"browserTarget": "ng-one:build"
},
"configurations": {
"production": {
"browserTarget": "ng-template-generator:build:production"
"browserTarget": "ng-one:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "ng-template-generator:build"
"browserTarget": "ng-one:build"
}
},
"test": {
......@@ -94,8 +100,7 @@
"src/assets"
],
"styles": [
"./node_modules/ng-zorro-antd/ng-zorro-antd.min.css",
"src/styles.css"
"src/styles.scss"
],
"scripts": []
}
......@@ -117,16 +122,15 @@
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "ng-template-generator:serve"
"devServerTarget": "ng-one:serve"
},
"configurations": {
"production": {
"devServerTarget": "ng-template-generator:serve:production"
"devServerTarget": "ng-one:serve:production"
}
}
}
}
}
},
"defaultProject": "ng-template-generator"
}},
"defaultProject": "ng-one"
}
\ No newline at end of file
......@@ -66,7 +66,7 @@ const runSpawn = async function (){
ls.on('close', (code) => {
console.log(`child process exited with code ${code}`);
//要压缩的目录
let zippath = path.resolve(__dirname,"../dist", pkg.name);
let zippath = path.resolve(__dirname,"../dist");
//压缩包的存放目录
let date = new Date();
let zipname = pkg.name+"_"+date.Format("yyyyMMdd hh-mm-ss");
......@@ -112,3 +112,4 @@ exec();
\ No newline at end of file
This diff is collapsed.
......@@ -2,56 +2,74 @@
"name": "ng-template-generator",
"version": "0.0.1",
"scripts": {
"start": "ng serve",
"start": "ng serve --host=0.0.0.0",
"build": "ng build --build--optimizer --aot --base-href /JGT/v3/",
"publish": "node ./bin/publish.js",
"ng": "ng",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
"publish": "node ./bin/publish.js"
},
"private": true,
"dependencies": {
"@angular/animations": "~9.0.2",
"@angular/common": "~9.0.2",
"@angular/compiler": "~9.0.2",
"@angular/core": "~9.0.2",
"@angular/forms": "~9.0.2",
"@angular/platform-browser": "~9.0.2",
"@angular/platform-browser-dynamic": "~9.0.2",
"@angular/router": "~9.0.2",
"@fortawesome/angular-fontawesome": "^0.6.0",
"@fortawesome/fontawesome-svg-core": "^1.2.27",
"@fortawesome/free-regular-svg-icons": "^5.12.1",
"@fortawesome/free-solid-svg-icons": "^5.12.1",
"@tweenjs/tween.js": "^18.5.0",
"ali-oss": "^6.5.1",
"compressing": "^1.5.0",
"ng-zorro-antd": "^8.5.2",
"rxjs": "~6.5.4",
"@angular/animations": "^7.2.10",
"@angular/cdk": "^7.2.2",
"@angular/common": "^7.2.10",
"@angular/compiler": "^7.2.10",
"@angular/core": "^7.2.10",
"@angular/flex-layout": "^7.0.0-beta.24",
"@angular/forms": "^7.2.10",
"@angular/http": "^7.2.10",
"@angular/material": "^7.2.2",
"@angular/platform-browser": "^7.2.10",
"@angular/platform-browser-dynamic": "^7.2.10",
"@angular/platform-server": "^7.2.10",
"@angular/router": "^7.2.10",
"@tweenjs/tween.js": "^17.3.0",
"ali-oss": "^6.0.0",
"angular-cropperjs": "^1.0.1",
"angular2-draggable": "^2.1.9",
"angular2-fontawesome": "^5.2.1",
"angularx-qrcode": "^1.5.3",
"animate.css": "^3.7.0",
"bootstrap": "^4.1.1",
"browser-image-compression": "^1.0.5",
"compressing": "^1.4.0",
"core-js": "^2.6.1",
"cropperjs": "1.4.1",
"css-element-queries": "^1.0.2",
"decimal.js": "^10.0.1",
"font-awesome": "^4.7.0",
"hammerjs": "^2.0.8",
"install": "^0.12.2",
"karma-cli": "^2.0.0",
"lodash": "^4.17.10",
"nedb": "^1.8.0",
"ng-lottie": "^0.3.1",
"ng-zorro-antd": "^7.2.0",
"npm": "^6.5.0",
"rxjs": "^6.3.3",
"rxjs-compat": "^6.3.3",
"rxjs-tslint": "^0.1.6",
"spark-md5": "^3.0.0",
"tslib": "^1.10.0",
"zone.js": "~0.10.2"
"webpack": "^4.28.2",
"zone.js": "^0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.900.3",
"@angular/cli": "~9.0.3",
"@angular/compiler-cli": "~9.0.2",
"@angular/language-service": "~9.0.2",
"@types/jasmine": "~3.5.0",
"@angular-devkit/build-angular": "^0.11.4",
"@angular/cli": "^7.2.10",
"@angular/compiler-cli": "^7.2.10",
"@angular/language-service": "^7.2.10",
"@types/jasmine": "^3.3.5",
"@types/jasminewd2": "~2.0.3",
"@types/node": "^12.11.1",
"codelyzer": "^5.1.2",
"jasmine-core": "~3.5.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~4.3.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~2.1.0",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.2",
"protractor": "~5.4.3",
"ts-node": "~8.3.0",
"tslint": "~5.18.0",
"typescript": "~3.7.5"
"@types/node": "^10.12.18",
"codelyzer": "^4.5.0",
"jasmine-core": "^3.3.0",
"jasmine-spec-reporter": "^4.2.1",
"karma": "^3.1.4",
"karma-chrome-launcher": "^2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.0",
"karma-jasmine": "^2.0.1",
"karma-jasmine-html-reporter": "^1.4.0",
"protractor": "^5.4.2",
"ts-node": "~5.0.1",
"tslint": "^5.12.0",
"typescript": "3.1.1"
}
}
......@@ -5,12 +5,12 @@ import { Component , OnInit} from '@angular/core';
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
export class AppComponent implements OnInit{
type = 'play';
constructor() {
const tp = this.getQueryString('type');
if (tp) {
let tp = this.getQueryString("type");
if (tp){
this.type = tp;
}
}
......
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { NgZorroAntdModule, NZ_I18N, zh_CN } from 'ng-zorro-antd';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgZorroAntdModule, NZ_I18N, zh_CN } from 'ng-zorro-antd';
import { NzButtonModule } from 'ng-zorro-antd/button';
import {Angular2FontawesomeModule} from 'angular2-fontawesome/angular2-fontawesome';
import { AppComponent } from './app.component';
import { FormComponent } from './form/form.component';
import { PlayComponent } from "./play/play.component";
import { LessonTitleConfigComponent } from './common/lesson-title-config/lesson-title-config.component';
import { AudioRecorderComponent } from './common/audio-recorder/audio-recorder.component';
import { PlayerContentWrapperComponent } from './common/player-content-wrapper/player-content-wrapper.component';
/** 配置 angular i18n **/
import { registerLocaleData } from '@angular/common';
import zh from '@angular/common/locales/zh';
import {FormComponent} from './form/form.component';
import {PlayComponent} from './play/play.component';
import {LessonTitleConfigComponent} from './common/lesson-title-config/lesson-title-config.component';
import {BackgroundImagePipe} from './pipes/background-image.pipe';
import {UploadImageWithPreviewComponent} from './common/upload-image-with-preview/upload-image-with-preview.component';
import {PlayerContentWrapperComponent} from './common/player-content-wrapper/player-content-wrapper.component';
import {CustomHotZoneComponent} from './common/custom-hot-zone/custom-hot-zone.component';
import {UploadVideoComponent} from './common/upload-video/upload-video.component';
import {TimePipe} from './pipes/time.pipe';
import {ResourcePipe} from './pipes/resource.pipe';
import {AudioRecorderComponent} from './common/audio-recorder/audio-recorder.component';
import { FontAwesomeModule, FaIconLibrary } from '@fortawesome/angular-fontawesome';
import { fas } from '@fortawesome/free-solid-svg-icons';
import { far } from '@fortawesome/free-regular-svg-icons';
import {UploadImageWithPreviewComponent} from "./common/upload-image-with-preview/upload-image-with-preview.component";
import {BackgroundImagePipe} from "./pipes/background-image.pipe";
import {UploadVideoComponent} from "./common/upload-video/upload-video.component";
import {ResourcePipe} from "./pipes/resource.pipe";
import {TimePipe} from "./pipes/time.pipe";
import {CustomHotZoneComponent} from "./common/custom-hot-zone/custom-hot-zone.component";
registerLocaleData(zh);
@NgModule({
......@@ -38,23 +41,21 @@ registerLocaleData(zh);
TimePipe,
UploadVideoComponent,
CustomHotZoneComponent,
PlayerContentWrapperComponent
],
imports: [
BrowserModule,
NgZorroAntdModule,
FormsModule,
HttpClientModule,
BrowserAnimationsModule,
FontAwesomeModule
BrowserModule,
Angular2FontawesomeModule,
NgZorroAntdModule,
],
/** 配置 ng-zorro-antd 国际化(文案 及 日期) **/
providers : [
{ provide: NZ_I18N, useValue: zh_CN }
],
providers: [{ provide: NZ_I18N, useValue: zh_CN }],
bootstrap: [AppComponent]
})
export class AppModule {
constructor(library: FaIconLibrary) {
library.addIconPacks(fas, far);
}
}
export class AppModule { }
<div class="d-flex">
<div class="p-btn-record d-flex">
<div class="btn-clear" style="cursor: pointer" (click)="onBtnClearAudio()" *ngIf="withRmBtn && (audioUrl || audioBlob)">
<fa-icon icon="times"></fa-icon>
<div
class="btn-clear"
(click)="onBtnClearAudio()"
*ngIf="withRmBtn && (audioUrl || audioBlob)"
>
<fa name="close"></fa>
</div>
<div class="btn-record" *ngIf="type===Type.RECORD && !isUploading"
<div
class="btn-record"
*ngIf="type === Type.RECORD && !isUploading"
[class.p-recording]="isRecording"
(click)="onBtnRecord()">
<fa-icon icon="microphone"></fa-icon>
(click)="onBtnRecord()"
>
<i nz-icon nzType="audio" nzTheme="outline"></i>
Record Audio
</div>
<nz-upload
[nzAccept] = "'.mp3'"
[nzAccept]="'.mp3'"
[nzShowUploadList]="false"
[nzAction]="uploadUrl"
[nzData]="uploadData"
(nzChange)="handleChange($event)">
<div class="btn-upload" [ngClass]="{'has-clear': withRmBtn && (audioUrl || audioBlob)}" *ngIf="type===Type.UPLOAD && !isUploading">
<fa-icon icon="upload"></fa-icon>
(nzChange)="handleChange($event)"
>
<div
class="btn-upload ng-star-inserted"
[ngClass]="{ 'has-clear': withRmBtn && (audioUrl || audioBlob) }"
*ngIf="type === Type.UPLOAD && !isUploading"
>
<i nz-icon nzType="cloud-upload" nzTheme="outline"></i>
Upload Audio
</div>
</nz-upload>
<div class="p-upload-progress-bg" *ngIf="isUploading">
<div class="i-bg" [style.width]="progress+'%'"></div>
<div class="i-bg" [style.width]="progress + '%'"></div>
<div class="i-text">
<fa-icon icon="cloud-upload-alt"></fa-icon>
<i nz-icon nzType="loading" nzTheme="outline"></i>
Uploading...
</div>
</div>
<div
*ngIf="audioUrl && needRemove; then truthyTemplate; else falsyTemplate"
></div>
<div *ngIf="audioUrl && needRemove; then truthyTemplate else falsyTemplate"></div>
<ng-template #truthyTemplate >
<ng-template #truthyTemplate>
<div class="btn-delete" (click)="onBtnDeleteAudio()">
<fa-icon icon="close"></fa-icon>
<i nz-icon nzType="close" nzTheme="outline"></i>
</div>
</ng-template>
<ng-template #falsyTemplate>
<div class="btn-switch" (click)="onBtnSwitchType()">
<fa-icon icon="cog"></fa-icon>
<i nz-icon nzType="setting" nzTheme="outline"></i>
</div>
</ng-template>
</div>
<div class="p-progress ml-2" (click)="onBtnPlay()" *ngIf="audioUrl || audioBlob">
<nz-progress [nzPercent]="percent" [nzWidth]="30" [nzFormat]="progressText"
nzType="circle"></nz-progress>
<div class="p-btn-play" [style.left]="isPlaying?'8px':''">
<fa-icon [icon]="playIcon"></fa-icon>
<div
class="p-progress ml-2"
(click)="onBtnPlay()"
*ngIf="audioUrl || audioBlob"
>
<nz-progress
[nzPercent]="percent"
[nzWidth]="30"
[nzFormat]="progressText"
nzType="circle"
></nz-progress>
<div class="p-btn-play" [style.left]="isPlaying ? '8px' : ''">
<i nz-icon nzType="caret-right" nzTheme="outline"></i>
</div>
</div>
</div>
.d-flex{
display: flex;
}
.p-btn-record {
font-size: 0.9rem;
color: #555;
......@@ -91,6 +88,7 @@
.p-progress {
margin-top: 2px;
margin-left: 5px;
position: relative;
line-height: 26px;
.p-btn-play {
......@@ -105,3 +103,6 @@
line-height: 33px;
}
.d-flex{
display: flex;
}
\ No newline at end of file
......@@ -19,11 +19,10 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
isUploading = false;
type = Type.UPLOAD; // record | upload
Type = Type;
@Input()
withRmBtn = false;
uploadUrl = (window as any).courseware.uploadUrl();
uploadData = (window as any).courseware.uploadData();
uploadUrl = (<any>window).courseware.uploadUrl();
uploadData = (<any>window).courseware.uploadData();
@Input()
needRemove = false;
......@@ -33,7 +32,7 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
@Input()
set audioUrl(url) {
this._audioUrl = url;
this._audioUrl = url
if (url) {
this.audio.src = this._audioUrl;
this.audio.load();
......@@ -145,7 +144,6 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
onBtnSwitchType() {
}
onBtnClearAudio() {
this.audioUrl = null;
this.audioRemoved.emit();
}
......
......@@ -16,7 +16,7 @@
<div class="bg-box">
<app-upload-image-with-preview
[picUrl]="bgItem?.url"
[picUrl]="bgItem.url"
(imageUploaded)="onBackgroundUploadSuccess($event)">
</app-upload-image-with-preview>
</div>
......@@ -76,7 +76,7 @@
<button class="save-btn" nz-button nzType="primary" [nzSize]="'large'" nzShape="round"
(click)="saveClick()">
<i nz-icon nzType="save"></i>
<i nz-icon type="save"></i>
Save
</button>
......
......@@ -42,8 +42,8 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
@Output()
save = new EventEmitter();
@ViewChild('canvas', {static: true }) canvas: ElementRef;
@ViewChild('wrap', {static: true }) wrap: ElementRef;
@ViewChild('canvas') canvas: ElementRef;
@ViewChild('wrap') wrap: ElementRef;
// @HostListener('window:resize', ['$event'])
canvasWidth = 1280;
......@@ -613,9 +613,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
update() {
if (!this.ctx) {
return;
}
this.animationId = window.requestAnimationFrame(this.update.bind(this));
......
<div class="title-config">
<div class="title-wrap">
......@@ -8,10 +7,9 @@
<nz-select class="ml-1" style="width: 120px;" [(ngModel)]="__fontFamily"
(ngModelChange)="onChangeFontFamily($event)"
nzPlaceHolder="Font Family"
[nzDropdownMatchSelectWidth]="false">
<nz-option [nzValue]="font" nzCustomContent [nzLabel]="font" *ngFor="let font of fontFamilyList">
<span [ngStyle]="{'font-family': font}" >{{font}}</span>
</nz-option>
[nzDropdownMatchSelectWidth]="false"
>
<nz-option [nzValue]="font" [nzLabel]="font" *ngFor="let font of fontFamilyList"></nz-option>
</nz-select>
<nz-select class="ml-1" style="width: 110px;" [(ngModel)]="__fontSize"
(ngModelChange)="onChangeFontSize()"
......@@ -21,33 +19,28 @@
<div class="p-divider"></div>
<div class="i-tool-font-btn d-flex mr-2">
<div class="position-relative fa-icon" (click)="onChangeBold()">
<!-- <div class="fa fa-bold"></div>-->
<fa-icon icon="bold"></fa-icon>
<div class="fa fa-bold"></div>
</div>
</div>
<div class="i-tool-font-btn d-flex mr-2">
<div class="position-relative fa-icon" (click)="onChangeItalic()">
<!-- <div class="fa fa-italic"></div>-->
<fa-icon icon="italic"></fa-icon>
<div class="fa fa-italic"></div>
</div>
</div>
<div class="i-tool-font-btn d-flex mr-2">
<div class="position-relative fa-icon" (click)="onChangeUnderline()">
<!-- <div class="fa fa-underline"></div>-->
<fa-icon icon="underline"></fa-icon>
<div class="fa fa-underline"></div>
</div>
</div>
<div class="i-tool-font-btn d-flex">
<div class="position-relative fa-icon" (click)="onChangeStrikethrough()">
<!-- <div class="fa fa-strikethrough"></div>-->
<fa-icon icon="strikethrough"></fa-icon>
<div class="fa fa-strikethrough"></div>
</div>
</div>
<div class="p-divider"></div>
<div class="i-tool-font-color d-flex">
<div class="position-relative i-left flex-fill" (click)="onChangeFontColor($event)">
<!-- <div class="fa fa-font"></div>-->
<fa-icon icon="palette"></fa-icon>
<div class="fa fa-font"></div>
<div class="i-color" [style.background-color]="__fontColor"></div>
</div>
<div class="i-dropdown-menu" nzPlacement="bottom"
......@@ -58,14 +51,14 @@
</div>
<div class="p-divider"></div>
<div style="background: #fff;display: block;">
<div class="position-relative">
<div class="position-relative" (click)="onChangeStrikethrough()">
<app-audio-recorder [audioUrl]="titleObj && titleObj.audio_url" (audioUploaded)="titleAudioUploaded($event)"></app-audio-recorder>
</div>
</div>
</div>
<div class="width-100 d-flex">
<iframe #titleEl id="titleContentEgret" frameborder="0" style="overflow: hidden;width: 100%; height:48px; margin: 0; padding: 0;"></iframe>
<iframe #titleEl frameborder="0" style="overflow: hidden;width: 100%; height:48px; margin: 0; padding: 0;"></iframe>
</div>
</div>
......@@ -83,11 +76,37 @@
<ng-container *ngIf="withIcon">
<div class="row type-row">
课程类型:
<nz-radio-group [(ngModel)]="titleObj && titleObj.type" (ngModelChange)="typeChange($event)">
<label nz-radio nzValue="a">单数课</label>
<label nz-radio nzValue="b">双数课</label>
<label nz-radio nzValue="c">复习课</label>
</nz-radio-group>
</div>
</ng-container>
</div>
<ng-container *ngIf="withIcon">
<div class="title-icons">
<div class="icons-list">
<nz-checkbox-wrapper style="width: 100%;clear:both" (nzOnChange)="iconsChanges($event)">
<div [class]="'icon-item icon-'+i" *ngFor="let i of groupIconsCount[titleObj.type];">
<div class="img-box">
<nz-badge class="icon-badge" [nzCount]="titleObj && titleObj.icons && titleObj.icons.indexOf(i) + 1">
<img [src]="'assets/title-icons/'+titleObj.type+'/icon-'+i+'.png'" alt="">
</nz-badge>
</div>
<label nz-checkbox [nzValue]="i" [ngModel]="titleObj && titleObj.icons && titleObj.icons.indexOf(i) > -1"></label>
</div>
</nz-checkbox-wrapper>
</div>
</div>
</ng-container>
</div>
@import '../../style/common_mixin.css';
@import '../../style/common_mixin';
.title-config {
.letter-wrap{
......@@ -11,73 +11,39 @@
.type-row{
margin: 0;padding-top: 1rem;
}
}
@font-face
{
font-family: 'BRLNSDB';
src: url("../../../assets/font/BRLNSDB.TTF") ;
}
@font-face
{
font-family: 'BRLNSB';
src: url("../../../assets/font/BRLNSB.TTF") ;
}
@font-face
{
font-family: 'BRLNSR';
src: url("../../../assets/font/BRLNSR.TTF") ;
}
@font-face
{
font-family: 'GOTHIC';
src: url("../../../assets/font/GOTHIC.TTF") ;
}
@font-face
{
font-family: 'GOTHICB';
src: url("../../../assets/font/GOTHICB.TTF") ;
}
@font-face
{
font-family: 'GOTHICBI';
src: url("../../../assets/font/GOTHICBI.TTF") ;
}
@font-face
{
font-family: 'GOTHICI';
src: url("../../../assets/font/GOTHICI.TTF") ;
}
@font-face
{
font-family: 'MMTextBook';
src: url("../../../assets/font/MMTextBook.otf") ;
}
@font-face
{
font-family: 'MMTextBook-Bold';
src: url("../../../assets/font/MMTextBook-Bold.otf") ;
}
@font-face
{
font-family: 'MMTextBook-BoldItalic';
src: url("../../../assets/font/MMTextBook-BoldItalic.otf") ;
.icon-item{
margin-right: 16px;
float: left;
width: 45px;
height: 75px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
.icon-badge{
position: absolute;
top: 0;
right: 0;
}
.img-box{
top: 0;
position: absolute;
width: 45px;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
img{
max-width: 100%;
}
}
label{
position: absolute;
bottom: 0;
}
}
}
@font-face
{
font-family: 'MMTextBook-Italic';
src: url("../../../assets/font/MMTextBook-Italic.otf") ;
}
@mixin tool-btn {
border: 1px solid #ddd;
display: flex;
......@@ -88,37 +54,16 @@
border-radius: 6px;
color: #555;
}
.d-flex{
display: flex;
}
.position-relative {
position: relative;
}
.flex-fill {
-webkit-box-flex: 1;
flex: 1 1 auto;
justify-content: center;
display: flex;
}
.i-dropdown-menu{
width: 15px;
font-size: 10px;
border-left: 1px solid #ddd;
display: -webkit-box;
display: flex;
-webkit-box-align: center;
align-items: center;
flex: 0
}
.p-title-box .p-title {
.p-title-box {
.p-title {
font-size: 20px;
}
.p-title-box input {
input {
width: 300px;
margin-left: 10px;
}
}
.p-content {
border: 1px solid #ddd;
......@@ -140,31 +85,33 @@
align-items: center;
border-bottom: 1px solid #ddd;
}
// save
.i-tool-save {
//@include tool-btn();
// save
.i-tool-save {
@include tool-btn();
color: white;
}
.i-tool-save:disabled {
}
.i-tool-save:disabled {
color: #555;
}
}
// font-size
.i-tool-font-size {
//@include tool-btn();
// font-size
.i-tool-font-size {
@include tool-btn();
width: 37px;
}
.i-tool-font-size:hover {
& > span {
position: absolute;
top: -5px;
right: 5px;
}
}
.i-tool-font-size:hover {
color: black;
border-color: #bbb;
}
}
// font-color
.i-tool-font-color, .i-tool-font-btn {
// font-color
.i-tool-font-color, .i-tool-font-btn {
border: 1px solid #ddd;
//padding: 3px 7px;
border-radius: 6px;
......@@ -208,20 +155,20 @@
transform: scale(0.6);
}
}
}
.i-tool-font-btn{
}
.i-tool-font-btn{
width: 31px;
}
.fa-icon{
}
.fa-icon{
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
// bg-color
.i-tool-bg-color {
}
// bg-color
.i-tool-bg-color {
@include tool-btn();
padding: 0 9px;
::ng-deep > span {
......@@ -236,14 +183,17 @@
background-color: white;
margin-left: 10px;
}
}
}
// horizontal-center
.i-tool-horizontal-center {
// horizontal-center
.i-tool-horizontal-center {
@include tool-btn();
width: 37px;
}
}
.p-box {
width: 1280px;
height: 720px;
......@@ -253,7 +203,9 @@
overflow: hidden;
}
.p-sentence {
@include k-no-select();
}
.p-animation-index-box {
.i-animation-index {
......@@ -326,6 +278,7 @@
::ng-deep .ant-radio-button-wrapper {
padding: 0 10px;
@include k-no-select();
}
.i-toolbox {
......@@ -356,6 +309,7 @@
cursor: pointer;
text-align: left;
display: flex;
@include k-no-select();
}
.i-active {
background-color: antiquewhite;
......
import {
Component,
ElementRef,
......@@ -11,82 +10,6 @@ import {
ViewChild
} from '@angular/core';
const editorTpl = `<html lang="en"><head><meta charset="utf-8">
<meta name="viewport"
content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"/>
<style>
@font-face{
font-family: 'BRLNSDB';
src: url("../../../assets/font/BRLNSDB.TTF") ;
}
@font-face{
font-family: 'BRLNSB';
src: url("../../../assets/font/BRLNSB.TTF") ;
}
@font-face{
font-family: 'BRLNSR';
src: url("../../../assets/font/BRLNSR.TTF") ;
}
@font-face{
font-family: 'GOTHIC';
src: url("../../../assets/font/GOTHIC.TTF") ;
}
@font-face{
font-family: 'GOTHICB';
src: url("../../../assets/font/GOTHICB.TTF") ;
}
@font-face{
font-family: 'GOTHICBI';
src: url("../../../assets/font/GOTHICBI.TTF") ;
}
@font-face{
font-family: 'GOTHICI';
src: url("../../../assets/font/GOTHICI.TTF") ;
}
@font-face{
font-family: 'MMTextBook';
src: url("../../../assets/font/MMTextBook.otf") ;
}
@font-face{
font-family: 'MMTextBook-Bold';
src: url("../../../assets/font/MMTextBook-Bold.otf") ;
}
@font-face{
font-family: 'MMTextBook-BoldItalic';
src: url("../../../assets/font/MMTextBook-BoldItalic.otf") ;
}
@font-face{
font-family: 'MMTextBook-Italic';
src: url("../../../assets/font/MMTextBook-Italic.otf") ;
}
html, body{
/*font-size: 30px;*/
}
body{
height:48px;
overflow: hidden;
margin: 0;
padding: 0 .5rem;
font-family: 'BRLNSB, BRLNSDB, BRLNSR, GOTHIC, GOTHICB, MMTextBook';
background: #FFF;
line-height: 48px;
}
</style>
</head>
<body>{{content}}</body>
</html>`;
@Component({
selector: 'app-lesson-title-config',
templateUrl: './lesson-title-config.component.html',
......@@ -96,45 +19,22 @@ export class LessonTitleConfigComponent implements OnInit, OnChanges, OnDestroy,
fontFamilyList = [
'Arial',
'BRLNSB',
'BRLNSDB',
'BRLNSR',
'GOTHIC',
'GOTHICB',
// "GOTHICBI",
// "GOTHICI",
'MMTextBook',
// "MMTextBook-Bold",
// "MMTextBook-Italic",
// "MMTextBook-BoldItalic",
'ARBLI'
];
colorList = [
'#000000',
'#111111',
'#ffffff',
'#595959',
'#0075c2',
'#c61c1e',
'#9cbc3a',
'#008000',
'#FF0000',
'#D2691E',
'#9cbc3a'
];
MIN_FONT_SIZE = 1;
MAX_FONT_SIZE = 7;
isShowFontColorPane = false;
isShowBGColorPane = false;
fontSizeRange = [
// {name: '1号', value: 9},
// {name: '2号', value: 13},
// {name: '3号', value: 16},
// {name: '4号', value: 18},
// {name: '5号', value: 24},
// {name: '6号', value: 32},
];
fontSizeRange: number[];
editorContent = '';
......@@ -145,17 +45,25 @@ export class LessonTitleConfigComponent implements OnInit, OnChanges, OnDestroy,
loopCnt = 0;
maxLoops = 20;
@ViewChild('titleEl', {static: true}) titleEl: ElementRef;
groupIconsCount = {
a: Array.from(Array(11).keys()),
b: Array.from(Array(8).keys()),
c: Array.from(Array(8).keys()),
};
prevIcons = [];
prevType = '';
@ViewChild('titleEl') titleEl: ElementRef;
titleEW = null;
@Input()
titleObj = {
type: 'a',
content: '',
icons: [],
audio_url: ''
};
@Input()
withIcon = true;
@Output()
titleUpdated = new EventEmitter();
......@@ -176,12 +84,16 @@ export class LessonTitleConfigComponent implements OnInit, OnChanges, OnDestroy,
let defObj = this.titleObj;
if (!vars.titleObj.currentValue) {
defObj = {
type: 'a',
content: '',
icons: [],
audio_url: ''
};
} else {
defObj = vars.titleObj.currentValue;
}
this.titleObj.icons = defObj.icons || [];
this.titleObj.type = defObj.type || 'a';
this.titleObj.content = defObj.content || '';
this.titleObj.audio_url = defObj.audio_url || '';
this.titleEW.document.body.innerHTML = this.titleObj.content;
......@@ -190,23 +102,33 @@ export class LessonTitleConfigComponent implements OnInit, OnChanges, OnDestroy,
ngOnInit() {
if (!this.titleObj) {
this.titleObj = {
type: 'a',
content: '',
icons: [],
audio_url: ''
};
}
this.titleObj.icons = this.titleObj.icons || [];
this.titleObj.type = this.titleObj.type || 'a';
this.titleObj.content = this.titleObj.content || '';
this.titleObj.audio_url = this.titleObj.audio_url || '';
this.editorContent = editorTpl.replace('{{content}}', this.titleObj.content) ;
this.editorContent = `<html lang="en"><head><meta charset="utf-8">
<meta name="viewport"
content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"/>
</head>
<body style="height:48px;overflow: hidden;margin: 0;padding: 0 .5rem;background: #FFF;line-height: 48px;">
${this.titleObj.content}
</body>
</html>`;
this.titleEW = this.titleEl.nativeElement.contentWindow;
console.log('this.titleEW', this.titleEW);
const tdoc = this.titleEW.document;
tdoc.designMode = 'on';
tdoc.designMode = "on";
tdoc.open('text/html', 'replace');
tdoc.write(this.editorContent);
tdoc.close();
tdoc.addEventListener('keypress', this.keyPress, true);
tdoc.addEventListener('blur', () => {
tdoc.addEventListener("keypress", this.keyPress, true);
tdoc.addEventListener("blur", () => {
if (this.titleObj.content === this.titleEW.document.body.innerHTML.trim()) {
return;
}
......@@ -237,7 +159,30 @@ export class LessonTitleConfigComponent implements OnInit, OnChanges, OnDestroy,
ngOnDestroy(): void {
}
iconsChanges(val) {
let a = this.titleObj.icons;
let b = val;
if (a.length > b.length) {
const diff = a.filter(x => !b.includes(x));
const ti = [...this.titleObj.icons];
for (let i = 0; i < diff.length; i++) {
const d = diff[i];
const idx = ti.indexOf(d);
ti.splice(idx, 1);
}
this.titleObj.icons = ti;
} else {
const diff = b.filter(x => !a.includes(x));
this.titleObj.icons = [...this.titleObj.icons, ...diff];
}
this.shouldSave();
}
typeChange(val) {
this.titleObj.icons = [];
this.shouldSave();
}
keyPress(evt) {
try {
......@@ -250,9 +195,9 @@ export class LessonTitleConfigComponent implements OnInit, OnChanges, OnDestroy,
const key = String.fromCharCode(evt.charCode).toLowerCase();
let cmd = '';
switch (key) {
case 'b': cmd = 'bold'; break;
case 'i': cmd = 'italic'; break;
case 'u': cmd = 'underline'; break;
case 'b': cmd = "bold"; break;
case 'i': cmd = "italic"; break;
case 'u': cmd = "underline"; break;
}
......@@ -269,13 +214,10 @@ export class LessonTitleConfigComponent implements OnInit, OnChanges, OnDestroy,
alert(e);
}
}
execEditorCommand(command, option?: any) {
console.log('sssss');
try {
this.titleEW.focus();
const result = this.titleEW.document.execCommand(command, false, option);
console.log(result);
this.titleEW.document.execCommand(command, false, option);
this.loopCnt = 0;
return false;
......@@ -287,7 +229,7 @@ export class LessonTitleConfigComponent implements OnInit, OnChanges, OnDestroy,
}, 100);
this.loopCnt += 1;
} else {
alert('Error executing command.');
alert("Error executing command.");
}
}
}
......@@ -300,7 +242,7 @@ export class LessonTitleConfigComponent implements OnInit, OnChanges, OnDestroy,
this.execEditorCommand('forecolor', this.__fontColor);
}
onChangeFontFamily(font) {
this.execEditorCommand('fontName', font);
this.execEditorCommand('fontname', font);
}
onChangeFontSize(size?: any) {
......@@ -330,10 +272,9 @@ export class LessonTitleConfigComponent implements OnInit, OnChanges, OnDestroy,
this.titleUpdated.emit(this.titleObj);
}
shouldSave = () => {
console.log('title shouldSave', this.titleObj);
console.log('title shouldSave');
this.titleObj.content = this.titleEW.document.body.innerHTML.trim();
this.titleUpdated.emit(this.titleObj);
}
}
@import '../../style/common_mixin.css';
@import '../../style/common_mixin';
.cmp-player-content-wrapper{
max-height: 100%;
......
......@@ -18,7 +18,7 @@ import {
export class PlayerContentWrapperComponent implements OnInit, OnChanges, OnDestroy, AfterViewInit {
@ViewChild('wrapperEl', {static: true }) wrapperEl: ElementRef;
@ViewChild('wrapperEl') wrapperEl: ElementRef;
// // aspect ratio?
@Input() ratio;
......
......@@ -5,21 +5,16 @@
[nzAction]="uploadUrl"
[nzData]="uploadData"
(nzChange)="handleChange($event)">
<!--[nzBeforeUpload]="customUpload">-->
<div class="p-box d-flex align-items-center">
<div class="p-upload-icon" *ngIf="!picUrl && !uploading">
<i nz-icon nzType="cloud-upload" nzTheme="outline" [style.font-size]="iconSize + 'em'"></i>
<i nz-icon type="cloud-upload" theme="outline" [style.font-size]="iconSize + 'em'"></i>
<div class="m-3"></div>
<span>{{TIP}}</span>
<!--<div class="mt-5 p-progress-bar" *ngIf="uploading">-->
<!--<div class="p-progress-bg" [style.width]="progress*0.2+'rem'"></div>-->
<!--<div class="p-progress-value">{{progress}}%</div>-->
<!--</div>-->
</div>
<div class="p-upload-progress-bg" *ngIf="uploading">
<div class="i-bg" [style.width]="progress+'%'"></div>
<div class="i-text">
<fa-icon icon="cloud-upload-alt"></fa-icon>
<fa name="cloud-upload"></fa>
Uploading...
</div>
</div>
......@@ -32,6 +27,6 @@
nz-popconfirm nzTitle="Are you sure ?"
(nzOnConfirm)="onDelete()"
>
<i nz-icon nzType="close" nzTheme="outline"></i>
<i nz-icon type="close" theme="outline"></i>
</div>
</div>
@import '../../style/common_mixin.css';
@import '../../style/common_mixin';
.p-image-uploader {
position: relative;
......@@ -52,15 +52,10 @@
.p-preview {
width: 100%;
height: 100%;
background-size: contain;
background-repeat: no-repeat;
background-position: 50% 50%;
//background-image: url("https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png");
@include k-img-bg();
}
}
.d-flex{
display: flex;
}
}
.p-btn-delete {
......
<div class="p-video-box">
<div class="up-video" style="display: flex;">
<!--<nz-upload class="" [nzDisabled]="!showUploadBtn"-->
<!--[nzShowUploadList]="false"-->
......@@ -16,7 +16,8 @@
<button type="button" nz-button nzType="default" *ngIf="showUploadBtn" [disabled]="uploading"
[nzLoading]="uploading" >
<i nz-icon nzType="plus" nzTheme="outline"></i>
<i nz-icon type="plus" theme="outline"></i>
<span>{{ uploading ? 'Uploading' : 'Select Video' }}</span>
<!--<span>Select Video</span>-->
</button>
......@@ -55,9 +56,9 @@
</div>
<div class="p-box d-flex align-items-center p-video-uploader">
<div class="p-box d-flex align-items-center p-video-uploader" style="top: 20px;">
<div class="p-upload-icon" *ngIf="!showUploadBtn && !videoUrl && !uploading">
<i nz-icon nzType="upload" nzTheme="outline"></i>
<i nz-icon type="upload" theme="outline"></i>
<div class="m-3"></div>
<span>Click here to upload video</span>
<div class="mt-5 p-progress-bar" *ngIf="uploading">
......@@ -69,26 +70,26 @@
[ngClass]="{'smart-bar': showUploadBtn}" >
<div class="i-bg" [style.width]="progress+'%'"></div>
<div class="i-text">
<fa-icon icon="cloud-upload-alt"></fa-icon>
<fa name="cloud-upload"></fa>
Uploading...
</div>
</div>
<div class="p-upload-check-bg" *ngIf="checking">
<div class="i-bg" [style.width]="progress+'%'"></div>
<div class="i-text">
<fa-icon icon="cloud-upload-alt"></fa-icon>
<i nz-icon nzType="loading" nzTheme="outline"></i>Checking...
<fa name="cloud-upload"></fa>
<i nz-icon type="loading" theme="outline"></i>Checking...
</div>
</div>
<div class="p-preview" *ngIf="!uploading && videoUrl " >
<div class="p-preview" *ngIf="!showUploadBtn && !uploading && videoUrl " >
<!--<video crossorigin="anonymous" [src]="videoUrl" controls #videoNode></video>-->
<video [src]="safeVideoUrl(videoUrl)" controls #videoNode></video>
<video [src]="safeVideoUrl(videoUrl)" controls #videoNode (loadedmetadata)="videoLoadedMetaData()"></video>
</div>
</div>
<div [style.display]="!checkVideoExists?'none':''">
<span><i nz-icon nzType="loading" nzTheme="outline"></i> checking file to upload</span>
</div>
<span><i nz-icon type="loading" theme="outline"></i> checking file to upload</span>
</div>
@import '../../style/common_mixin.css';
/*.p-video-box{
bottom: 0;
border: 2px dashed #ddd;
border-radius: 0.5rem;
background-color: #fafafa;
text-align: center;
color: #aaa;
padding-top: 56.25%;
//font-size: 4rem;
position: relative;
.p-upload-icon{
left: 50%;
position: absolute;
top: 50%;
transform: translate(-50% ,-50%);
}
}*/
@import '../../style/common_mixin';
.p-video-uploader {
position: relative;
display: block;
......@@ -33,33 +17,25 @@
background-color: #fafafa;
text-align: center;
color: #aaa;
}
}
.p-upload-icon {
.p-upload-icon {
text-align: center;
margin: auto;
}
.p-upload-icon .anticon-upload {
.anticon-upload {
color: #888;
font-size: 5rem;
}
p-progress-bar {
}
.p-progress-bar {
position: relative;
width: 20rem;
height: 1.5rem;
border: 1px solid #ccc;
border-radius: 1rem;
}
.p-progress-bar .p-progress-bg {
.p-progress-bg {
background-color: #1890ff;
border-radius: 1rem;
height: 100%;
}
.p-progress-bar .p-progress-value {
}
.p-progress-value {
position: absolute;
top: 0;
left: 0;
......@@ -70,19 +46,21 @@ p-progress-bar {
text-align: center;
font-size: 0.9rem;
line-height: 1.5rem;
}
.p-preview {
}
}
}
.p-preview {
width: 100%;
height: 100%;
//background-image: url("https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png");
}
.p-preview video{
video{
max-height: 100%;
max-width: 100%;
position: absolute;
display: flex;
}
}
}
}
.p-btn-delete {
position: absolute;
right: -0.5rem;
......
import {Component, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, Output, SecurityContext, ViewChild} from '@angular/core';
import {NzMessageService, UploadChangeParam, UploadFile, UploadFileStatus} from 'ng-zorro-antd';
import {NzMessageService, UploadFile} from 'ng-zorro-antd';
import {DomSanitizer, SafeResourceUrl} from '@angular/platform-browser';
......@@ -24,7 +24,7 @@ export class UploadVideoComponent implements OnChanges, OnDestroy {
@Input()
videoUrl = '';
@ViewChild('videoNode', {static: true })
@ViewChild('videoNode')
videoNode: ElementRef;
......@@ -47,8 +47,8 @@ export class UploadVideoComponent implements OnChanges, OnDestroy {
item: any;
// videoItem = null;
uploadUrl = (window as any).courseware.uploadUrl();
uploadData = (window as any).courseware.uploadData();
uploadUrl = (<any> window).courseware.uploadUrl();
uploadData = (<any> window).courseware.uploadData();
constructor(private nzMessageService: NzMessageService,
private sanitization: DomSanitizer
......@@ -71,7 +71,7 @@ export class UploadVideoComponent implements OnChanges, OnDestroy {
}
safeVideoUrl(url) {
console.log(url);
console.log(url)
return this.sanitization.bypassSecurityTrustResourceUrl(url); // `${url}`;
}
videoLoadedMetaData() {
......@@ -79,7 +79,7 @@ export class UploadVideoComponent implements OnChanges, OnDestroy {
}
handleChange(info: UploadChangeParam/* { type: string, file: UploadFile, event: any }*/): void {
handleChange(info: { type: string, file: UploadFile, event: any }): void {
console.log('info:' , info);
......@@ -109,7 +109,7 @@ export class UploadVideoComponent implements OnChanges, OnDestroy {
break;
case 'progress':
this.progress = info.event.percent;
this.progress = parseInt(info.event.percent, 10);
this.doProgress(this.progress);
break;
}
......@@ -152,9 +152,9 @@ export class UploadVideoComponent implements OnChanges, OnDestroy {
if (duration) {
duration = duration * 1000;
}
file.height = height;
file.width = width;
file.duration = duration;
file['height'] = height;
file['width'] = width;
file['duration'] = duration;
vid.preload = 'none';
vid.src = '';
vid.remove();
......
@import '../style/common_mixin.css';
.model-content {
width: 100%;
height: 100%;
}
This diff is collapsed.
@import "../style/common_mixin";
.model-content {
.card-config {
width: 100%;
height: 100%;
margin-left: 10px;
display: flex;
flex-wrap: wrap;
.card-item{
flex:1;
.border {
border-radius: 20px;
border-style: dashed;
padding:20px;
width: 800px;
}
.card-item-content{
.title {
font-size: 24px;
width: 100%;
text-align: center;
}
.section{
border-top: 1px solid ;
padding: 10px 0;
.section-title{
font-size: 24px;
width: 100%;
}
.section-content{
display: flex;
margin: 5px 0 10px 0;
}
}
.pic-sound-box {
width: 50%;
display: flex;
flex-direction: column;
}
.add-btn-box {
display: flex;
align-items: center;
justify-content: center;
height: 20vw;
padding: 10px;
padding-top: 5vw;
}
}
}
}
}
import {Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, ApplicationRef} from '@angular/core';
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.css']
styleUrls: ['./form.component.scss']
})
export class FormComponent implements OnInit, OnChanges, OnDestroy {
// 储存数据用
saveKey = "test_0011";
// 储存对象
item;
dataArray = [];
_item: any;
KEY = 'DataKey_MultipleChoice';
set item(item) {
this._item = item;
}
get item() {
return this._item;
}
@Output()
update = new EventEmitter();
constructor(private appRef: ApplicationRef) {
}
ngOnInit() {
this.item = {};
// 获取存储的数据
(<any> window).courseware.getData((data) => {
this.item.contentObj = {};
const getData = (<any> window).courseware.getData;
getData((data) => {
if (data) {
this.item = data;
} else {
this.item = {};
}
if ( !this.item.contentObj ) {
this.item.contentObj = {};
}
this.init();
this.refresh();
this.saveItem();
}, this.KEY);
}
ngOnChanges() {
}, this.saveKey);
}
ngOnDestroy() {
}
ngOnChanges() {
init() {
if (this.item.contentObj.dataArray) {
this.dataArray = this.item.contentObj.dataArray;
} else {
this.dataArray = this.getDefaultPicArr();
this.item.contentObj.dataArray = this.dataArray;
}
}
ngOnDestroy() {
cardItemData(){
return {
time: 3,
question:{
text:"",
image_url:"",
audio_url:""
},
choice:{
correct:{ isText: true, text: "", image_url: "" },
incorrect:[
{ isText: true, text: "", image_url: "" },
{ isText: true, text: "", image_url: "" },
{ isText: true, text: "", image_url: "" },
]
}
};
}
cardChoiceData(){
return { isText: true, text: "", image_url: "" }
}
getDefaultPicArr() {
let arr = [];
return arr;
}
init() {
initData() {
}
deleteItem(index) {
if (index !== -1) {
this.dataArray.splice(index, 1);
}
this.save();
}
/**
* 储存图片数据
* @param e
*/
onImageUploadSuccess(e, key) {
this.item[key] = e.url;
deleteChoice(questionIndex, choiceIndex){
if (questionIndex !== -1 && choiceIndex !== -1) {
this.dataArray[questionIndex].choice.incorrect.splice(choiceIndex, 1);
}
this.save();
}
addChoice(questionIndex) {
let item = this.cardChoiceData();
this.dataArray[questionIndex].choice.incorrect.push(item);
this.saveItem();
}
/**
* 储存音频数据
* @param e
*/
onAudioUploadSuccess(e, key) {
onImageUploadSuccessByItem(e, item) {
item.image_url = e.url
this.save();
}
this.item[key] = e.url;
onAudioUploadSuccessByItem(e, item) {
item.audio_url = e.url;
this.save();
}
onTitleAudioUploadSuccess(e) {
this.item.contentObj.titleAudio_url = e.url;
this.save();
}
addItem() {
let item = this.cardItemData();
this.dataArray.push(item);
this.saveItem();
}
radioClick(it, radioValue) {
it.radioValue = radioValue;
this.saveItem();
}
clickCheckBox() {
this.saveItem();
}
saveItem() {
this.save();
}
/**
* 储存数据
*/
save() {
(<any> window).courseware.setData(this.item, null, this.saveKey);
(<any> window).courseware.setData(this.item, null, this.KEY);
this.refresh();
console.log(this.item)
}
/**
* 刷新 渲染页面
*/
refresh() {
setTimeout(() => {
this.appRef.tick();
......
import {
MySprite,
getMinScale,
ShapeRect,
tweenChange,
randomSortByArr,
Label,
showPopParticle,
moveItem,
removeItemFromArr,
rotateItem,
ShapeRectNew
} from "./Unit";
import { CartoonAnimation } from './CartoonAnimation'
export class Cartoon {
// 系统缩放比例
mapScale = 1;
stageWidth;
stageHeight;
clientWidth;
clientHeight;
// 音乐 和 图片的缓冲区
audio = new Map();
images = new Map();
imagesOriginSize = new Map();
// 坐标原点 包含缩放
originX = 0;
originY = 0;
setOrigin = (x, y)=>{
this.originX = x;
this.originY = y;
}
getOrigin = ()=>{
return {
x: this.originX,
y: this.originY
}
}
// 相对坐标原点 包含缩放 用于添加孩子动画元素
relativeOriginX = 0;
relativeOriginY = 0;
setRelativeOrigin = (x, y)=>{
this.relativeOriginX = x;
this.relativeOriginY = y;
}
getRelativeOrigin = ()=>{
return {
x: this.relativeOriginX,
y: this.relativeOriginY
}
}
// 存放音乐和图片的地址
audioObj = {}
imageObj = {}
_currentPlayAudio;
// 添加音乐
addAudio = ( key, url ) => {
this.audioObj[key] = url
};
// 添加音乐
addImage = ( key, url ) => {
this.imageObj[key] = url
};
// 播放音乐
_playingNow = []
playAudio = function( key, now = false, callback = null) {
const audio = this.audio.get(key);
if (audio) {
if (now) {
audio.pause();
audio.currentTime = 0;
}
if (callback) {
audio.onended = () => {
let index = this._playingNow.indexOf(audio)
if(index != -1){
this._playingNow.splice(index,1)
}
callback();
};
}
audio.play();
audio.callback = callback
this._playingNow.push(audio)
this._currentPlayAudio = audio;
}
}
stopAllAudio(){
this._playingNow.forEach(audio=>{
audio.onended && audio.onended()
audio.pause();
audio.currentTime = 0;
})
this._playingNow = []
}
stopAudio(){
if(this._currentPlayAudio){
this._currentPlayAudio.pause();
this._currentPlayAudio.currentTime = 0;
}
}
// 异步加载图片 音频资源
loadResources = ()=> {
const pr = [];
for(let key in this.imageObj){
const p = this.preloadImage(this.imageObj[key]).then( (img:any) => {
this.images.set(key, img);
this.imagesOriginSize.set(key, {width:img.width, height:img.height});
}).catch(err => console.log(key));
pr.push(p);
};
for(let key in this.audioObj){
const a = this.preloadAudio(this.audioObj[key]).then( (audio:any) => {
this.audio.set(key, audio);
}).catch(err => console.log(key));
pr.push(a);
};
return Promise.all(pr);
}
// 预加载图片
preloadImage = (url) => {
return new Promise((resolve, reject) => {
const img = new Image();
img.src = url;
img.onload = () => resolve(img);
img.onerror = reject;
img.src = url;
});
}
// 预加载音频
preloadAudio = (url) => {
return new Promise((resolve, reject) => {
const audio = new Audio();
audio.oncanplay = a => {
resolve(audio);
};
audio.onerror = () => {
reject();
};
audio.src = url;
audio.load();
});
}
// 缓存页面元素
cartoonElementsBuffer = {}
createCartoonElement = (key, type, width?:number, heigth?:number, initX?:number, initY?:number)=>{
this.cartoonElementsBuffer[key] = {}
this.cartoonElementsBuffer[key].id = key;
this.cartoonElementsBuffer[key].width = width;
this.cartoonElementsBuffer[key].heigth = heigth;
this.cartoonElementsBuffer[key].width = width;
this.cartoonElementsBuffer[key].heigth = heigth;
this.cartoonElementsBuffer[key].x = initX;
this.cartoonElementsBuffer[key].y = initY;
switch(type){
case "MySprite": this.cartoonElementsBuffer[key].ref = new MySprite(); break;
case "ShapeRect": this.cartoonElementsBuffer[key].ref = new ShapeRect(); break;
case "ShapeRectNew": this.cartoonElementsBuffer[key].ref = new ShapeRectNew(); break;
case "Label": this.cartoonElementsBuffer[key].ref = new Label(); break;
default : this.cartoonElementsBuffer[key].ref = new MySprite(); break;
}
this.cartoonElementsBuffer[key].ref.x = initX;
this.cartoonElementsBuffer[key].ref.y = initY;
this.cartoonElementsBuffer[key].animation = new CartoonAnimation(this.cartoonElementsBuffer[key].ref)
return this.cartoonElementsBuffer[key]
}
createElement = (type, initX?:number, initY?:number)=>{
let element;
switch(type){
case "MySprite": element = new MySprite(); break;
case "ShapeRect": element = new ShapeRect(); break;
default : element = new MySprite(); break;
}
element.x = initX;
element.y = initY;
return element
}
createLabel = ({
text,
fontName,
fontColor,
fontSize,
textAlign
}, initX?, initY?)=>{
let element = new Label()
element.text = text;
element.fontName = fontName;
element.fontColor = fontColor;
element.fontSize = fontSize;
element.textAlign = textAlign;
element.x = initX;
element.y = initY;
return element
}
getCartoonElementRef = (key)=>{
if(this.cartoonElementsBuffer[key]){
return this.cartoonElementsBuffer[key].ref;
}else{
return undefined
}
}
getCartoonElement = (key)=>{
return this.cartoonElementsBuffer[key]
}
setCartoonElementPosition = (key, posi)=>{
this.cartoonElementsBuffer[key].ref.x = posi.x
this.cartoonElementsBuffer[key].ref.y = posi.y
this.cartoonElementsBuffer[key].x = posi.x
this.cartoonElementsBuffer[key].y = posi.y
}
setCartoonElementPositionX = (key, x)=>{
this.cartoonElementsBuffer[key].ref.x = x
this.cartoonElementsBuffer[key].x = x
}
setCartoonElementRelativePositionX = (key, x)=>{
this.cartoonElementsBuffer[key].relativeX = x
}
setCartoonElementPositionY = (key, y)=>{
this.cartoonElementsBuffer[key].ref.y = y
this.cartoonElementsBuffer[key].y = y
}
setCartoonElementRelativePositionY = (key, y)=>{
this.cartoonElementsBuffer[key].relativeY = y
}
getCartoonElementPosition = (key)=>{
return {
x: this.cartoonElementsBuffer[key].x,
y: this.cartoonElementsBuffer[key].y
}
}
getCartoonElementRelativePosition = (key)=>{
return {
x: this.cartoonElementsBuffer[key].relativeX,
y: this.cartoonElementsBuffer[key].relativeY
}
}
animation = new CartoonAnimation(this)
}
\ No newline at end of file
import {
MySprite,
getMinScale,
ShapeRect,
tweenChange,
randomSortByArr,
Label,
showPopParticle,
moveItem,
removeItemFromArr,
rotateItem
} from "./Unit";
export class CartoonAnimation {
animations = {}
currentRef;
constructor(ref){
this.currentRef = ref
}
add(key:string, func:Function){
this.animations[key] = func
}
move = (ele, distPosition, runTime, callback?:Function )=>{
tweenChange(ele, distPosition, runTime, ()=>{
callback && callback()
});
}
scaleChange = this.move;
run( key:string ){
this.animations[key]()
}
overCard = function (callback?: any){
let w = this.currentRef.scaleX;
this.scaleChange(this.currentRef, { scaleX: 0 }, 0.3, () => {
this.currentRef.frontSide.visible = !this.currentRef.frontSide.visible;
this.currentRef.backSide.visible = !this.currentRef.backSide.visible;
this.scaleChange(this.currentRef, { scaleX: w }, 0.3, () => {
callback && callback();
});
});
}
}
\ No newline at end of file
This diff is collapsed.
.game-container {
width: 100%;
height: 100%;
background: #ffffff;
background-size: cover;
}
#canvas {
}
@font-face
{
font-family: 'BRLNSDB';
src: url("../../assets/font/BRLNSDB.TTF") ;
}
.game-container {
width: 100%;
height: 100%;
//background-image: url("/assets/listen-read-circle/bg.jpg");
background: #ffffff;
background-repeat: no-repeat;
background-size: cover;
}
.read-and-point-copy {
width: 500px;
height: 85px;
object-fit: contain;
text-shadow: 0 6px 4px rgba(0, 0, 0, 0.5), 0 3px 0 #fffecc;
font-family: Questrian;
font-size: 72px;
font-weight: normal;
font-stretch: normal;
font-style: normal;
line-height: normal;
letter-spacing: normal;
color: #f8e424;
}
.read-and-point-copy .text-style-1 {
font-size: 48px;
}
.read-and-point-copy .text-style-2 {
font-size: 64px;
}
@font-face
{
font-family: 'BRLNSDB';
src: url("../../assets/font/BRLNSDB.TTF") ;
}
@font-face
{
font-family: 'RoundedBold';
src: url("../../assets/font/ArialRoundedBold.otf") ;
}
@font-face{
font-family: 'BRLNSB_1';
src: url("../../assets/font/BerlinSansFB/BRLNSB_1.TTF") ;
}
@font-face{
font-family: 'BerlinSansFBDemi-Bold';
src: url("../../assets/font/BerlinSansFB/BRLNSDB_1.TTF") ;
}
@font-face{
font-family: 'BRLNSR_1';
src: url("../../assets/font/BerlinSansFB/BRLNSR_1.TTF") ;
}
@font-face{
font-family: 'GOTHIC_1';
src: url("../../assets/font/CenturyGothic/GOTHIC_1.TTF") ;
}
@font-face{
font-family: 'GOTHICB_1';
src: url("../../assets/font/CenturyGothic/GOTHICB_1.TTF") ;
}
@font-face{
font-family: 'GOTHICBI_1';
src: url("../../assets/font/CenturyGothic/GOTHICBI_1.TTF") ;
}
@font-face{
font-family: 'GOTHICI_1';
src: url("../../assets/font/CenturyGothic/GOTHICI_1.TTF") ;
}
@font-face{
font-family: 'MMTextBook';
src: url("../../assets/font/MMTextBook/MMTextBook.otf") ;
}
@font-face{
font-family: 'MMTextBook-Bold';
src: url("../../assets/font/MMTextBook/MMTextBook-Bold.otf") ;
}
@font-face{
font-family: 'MMTextBook-BoldItalic';
src: url("../../assets/font/MMTextBook/MMTextBook-BoldItalic.otf") ;
}
@font-face{
font-family: 'MMTextBook-Italic';
src: url("../../assets/font/MMTextBook/MMTextBook-Italic.otf") ;
}
This diff is collapsed.
const res = [
const localImages = {
'startBtn': "assets/play/btn-start.png",
'restartBtn': "assets/play/btn-restart.png",
'petal_1': "assets/play/scrap-pic-1.png",
'petal_2': "assets/play/scrap-pic-2.png",
'petal_3': "assets/play/scrap-pic-3.png",
'bg_1280_720_Ruler': "assets/play/1280_720_Ruler.png",
'bubble': "assets/play/bubble.png",
'replay': 'assets/play/replay.png',
'title': 'assets/play/multiple-choice.png',
'group': 'assets/play/group.png',
'rectangle-3': 'assets/play/rectangle-3.png',
'drop-down': 'assets/play/drop-down.png',
'combined-shape': 'assets/play/combined-shape.png',
'choice-card-typeA': 'assets/play/choice-card-a.png',
'choice-card-typeB': 'assets/play/choice-card-b.png',
'choice-card-typeC': 'assets/play/choice-card-c.png',
'choice-card-typeD': 'assets/play/choice-card-d.png',
'complete-card': 'assets/play/complete-card.png',
'header': 'assets/play/header.png',
'background': 'assets/play/background.png',
'question-image': 'assets/play/question-image.png',
'speaker-1': 'assets/play/speaker-1.png',
'correct-icon': 'assets/play/correct-icon.png',
'incorrect-icon': 'assets/play/incorrect-icon.png',
'red-circle': 'assets/play/combined-shape-red-circle.png',
'rectangle-4': 'assets/play/rectangle-4.png',
'me': 'assets/play/me.png',
'bg-240-180': 'assets/play/bg-240-180.png',
'bg-453-251': 'assets/play/bg-453-251.png',
't_right': "assets/play/right.png",
't_arrow': "assets/play/arrow.png",
'bg_500_600': "assets/play/bg_500_600.png",
'bg_1280_222': "assets/play/bg_1280_222.png",
'bg_ready': "assets/play/bg_ready.png",
'ready': "assets/play/ready.png",
'go': "assets/play/go.png"
};
// ['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"],
];
const localAudios = {
'sm-back': "assets/audio/sm-back.mp3",
'sm-display': "assets/audio/sm-display.mp3",
'sm-wrong': "assets/audio/sm-wrong.mp3",
'sm-win': "assets/audio/sm-win.mp3",
'sm-in': "assets/audio/sm-in.mp3",
'sm-out': "assets/audio/sm-out.mp3",
'sm-click': "assets/audio/sm-click.mp3",
'sm-start': "assets/audio/sm-start.mp3",
'sm-correct': 'assets/audio/sm-correct.mp3',
'sm-choice-complete': 'assets/audio/sm-choice-complete.mp3',
'sm-choice-correct': 'assets/audio/sm-choice-correct.mp3',
'sm-choice-incorrect': 'assets/audio/sm-choice-error.mp3',
'sm-choice-in': 'assets/audio/sm-choice-in.mp3',
'sm-choice-show-answer': 'assets/audio/sm-choice-show-answer.mp3',
'sm-choice-timeup-0': 'assets/audio/sm-choice-timeup-0.mp3',
'sm-choice-timeup-3': 'assets/audio/sm-choice-timeup-3.mp3',
'sm-go': 'assets/audio/sm-go.mp3',
'sm-ready': 'assets/audio/sm-ready.mp3'
};
const resAudio = [
['click', "assets/play/music/click.mp3"],
];
export {res, resAudio};
export {localImages, localAudios};
This diff is collapsed.
@mixin hide-overflow-text {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
@mixin k-no-select {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
@mixin k-img-bg {
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}
.anticon{
vertical-align: .1em!important;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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