Commit 6512cb21 authored by liujiaxin's avatar liujiaxin

upgrade angular to 9.0.2

remove scss
add fontawesome solid and regular
remove useless package
parent a7e92ed4
......@@ -3,13 +3,9 @@
"version": 1,
"newProjectRoot": "projects",
"projects": {
"ng-one": {
"origin-angular": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
},
"schematics": {},
"root": "",
"sourceRoot": "src",
"prefix": "app",
......@@ -17,39 +13,26 @@
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist",
"outputPath": "dist/origin-angular",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": false,
"aot": true,
"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",
"./node_modules/font-awesome/css/font-awesome.css",
"./node_modules/bootstrap/dist/css/bootstrap.min.css",
"./node_modules/animate.css/animate.min.css"
"src/styles.css"
],
"scripts": [
"src/assets/libs/audio-recorder/lame.min.js",
"src/assets/libs/audio-recorder/worker.js",
"src/assets/libs/audio-recorder/recorder.js"
]
"scripts": []
},
"configurations": {
"production": {
......@@ -64,28 +47,39 @@
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "ng-one:build"
"browserTarget": "origin-angular:build"
},
"configurations": {
"production": {
"browserTarget": "ng-one:build:production"
"browserTarget": "origin-angular:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "ng-one:build"
"browserTarget": "origin-angular:build"
}
},
"test": {
......@@ -100,7 +94,8 @@
"src/assets"
],
"styles": [
"src/styles.scss"
"./node_modules/ng-zorro-antd/ng-zorro-antd.min.css",
"src/styles.css"
],
"scripts": []
}
......@@ -122,15 +117,16 @@
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "ng-one:serve"
"devServerTarget": "origin-angular:serve"
},
"configurations": {
"production": {
"devServerTarget": "ng-one:serve:production"
"devServerTarget": "origin-angular:serve:production"
}
}
}
}
}},
"defaultProject": "ng-one"
}
\ No newline at end of file
}
},
"defaultProject": "origin-angular"
}
{
"name": "ng-template-generator",
"version": "0.0.1",
"scripts": {
"start": "ng serve",
"scripts": {
"start": "ng serve",
"build": "ng build --build--optimizer --aot --base-href /JGT/v3/",
"publish": "node ./bin/publish.js"
"publish": "node ./bin/publish.js",
"ng": "ng",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@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",
"@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",
"ng-zorro-antd": "^8.5.2",
"rxjs": "~6.5.4",
"spark-md5": "^3.0.0",
"webpack": "^4.28.2",
"zone.js": "^0.8.26"
"tslib": "^1.10.0",
"zone.js": "~0.10.2"
},
"devDependencies": {
"@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",
"@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",
"@types/jasminewd2": "~2.0.3",
"@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"
"@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"
}
}
......@@ -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() {
let tp = this.getQueryString("type");
if (tp){
const 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 { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { NgZorroAntdModule, NZ_I18N, zh_CN } from 'ng-zorro-antd';
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 { 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 { registerLocaleData } from '@angular/common';
import zh from '@angular/common/locales/zh';
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";
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';
registerLocaleData(zh);
@NgModule({
......@@ -42,20 +40,21 @@ registerLocaleData(zh);
CustomHotZoneComponent,
PlayerContentWrapperComponent
],
imports: [
BrowserModule,
NgZorroAntdModule,
FormsModule,
HttpClientModule,
BrowserAnimationsModule,
BrowserModule,
Angular2FontawesomeModule,
NgZorroAntdModule,
],
/** 配置 ng-zorro-antd 国际化(文案 及 日期) **/
providers : [
{ provide: NZ_I18N, useValue: zh_CN }
FontAwesomeModule
],
providers: [{ provide: NZ_I18N, useValue: zh_CN }],
bootstrap: [AppComponent]
})
export class AppModule { }
export class AppModule {
constructor(library: FaIconLibrary) {
library.addIconPacks(fas, far);
}
}
<div class="d-flex">
<div class="p-btn-record d-flex">
<div class="btn-clear" (click)="onBtnClearAudio()" *ngIf="withRmBtn && (audioUrl || audioBlob)">
<fa name="close"></fa>
<fa-icon icon="close"></fa-icon>
</div>
<div class="btn-record" *ngIf="type===Type.RECORD && !isUploading"
[class.p-recording]="isRecording"
(click)="onBtnRecord()">
<fa name="microphone"></fa>
<fa-icon icon="microphone"></fa-icon>
Record Audio
</div>
<nz-upload
[nzAccept] = "'.mp3'"
[nzShowUploadList]="false"
[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 name="upload"></fa>
<fa-icon icon="upload"></fa-icon>
Upload Audio
</div>
</nz-upload>
<div class="p-upload-progress-bg" *ngIf="isUploading">
<div class="i-bg" [style.width]="progress+'%'"></div>
<div class="i-text">
<fa name="cloud-upload"></fa>
<fa-icon icon="cloud-upload-alt"></fa-icon>
Uploading...
</div>
</div>
......@@ -35,14 +35,14 @@
<ng-template #truthyTemplate >
<div class="btn-delete" (click)="onBtnDeleteAudio()">
<fa name="close"></fa>
<fa-icon icon="close"></fa-icon>
</div>
</ng-template>
<ng-template #falsyTemplate>
<div class="btn-switch" (click)="onBtnSwitchType()">
<fa name="cog"></fa>
<fa-icon icon="cog"></fa-icon>
</div>
</ng-template>
......@@ -55,7 +55,7 @@
<nz-progress [nzPercent]="percent" [nzWidth]="30" [nzFormat]="progressText"
nzType="circle"></nz-progress>
<div class="p-btn-play" [style.left]="isPlaying?'8px':''">
<fa [name]="playIcon"></fa>
<fa-icon [icon]="playIcon"></fa-icon>
</div>
</div>
</div>
.d-flex{
display: flex;
}
.p-btn-record {
font-size: 0.9rem;
color: #555;
......
import {Component, EventEmitter, Input, OnDestroy, OnInit, Output, NgZone, OnChanges} from '@angular/core';
import {Component, EventEmitter, Input, OnDestroy, OnInit, Output, NgZone, OnChanges} from '@angular/core';
import {NzMessageService, NzNotificationService, UploadFile} from 'ng-zorro-antd';
import {HttpClient, HttpEvent, HttpEventType, HttpRequest} from '@angular/common/http';
import {environment} from '../../../environments/environment';
import {environment} from '../../../environments/environment';
declare var Recorder;
......@@ -9,7 +9,7 @@ declare var Recorder;
selector: 'app-audio-recorder',
templateUrl: './audio-recorder.component.html',
styleUrls: ['./audio-recorder.component.scss']
})
})
export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
_audioUrl: string;
audio = new Audio();
......@@ -21,8 +21,8 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
Type = Type;
withRmBtn = false;
uploadUrl = (<any>window).courseware.uploadUrl();
uploadData = (<any>window).courseware.uploadData();
uploadUrl = (window as any).courseware.uploadUrl();
uploadData = (window as any).courseware.uploadData();
@Input()
needRemove = false;
......@@ -32,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();
......@@ -52,8 +52,8 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
recorder: any;
audioBlob: any;
constructor( private nzMessageService: NzMessageService ) {
constructor( private nzMessageService: NzMessageService ) {
}
......@@ -137,11 +137,11 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
}
// 开始录音
onBtnRecord = () => {
onBtnRecord = () => {
}
// 切换模式
onBtnSwitchType() {
onBtnSwitchType() {
}
onBtnClearAudio() {
this.audioRemoved.emit();
......@@ -152,7 +152,7 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
this.audioRemoved.emit();
}
handleChange(info: { type: string, file: UploadFile, event: any }): void {
handleChange(info: { type: string, file: UploadFile, event: any }): void {
switch (info.type) {
case 'start':
this.isUploading = true;
......@@ -185,19 +185,19 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
}
return true;
}
beforeUpload = (file: File) => {
beforeUpload = (file: File) => {
this.audioUrl = null;
if (!this.checkSelectFile(file)) {
return false;
}
this.isUploading = true;
this.progress = 0;
this.progress = 0;
}
uploadSuccess = (url) => {
this.nzMessageService.info('Upload Success');
this.isUploading = false;
this.audioUrl = url;
uploadSuccess = (url) => {
this.nzMessageService.info('Upload Success');
this.isUploading = false;
this.audioUrl = url;
}
uploadFailure = (err, file) => {
this.isUploading = false;
......
......@@ -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 type="save"></i>
<i nz-icon nzType="save"></i>
Save
</button>
......
......@@ -42,8 +42,8 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
@Output()
save = new EventEmitter();
@ViewChild('canvas') canvas: ElementRef;
@ViewChild('wrap') wrap: ElementRef;
@ViewChild('canvas', {static: true }) canvas: ElementRef;
@ViewChild('wrap', {static: true }) wrap: ElementRef;
// @HostListener('window:resize', ['$event'])
canvasWidth = 1280;
......@@ -613,7 +613,9 @@ 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">
<div class="row" style="margin: 5px;">
<div class="row" style="margin: 5px;">
<div class="p-content" style="width:100%">
<div class="p-tool-box d-flex" style="background: #fff;">
<div class="p-tool-box d-flex" style="background: #fff;">
<nz-select class="ml-1" style="width: 120px;" [(ngModel)]="__fontFamily"
(ngModelChange)="onChangeFontFamily($event)"
nzPlaceHolder="Font Family"
[nzDropdownMatchSelectWidth]="false"
>
<nz-option [nzValue]="font" [nzLabel]="font" *ngFor="let font of fontFamilyList"></nz-option>
</nz-select>
[nzDropdownMatchSelectWidth]="false">
<nz-option [nzValue]="font" nzCustomContent [nzLabel]="font" *ngFor="let font of fontFamilyList">
<span [ngStyle]="{'font-family': font}" >{{font}}</span>
</nz-option>
</nz-select>
<nz-select class="ml-1" style="width: 110px;" [(ngModel)]="__fontSize"
(ngModelChange)="onChangeFontSize()"
nzPlaceHolder="Font Size">
<nz-option [nzValue]="i" [nzLabel]="'Size - ' + i" *ngFor="let i of fontSizeRange"></nz-option>
</nz-select>
<div class="p-divider"></div>
</nz-select>
<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>
<!-- <div class="fa fa-bold"></div>-->
<fa-icon icon="bold"></fa-icon>
</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>
<!-- <div class="fa fa-italic"></div>-->
<fa-icon icon="italic"></fa-icon>
</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>
<!-- <div class="fa fa-underline"></div>-->
<fa-icon icon="underline"></fa-icon>
</div>
</div>
<div class="i-tool-font-btn d-flex">
<div class="position-relative fa-icon" (click)="onChangeStrikethrough()">
<div class="fa fa-strikethrough"></div>
<!-- <div class="fa fa-strikethrough"></div>-->
<fa-icon icon="strikethrough"></fa-icon>
</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>
<!-- <div class="fa fa-font"></div>-->
<fa-icon icon="palette"></fa-icon>
<div class="i-color" [style.background-color]="__fontColor"></div>
</div>
<div class="i-dropdown-menu" nzPlacement="bottom"
nz-popover [(nzVisible)]="isShowFontColorPane" nzTrigger="click"
[nzContent]="colorPane">
[nzContent]="colorPane">
<i nz-icon type="down" theme="outline"></i>
</div>
</div>
<div class="p-divider"></div>
<div style="background: #fff;display: block;">
<div class="position-relative" (click)="onChangeStrikethrough()">
<div class="position-relative">
<app-audio-recorder [audioUrl]="titleObj && titleObj.audio_url" (audioUploaded)="titleAudioUploaded($event)"></app-audio-recorder>
</div>
</div>
</div>
</div>
<div class="width-100 d-flex">
<iframe #titleEl frameborder="0" style="overflow: hidden;width: 100%; height:48px; margin: 0; padding: 0;"></iframe>
<div class="width-100 d-flex">
<iframe #titleEl id="titleContentEgret" frameborder="0" style="overflow: hidden;width: 100%; height:48px; margin: 0; padding: 0;"></iframe>
</div>
</div>
......@@ -76,37 +83,11 @@
<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>
</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';
@import '../../style/common_mixin.css';
.title-config {
.letter-wrap{
......@@ -11,39 +11,73 @@
.type-row{
margin: 0;padding-top: 1rem;
}
.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: '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") ;
}
@mixin tool-btn {
border: 1px solid #ddd;
display: flex;
......@@ -54,16 +88,37 @@
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;
}
.p-title-box {
.p-title {
.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 {
font-size: 20px;
}
input {
.p-title-box input {
width: 300px;
margin-left: 10px;
}
}
.p-content {
border: 1px solid #ddd;
......@@ -85,115 +140,110 @@
align-items: center;
border-bottom: 1px solid #ddd;
// save
.i-tool-save {
@include tool-btn();
color: white;
}
.i-tool-save:disabled {
color: #555;
}
// font-size
.i-tool-font-size {
@include tool-btn();
width: 37px;
& > span {
position: absolute;
top: -5px;
right: 5px;
}
}
.i-tool-font-size:hover {
color: black;
border-color: #bbb;
}
}
// save
.i-tool-save {
//@include tool-btn();
color: white;
}
.i-tool-save:disabled {
color: #555;
}
// font-color
.i-tool-font-color, .i-tool-font-btn {
border: 1px solid #ddd;
//padding: 3px 7px;
border-radius: 6px;
width: 45px;
height: 31px;
background-color: white;
color: #555;
::ng-deep > span {
display: flex;
// font-size
.i-tool-font-size {
//@include tool-btn();
width: 37px;
}
.i-tool-font-size:hover {
color: black;
border-color: #bbb;
}
// font-color
.i-tool-font-color, .i-tool-font-btn {
border: 1px solid #ddd;
//padding: 3px 7px;
border-radius: 6px;
width: 45px;
height: 31px;
background-color: white;
color: #555;
::ng-deep > span {
display: flex;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
padding: 3px 7px;
}
.i-left {
.fa-font,.fa-bold,.fa-italic,.fa-strikethrough, .fa-underline {
font-size: 10px;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
padding: 3px 7px;
}
.i-left {
.fa-font,.fa-bold,.fa-italic,.fa-strikethrough, .fa-underline {
font-size: 10px;
position: absolute;
color: #555;
left: 8px;
top: 7px;
}
.i-color {
width: 68%;
height: 5px;
background-color: black;
position: absolute;
top: 21px;
left: 5px;
}
color: #555;
left: 8px;
top: 7px;
}
.i-dropdown-menu {
width: 15px;
font-size: 10px;
border-left: 1px solid #ddd;
display: flex;
align-items: center;
.anticon-down {
transform: scale(0.6);
}
.i-color {
width: 68%;
height: 5px;
background-color: black;
position: absolute;
top: 21px;
left: 5px;
}
}
.i-tool-font-btn{
width: 31px;
}
.fa-icon{
width: 100%;
height: 100%;
.i-dropdown-menu {
width: 15px;
font-size: 10px;
border-left: 1px solid #ddd;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
// bg-color
.i-tool-bg-color {
@include tool-btn();
padding: 0 9px;
::ng-deep > span {
display: flex;
align-items: center;
}
.i-color {
display: block;
width: 16px;
height: 16px;
background-color: white;
margin-left: 10px;
.anticon-down {
transform: scale(0.6);
}
}
}
.i-tool-font-btn{
width: 31px;
}
.fa-icon{
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
// bg-color
.i-tool-bg-color {
@include tool-btn();
padding: 0 9px;
::ng-deep > span {
display: flex;
align-items: center;
}
// horizontal-center
.i-tool-horizontal-center {
@include tool-btn();
width: 37px;
.i-color {
display: block;
width: 16px;
height: 16px;
background-color: white;
margin-left: 10px;
}
}
// horizontal-center
.i-tool-horizontal-center {
@include tool-btn();
width: 37px;
}
.p-box {
width: 1280px;
height: 720px;
......@@ -203,9 +253,7 @@
overflow: hidden;
}
.p-sentence {
@include k-no-select();
}
.p-animation-index-box {
.i-animation-index {
......@@ -278,7 +326,6 @@
::ng-deep .ant-radio-button-wrapper {
padding: 0 10px;
@include k-no-select();
}
.i-toolbox {
......@@ -309,7 +356,6 @@
cursor: pointer;
text-align: left;
display: flex;
@include k-no-select();
}
.i-active {
background-color: antiquewhite;
......
import {
Component,
ElementRef,
......@@ -10,6 +11,82 @@ 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',
......@@ -19,22 +96,45 @@ export class LessonTitleConfigComponent implements OnInit, OnChanges, OnDestroy,
fontFamilyList = [
'Arial',
'ARBLI'
'BRLNSB',
'BRLNSDB',
'BRLNSR',
'GOTHIC',
'GOTHICB',
// "GOTHICBI",
// "GOTHICI",
'MMTextBook',
// "MMTextBook-Bold",
// "MMTextBook-Italic",
// "MMTextBook-BoldItalic",
];
colorList = [
'#111111',
'#000000',
'#ffffff',
'#595959',
'#0075c2',
'#c61c1e',
'#9cbc3a'
'#9cbc3a',
'#008000',
'#FF0000',
'#D2691E',
];
MIN_FONT_SIZE = 1;
MAX_FONT_SIZE = 7;
isShowFontColorPane = false;
isShowBGColorPane = false;
fontSizeRange: number[];
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},
];
editorContent = '';
......@@ -45,25 +145,17 @@ export class LessonTitleConfigComponent implements OnInit, OnChanges, OnDestroy,
loopCnt = 0;
maxLoops = 20;
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;
@ViewChild('titleEl', {static: true}) titleEl: ElementRef;
titleEW = null;
@Input()
titleObj = {
type: 'a',
content: '',
icons: [],
audio_url: ''
};
@Input()
withIcon = true;
@Output()
titleUpdated = new EventEmitter();
......@@ -84,16 +176,12 @@ 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;
......@@ -102,33 +190,23 @@ 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 = `<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.editorContent = editorTpl.replace('{{content}}', this.titleObj.content) ;
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;
}
......@@ -159,30 +237,7 @@ 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 {
......@@ -195,9 +250,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;
}
......@@ -214,10 +269,13 @@ export class LessonTitleConfigComponent implements OnInit, OnChanges, OnDestroy,
alert(e);
}
}
execEditorCommand(command, option?: any) {
console.log('sssss');
try {
this.titleEW.focus();
this.titleEW.document.execCommand(command, false, option);
const result = this.titleEW.document.execCommand(command, false, option);
console.log(result);
this.loopCnt = 0;
return false;
......@@ -229,7 +287,7 @@ export class LessonTitleConfigComponent implements OnInit, OnChanges, OnDestroy,
}, 100);
this.loopCnt += 1;
} else {
alert("Error executing command.");
alert('Error executing command.');
}
}
}
......@@ -242,7 +300,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) {
......@@ -272,9 +330,10 @@ export class LessonTitleConfigComponent implements OnInit, OnChanges, OnDestroy,
this.titleUpdated.emit(this.titleObj);
}
shouldSave = () => {
console.log('title shouldSave');
console.log('title shouldSave', this.titleObj);
this.titleObj.content = this.titleEW.document.body.innerHTML.trim();
this.titleUpdated.emit(this.titleObj);
}
}
@import '../../style/common_mixin';
@import '../../style/common_mixin.css';
.cmp-player-content-wrapper{
max-height: 100%;
......
import {
AfterViewInit,
Component,
ElementRef,
ElementRef,
Input,
OnChanges,
OnDestroy,
OnInit,
OnInit,
ViewChild
} from '@angular/core';
} from '@angular/core';
@Component({
......@@ -18,21 +18,21 @@ import {
export class PlayerContentWrapperComponent implements OnInit, OnChanges, OnDestroy, AfterViewInit {
@ViewChild('wrapperEl') wrapperEl: ElementRef;
@ViewChild('wrapperEl', {static: true }) wrapperEl: ElementRef;
// // aspect ratio?
@Input() ratio;
_w: string;
_h: string;
constructor() {
constructor() {
if (window.innerHeight < window.innerWidth) {
this._h = '100%';
this._w = 'auto';
} else {
this._w = '100%';
this._h = 'auto';
}
}
}
ngOnInit() {
if (!this.ratio) {
......
......@@ -8,7 +8,7 @@
<!--[nzBeforeUpload]="customUpload">-->
<div class="p-box d-flex align-items-center">
<div class="p-upload-icon" *ngIf="!picUrl && !uploading">
<i nz-icon type="cloud-upload" theme="outline" [style.font-size]="iconSize + 'em'"></i>
<i nz-icon nzType="cloud-upload" nzTheme="outline" [style.font-size]="iconSize + 'em'"></i>
<div class="m-3"></div>
<span>{{TIP}}</span>
<!--<div class="mt-5 p-progress-bar" *ngIf="uploading">-->
......@@ -19,7 +19,7 @@
<div class="p-upload-progress-bg" *ngIf="uploading">
<div class="i-bg" [style.width]="progress+'%'"></div>
<div class="i-text">
<fa name="cloud-upload"></fa>
<fa-icon icon="cloud-upload-alt"></fa-icon>
Uploading...
</div>
</div>
......@@ -32,6 +32,6 @@
nz-popconfirm nzTitle="Are you sure ?"
(nzOnConfirm)="onDelete()"
>
<i nz-icon type="close" theme="outline"></i>
<i nz-icon nzType="close" nzTheme="outline"></i>
</div>
</div>
@import '../../style/common_mixin';
@import '../../style/common_mixin.css';
.p-image-uploader {
position: relative;
......@@ -53,9 +53,11 @@
width: 100%;
height: 100%;
//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,8 +16,7 @@
<button type="button" nz-button nzType="default" *ngIf="showUploadBtn" [disabled]="uploading"
[nzLoading]="uploading" >
<i nz-icon type="plus" theme="outline"></i>
<i nz-icon nzType="plus" nzTheme="outline"></i>
<span>{{ uploading ? 'Uploading' : 'Select Video' }}</span>
<!--<span>Select Video</span>-->
</button>
......@@ -56,9 +55,9 @@
</div>
<div class="p-box d-flex align-items-center p-video-uploader" style="top: 20px;">
<div class="p-box d-flex align-items-center p-video-uploader">
<div class="p-upload-icon" *ngIf="!showUploadBtn && !videoUrl && !uploading">
<i nz-icon type="upload" theme="outline"></i>
<i nz-icon nzType="upload" nzTheme="outline"></i>
<div class="m-3"></div>
<span>Click here to upload video</span>
<div class="mt-5 p-progress-bar" *ngIf="uploading">
......@@ -70,26 +69,26 @@
[ngClass]="{'smart-bar': showUploadBtn}" >
<div class="i-bg" [style.width]="progress+'%'"></div>
<div class="i-text">
<fa name="cloud-upload"></fa>
<fa-icon icon="cloud-upload-alt"></fa-icon>
Uploading...
</div>
</div>
<div class="p-upload-check-bg" *ngIf="checking">
<div class="i-bg" [style.width]="progress+'%'"></div>
<div class="i-text">
<fa name="cloud-upload"></fa>
<i nz-icon type="loading" theme="outline"></i>Checking...
<fa-icon icon="cloud-upload-alt"></fa-icon>
<i nz-icon nzType="loading" nzTheme="outline"></i>Checking...
</div>
</div>
<div class="p-preview" *ngIf="!showUploadBtn && !uploading && videoUrl " >
<div class="p-preview" *ngIf="!uploading && videoUrl " >
<!--<video crossorigin="anonymous" [src]="videoUrl" controls #videoNode></video>-->
<video [src]="safeVideoUrl(videoUrl)" controls #videoNode (loadedmetadata)="videoLoadedMetaData()"></video>
<video [src]="safeVideoUrl(videoUrl)" controls #videoNode></video>
</div>
</div>
<div [style.display]="!checkVideoExists?'none':''">
<span><i nz-icon type="loading" theme="outline"></i> checking file to upload</span>
<span><i nz-icon nzType="loading" nzTheme="outline"></i> checking file to upload</span>
</div>
</div>
@import '../../style/common_mixin';
@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%);
}
}*/
.p-video-uploader {
position: relative;
display: block;
......@@ -17,50 +33,56 @@
background-color: #fafafa;
text-align: center;
color: #aaa;
.p-upload-icon {
text-align: center;
margin: auto;
.anticon-upload {
color: #888;
font-size: 5rem;
}
.p-progress-bar {
position: relative;
width: 20rem;
height: 1.5rem;
border: 1px solid #ccc;
border-radius: 1rem;
.p-progress-bg {
background-color: #1890ff;
border-radius: 1rem;
height: 100%;
}
.p-progress-value {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
text-shadow: 0 0 4px #000;
color: white;
text-align: center;
font-size: 0.9rem;
line-height: 1.5rem;
}
}
}
.p-preview {
width: 100%;
height: 100%;
//background-image: url("https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png");
video{
max-height: 100%;
max-width: 100%;
}
}
}
}
.p-upload-icon {
text-align: center;
margin: auto;
}
.p-upload-icon .anticon-upload {
color: #888;
font-size: 5rem;
}
p-progress-bar {
position: relative;
width: 20rem;
height: 1.5rem;
border: 1px solid #ccc;
border-radius: 1rem;
}
.p-progress-bar .p-progress-bg {
background-color: #1890ff;
border-radius: 1rem;
height: 100%;
}
.p-progress-bar .p-progress-value {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
text-shadow: 0 0 4px #000;
color: white;
text-align: center;
font-size: 0.9rem;
line-height: 1.5rem;
}
.p-preview {
width: 100%;
height: 100%;
//background-image: url("https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png");
}
.p-preview 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, UploadFile} from 'ng-zorro-antd';
import {NzMessageService, UploadChangeParam, UploadFile, UploadFileStatus} 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')
@ViewChild('videoNode', {static: true })
videoNode: ElementRef;
......@@ -47,8 +47,8 @@ export class UploadVideoComponent implements OnChanges, OnDestroy {
item: any;
// videoItem = null;
uploadUrl = (<any> window).courseware.uploadUrl();
uploadData = (<any> window).courseware.uploadData();
uploadUrl = (window as any).courseware.uploadUrl();
uploadData = (window as any).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: { type: string, file: UploadFile, event: any }): void {
handleChange(info: UploadChangeParam/* { 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 = parseInt(info.event.percent, 10);
this.progress = info.event.percent;
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';
@import '../style/common_mixin.css';
.model-content {
......
......@@ -2,7 +2,7 @@
<div class="model-content">
<div style="position: absolute; left: 200px; top: 100px; width: 300px;">
<div style="position: absolute; left: 200px; top: 100px; width: 800px;">
<input type="text" nz-input [(ngModel)]="item.text" (blur)="save()">
......@@ -15,12 +15,14 @@
[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>
<div style="position: absolute; left: 1000px; top: 100px; width: 300px;">
<!-- div style="position: absolute; left: 1000px; top: 100px; width: 300px;">
<input type="text" nz-input [(ngModel)]="item.text_2" (blur)="save()">
......@@ -34,7 +36,7 @@
(audioUploaded)="onAudioUploadSuccess($event, 'audio_url_2')"
></app-audio-recorder>
</div>
</div -->
......
......@@ -5,7 +5,7 @@ import {Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, Ap
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.scss']
styleUrls: ['./form.component.css']
})
export class FormComponent implements OnInit, OnChanges, OnDestroy {
......
......@@ -15,7 +15,7 @@ class Sprite {
constructor(ctx = null) {
if (!ctx) {
this.ctx = window['curCtx'];
this.ctx = (window as any).curCtx;
} else {
this.ctx = ctx;
}
......@@ -158,6 +158,7 @@ export class MySprite extends Sprite {
if (this._shadowFlag) {
this.ctx.shadowOffsetX = this._shadowOffsetX;
this.ctx.shadowOffsetY = this._shadowOffsetY;
this.ctx.shadowBlur = this._shadowBlur;
......@@ -175,6 +176,8 @@ export class MySprite extends Sprite {
}
}
updateChildren() {
......@@ -359,7 +362,7 @@ export class ColorSpr extends MySprite {
g = 0;
b = 0;
createGSCanvas() {
createGSCanvas(){
if (!this.img) {
return;
......@@ -502,15 +505,15 @@ export class Label extends MySprite {
fontSize = 40;
fontColor = '#000000';
fontWeight = 900;
maxWidth;
_maxWidth;
outline = 0;
outlineColor = '#ffffff';
_shadowFlag = false;
_shadowColor;
_shadowOffsetX;
_shadowOffsetY;
_shadowBlur;
// _shadowFlag = false;
// _shadowColor;
// _shadowOffsetX;
// _shadowOffsetY;
// _shadowBlur;
_outlineFlag = false;
_outLineWidth;
......@@ -541,7 +544,7 @@ export class Label extends MySprite {
setMaxSize(w) {
this.maxWidth = w;
this._maxWidth = w;
this.refreshSize();
if (this.width >= w) {
this.scaleX *= w / this.width;
......@@ -568,16 +571,16 @@ export class Label extends MySprite {
.start(); // Start the tween immediately.
}
setShadow(offX = 2, offY = 2, blur = 2, color = 'rgba(0, 0, 0, 0.2)') {
this._shadowFlag = true;
this._shadowColor = color;
// 将阴影向右移动15px,向上移动10px
this._shadowOffsetX = 5;
this._shadowOffsetY = 5;
// 轻微模糊阴影
this._shadowBlur = 5;
}
// setShadow(offX = 0, offY = 2, blur = 2, color = 'rgba(0, 0, 0, 0.2)') {
//
// this._shadowFlag = true;
// this._shadowColor = color;
// // 将阴影向右移动15px,向上移动10px
// this._shadowOffsetX = 5;
// this._shadowOffsetY = 5;
// // 轻微模糊阴影
// this._shadowBlur = 5;
// }
setOutline(width = 5, color = '#ffffff') {
......@@ -836,6 +839,40 @@ export class RichText extends Label {
export class LineRect extends MySprite {
lineColor = "#ffffff";
lineWidth = 10;
setSize(w, h) {
this.width = w;
this.height = h;
}
drawLine() {
this.ctx.beginPath();
this.ctx.moveTo(this._offX, this._offY);
this.ctx.lineTo(this._offX + this.width, this._offY);
this.ctx.lineTo(this._offX + this.width, this._offY + this.height);
this.ctx.lineTo(this._offX, this._offY + this.height);
this.ctx.closePath();
this.ctx.lineWidth = this.lineWidth;
// this.ctx.fillStyle = "rgb(2,33,42)"; //指定填充颜色
// this.ctx.fill(); //对多边形进行填充
this.ctx.strokeStyle = this.lineColor; // "#ffffff";
this.ctx.stroke();
}
drawSelf() {
super.drawSelf();
this.drawLine();
}
}
export class ShapeRect extends MySprite {
......@@ -1076,7 +1113,7 @@ export function tweenChange(item, obj, time = 0.8, callBack = null, easing = nul
}
if (update) {
tween.onUpdate( (a, b) => {
update(a, b);
update(a, b);
});
}
......@@ -1129,7 +1166,7 @@ export function moveItem(item, x, y, time = 0.8, callBack = null, easing = null)
if (callBack) {
tween.onComplete(() => {
callBack();
callBack();
});
}
if (easing) {
......@@ -1327,16 +1364,6 @@ export function removeItemFromArr(arr, item) {
export function getPosDistance(sx, sy, ex, ey) {
const _x = ex - sx;
const _y = ey - sy;
const len = Math.sqrt( Math.pow(_x, 2) + Math.pow(_y, 2) );
return len;
}
......@@ -1380,6 +1407,13 @@ export function circleMove(item, x0, y0, time = 2, addR = 360, xPer = 1, yPer =
}
export function getPosDistance(sx, sy, ex, ey) {
const _x = ex - sx;
const _y = ey - sy;
const len = Math.sqrt( Math.pow(_x, 2) + Math.pow(_y, 2) );
return len;
}
export function delayCall(callback, second) {
const tween = new TWEEN.Tween(this)
......@@ -1461,9 +1495,9 @@ export function jelly(item, time = 0.7) {
export function showPopParticle(img, pos, parent) {
export function showPopParticle(img, pos, parent, num = 20, minLen = 40, maxLen = 80, showTime = 0.4) {
const num = 20;
for (let i = 0; i < num; i ++) {
const particle = new MySprite();
......@@ -1475,8 +1509,8 @@ export function showPopParticle(img, pos, parent) {
const randomR = 360 * Math.random();
particle.rotation = randomR;
const randomS = 0.5 + Math.random() * 0.5;
particle.setScaleXY(randomS);
const randomS = 0.3 + Math.random() * 0.7;
particle.setScaleXY(randomS * 0.3);
const randomX = Math.random() * 20 - 10;
particle.x += randomX;
......@@ -1484,16 +1518,32 @@ export function showPopParticle(img, pos, parent) {
const randomY = Math.random() * 20 - 10;
particle.y += randomY;
const randomL = 40 + Math.random() * 40;
const randomL = minLen + Math.random() * (maxLen - minLen);
const randomA = 360 * Math.random();
const randomT = getPosByAngle(randomA, randomL);
moveItem(particle, particle.x + randomT.x, particle.y + randomT.y, 0.4, () => {
moveItem(particle, particle.x + randomT.x, particle.y + randomT.y, showTime, () => {
}, TWEEN.Easing.Exponential.Out);
scaleItem(particle, 0, 0.6, () => {
// scaleItem(particle, 0, 0.6, () => {
//
// });
scaleItem(particle, randomS, 0.6, () => {
}, TWEEN.Easing.Exponential.Out);
setTimeout(() => {
hideItem(particle, 0.4, () => {
}, TWEEN.Easing.Cubic.In);
}, showTime * 0.5 * 1000);
});
}
}
......@@ -1535,7 +1585,7 @@ export function shake(item, time = 0.5, callback = null, rate = 1) {
};
const move1 = () => {
moveItem(item, baseX + offX, baseY + offY, time / 8, () => {
moveItem(item, baseX + offX, baseY + offY, time / 7.5, () => {
move2();
}, easing);
};
......
......@@ -18,12 +18,12 @@ import TWEEN from '@tweenjs/tween.js';
@Component({
selector: 'app-play',
templateUrl: './play.component.html',
styleUrls: ['./play.component.scss']
styleUrls: ['./play.component.css']
})
export class PlayComponent implements OnInit, OnDestroy {
@ViewChild('canvas') canvas: ElementRef;
@ViewChild('wrap') wrap: ElementRef;
@ViewChild('canvas', {static: true }) canvas: ElementRef;
@ViewChild('wrap', {static: true }) wrap: ElementRef;
// 数据
data;
......
@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;
}
......@@ -4,12 +4,12 @@
<meta charset="utf-8">
<title>NgOne</title>
<base href="/">
<!-- <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">-->
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<script type="text/javascript" src="http://teach.cdn.ireadabc.com/h5template/h5-static-lib/js/air.js"></script>
</head>
<body>
<app-root></app-root>
......
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