Commit 5648bd21 authored by limingzhe's avatar limingzhe

fix: debug

parent c71b356e
No preview for this file type
......@@ -6,7 +6,7 @@ import { Component , OnInit} from '@angular/core';
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
type = 'form';
type = 'play';
constructor() {
const tp = this.getQueryString('type');
......
import { BrowserModule } from '@angular/platform-browser';
import {DragDropModule} from '@angular/cdk/drag-drop';
import { NgModule, ErrorHandler } from '@angular/core';
import {MyErrorHandler} from './MyError';
......@@ -24,7 +25,13 @@ import {AudioRecorderComponent} from './common/audio-recorder/audio-recorder.com
import { FontAwesomeModule, FaIconLibrary } from '@fortawesome/angular-fontawesome';
import { fas } from '@fortawesome/free-solid-svg-icons';
import { far } from '@fortawesome/free-regular-svg-icons';
import { CustomActionComponent } from './common/custom-action/custom-action.component';
import { UploadDragonBoneComponent } from './common/upload-dragon-bone/upload-dragon-bone.component';
import { SubTemplateComponent } from './common/sub-template/sub-template.component';
import {FormulaInputComponent} from './common/formula-input/formula-input.component';
import { MultRectComponent } from './common/mult-rect/mult-rect.component';
import { AnchorGroupComponent } from './common/anchor-group/anchor-group.component';
registerLocaleData(zh);
......@@ -41,9 +48,14 @@ registerLocaleData(zh);
TimePipe,
UploadVideoComponent,
CustomHotZoneComponent,
UploadDragonBoneComponent,
PlayerContentWrapperComponent
SubTemplateComponent,
PlayerContentWrapperComponent,
CustomActionComponent,
UploadDragonBoneComponent,
FormulaInputComponent,
MultRectComponent,
AnchorGroupComponent
],
imports: [
BrowserModule,
......@@ -51,7 +63,8 @@ registerLocaleData(zh);
FormsModule,
HttpClientModule,
BrowserAnimationsModule,
FontAwesomeModule
FontAwesomeModule,
DragDropModule
],
providers: [
{provide: ErrorHandler, useClass: MyErrorHandler},
......
<div class="container">
<div class="row">
<div class="square" [class.active]="activeIndex === 1" (click)="onClick(1)">&#8598;</div>
<div class="square" [class.active]="activeIndex === 2" (click)="onClick(2)">&uarr;</div>
<div class="square" [class.active]="activeIndex === 3" (click)="onClick(3)">&#8599;</div>
</div>
<div class="row">
<div class="square" [class.active]="activeIndex === 4" (click)="onClick(4)">&larr;</div>
<div class="square center" [class.active]="activeIndex === 5" (click)="onClick(5)">&bull;</div>
<div class="square" [class.active]="activeIndex === 6" (click)="onClick(6)">&rarr;</div>
</div>
<div class="row">
<div class="square" [class.active]="activeIndex === 7" (click)="onClick(7)">&#8601;</div>
<div class="square" [class.active]="activeIndex === 8" (click)="onClick(8)">&darr;</div>
<div class="square" [class.active]="activeIndex === 9" (click)="onClick(9)">&#8600;</div>
</div>
</div>
\ No newline at end of file
.container {
display: flex;
flex-direction: column;
align-items: center;
}
.row {
display: flex;
}
.square {
width: 30px;
height: 30px;
border: 1px solid black;
margin: 5px;
display: flex;
align-items: center;
justify-content: center;
}
.center {
background-color: lightgray;
}
.arrows {
margin-top: 20px;
}
.arrow-up, .arrow-down, .arrow-left, .arrow-right {
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
}
.arrow-up {
border-bottom: 10px solid black;
margin-right: 5px;
}
.arrow-down {
border-top: 10px solid black;
margin-left: 5px;
}
.arrow-left {
border-right: 10px solid black;
transform: rotate(90deg);
margin-bottom: 5px;
}
.arrow-right {
border-left: 10px solid black;
transform: rotate(90deg);
margin-top: 5px;
}
.active {
background-color: yellow; /* 或者其他你想要的高亮颜色 */
}
\ No newline at end of file
import {ApplicationRef, Component, EventEmitter, Input, OnChanges, OnDestroy, Output} from '@angular/core';
import { NzMessageService, UploadXHRArgs, UploadFile } from 'ng-zorro-antd';
@Component({
selector: 'app-anchor-group',
templateUrl: './anchor-group.component.html',
styleUrls: ['./anchor-group.component.scss']
})
export class AnchorGroupComponent implements OnDestroy, OnChanges {
uploading = false;
progress = 0;
@Input()
activeIndex;
@Output()
save = new EventEmitter();
@Output()
refreshEmitter = new EventEmitter();
uploadUrl;
uploadData;
panelVisible = false;
colorArr = [
{name: 'red', color: '#ff0000'},
{name: 'green', color: '#00ff00'},
{name: 'blue', color: '#0000ff'},
{name: 'yellow', color: '#ffff00'},
]
// activeIndex: number | null = null;
constructor(private appRef: ApplicationRef, private nzMessageService: NzMessageService) {
// this.uploadUrl = (<any> window).courseware.uploadUrl();
// this.uploadData = (<any> window).courseware.uploadData();
// window['air'].getUploadCallback = (url, data) => {
// this.uploadUrl = url;
// this.uploadData = data;
// };
}
ngOnChanges() {
}
onClick(index: number) {
console.log(`Square ${index} clicked`);
this.activeIndex = index;
this.save.emit(this.activeIndex)
}
onClickArrow(direction: string) {
console.log(`Arrow ${direction} clicked`);
// 这里可以添加点击箭头后的逻辑
}
/**
* 刷新 渲染页面
*/
refresh() {
// this.refreshEmitter.emit();
setTimeout(() => {
this.appRef.tick();
}, 1);
}
ngOnDestroy() {
}
}
<div class="d-flex" (drop)="handle_drop($event)" (dragover)="handle_dragover($event)">
<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>
......@@ -35,7 +35,8 @@
<ng-template #truthyTemplate >
<div class="btn-delete" (click)="onBtnDeleteAudio()">
<fa-icon icon="close"></fa-icon>
<!-- <fa-icon icon="close"></fa-icon> -->
<i nz-icon nzType="close" nzTheme="outline"></i>
</div>
</ng-template>
......@@ -45,19 +46,17 @@
<fa-icon icon="cog"></fa-icon>
</div>
</ng-template>
</div>
<div class="p-progress ml-2" (click)="onBtnPlay()" *ngIf="audioUrl || audioBlob"
style="background-color: #70B603; width: 35px; height: 35px; border-radius: 35px; margin-left: 10px;margin-top:-1px">
<nz-progress [nzPercent]="percent" [nzWidth]="35" [nzFormat]="progressText"
nzType="circle">
</nz-progress>
<div class="p-btn-play"
style="color: white;margin-left: 2px;margin-top: 1px;"
[style.left]="isPlaying?'8px':''">
<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>
</div>
<div class="audio-name">{{_audioName}}</div>
</div>
......@@ -90,26 +90,17 @@
}
.p-progress {
margin-top: 3.5px;
margin-top: 2px;
position: relative;
background-color: #27b43f;
border-radius: 15px;
line-height: 26px;
.p-btn-play {
position: absolute;
left: 11px;
left: 10px;
top: 3px;
color: #ffffff;
color: #555;
}
}
.audio-name{
margin-top: 3.5px;
position: relative;
margin-left: 7px;;
line-height: 26px;
}
:host ::ng-deep nz-upload {
line-height: 33px;
}
......
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';
declare var Recorder;
......@@ -26,26 +26,17 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
uploadData;
@Input()
needRemove = false;
needRemove = true;
@Input()
audioItem: any = null;
@Input()
_audioName: any = null;
@Input()
set audioUrl(url) {
this._audioUrl = url;
if (url) {
this.httpHeadCall(this._audioUrl, flag => {
if (flag) {
this.audio.src = this._audioUrl;
} else {
this.audio.src = this._audioUrl.replace("_l.", ".");
}
this.audio.load();
});
this.audio.src = this._audioUrl;
this.audio.load();
}
this.init();
}
......@@ -57,7 +48,6 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
@Output() audioUploaded = new EventEmitter();
@Output() audioUploadFailure = new EventEmitter();
@Output() audioRemoved = new EventEmitter();
@Output() audioName = new EventEmitter();
percent = 0;
progress = 0;
recorder: any;
......@@ -72,43 +62,25 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
this.uploadUrl = url;
this.uploadData = data;
};
this.setUploadUrl();
}
httpHeadCall(requsetUrl: string, callback) {
let xhr = new XMLHttpRequest();
console.log("Status: Send Post Request to " + requsetUrl);
try {
xhr.onreadystatechange = () => {
try {
console.log('xhr.readyState: ', xhr.readyState);
if (xhr.readyState == 4) {
if ((xhr.status >= 200 && xhr.status < 400)) {
callback(true);
} else {
callback(false);
}
}
} catch (e) {
console.log(e)
}
};
xhr.open("HEAD", requsetUrl, true);
xhr.send();
xhr.timeout = 15000;
xhr.onerror = (e) => {
console.log("汪汪汪 posterror", e);
callback(false);
};
xhr.ontimeout = (e) => {
console.log("汪汪汪 ontimeout", e);
callback(false);
};
} catch (e) {
console.log("Send Get Request error: ", e)
setUploadUrl() {
if (!this.uploadUrl) {
this.uploadUrl = (<any> window).courseware.uploadUrl();
this.uploadData = (<any> window).courseware.uploadData();
setTimeout(() => {
this.setUploadUrl();
}, 500);
}
}
init() {
this.playIcon = 'play';
this.isPlaying = false;
......@@ -202,6 +174,7 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
onBtnDeleteAudio() {
this.audioUrl = null;
this.audioUploaded.emit({});
this.audioRemoved.emit();
}
......@@ -213,12 +186,8 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
break;
case 'success':
this.isUploading = false;
let url = info.file.response.url;
url = url.substring(0, url.lastIndexOf(".")) + "_l.mp3";
info.file.response.url = url;
this.uploadSuccess(info.file.response);
this.audioUploaded.emit(info.file.response);
this.audioName.emit(info.file.name);
break;
case 'progress':
this.progress = parseInt(info.event.percent, 10);
......@@ -276,39 +245,6 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
this.progress = Math.floor(p * 100);
}
linkInputed (url, name) {
url = url.substring(0, url.lastIndexOf(".")) + "_l.mp3";
this.audioUrl = url;
this.audioUploaded.emit({url});
this.audioName.emit(name);
}
handle_dragover(e) {
e.preventDefault();
}
handle_drop(e) {
const dt = e.dataTransfer.getData("text/plain");
console.log("handle_drop===", dt);
if (!dt) {
return;
}
try {
const {url, name} = JSON.parse(dt);
if (url.indexOf("teach")<0 || url.indexOf("cdn")<0) {
return;
}
const white = [".mp3"];
if (!white.includes(url.substr(url.lastIndexOf(".")))) {
return;
}
this.linkInputed(url, name);
} catch (error) {
console.warn("handle_drop拖拽在线音频传递参数不合法,应该是{url:'', name:''}");
}
}
}
enum Type {
......
<div class="position-relative">
<button nz-button (click)="setAnimaBtnClick()" style=" border-radius: 0.5rem; border: 1px solid #ddd;" >
<i nz-icon nzType="tool" nzTheme="outline"></i>
{{btnName}}
</button>
<!--配置龙骨面板-->
<nz-modal [(nzVisible)]="panelVisible" (nzAfterClose)="closePanel()" [nzTitle]="btnName" (nzOnCancel)="panelCancel()" (nzOnOk)="panelOk()" nzOkText="保存">
<div>
<h4>基础内容:</h4>
<div style="margin-bottom: 10px; width: 80%; margin: auto;">
<!-- <nz-radio-group [ngModel]="item.type" (ngModelChange)="radioChange($event)">
<label nz-radio nzValue="pic">图片</label>
<label nz-radio nzValue="text">文本</label>
</nz-radio-group> -->
<div *ngIf="item.type == 'pic'">
<app-upload-image-with-preview
[picUrl]="item?.pic_url"
(imageUploaded)="onItemImgUploadSuccess($event, item)">
</app-upload-image-with-preview>
</div>
<div *ngIf="item.type == 'text'">
<input type="text" nz-input [(ngModel)]="item.text" (blur)="saveText(item)">
</div>
<div *ngIf="item.type == 'anima'" style="margin-left: 100px;">
<app-upload-dragon-bone
[skeJsonData]=item.skeJsonData
[texJsonData]=item.texJsonData
[texPngData]=item.texPngData
(save)="saveAnima($event)"
>
</app-upload-dragon-bone>
</div>
</div>
<nz-divider style="margin-top: 10px;"></nz-divider>
<h4>状态设置:</h4>
<div style="display: flex; justify-content: space-around;">
<div style="width: 30%; display: flex; align-items: center; flex-direction: column;">
<h5> 开始状态 </h5>
<div *ngFor="let op of item.changeOption; let i = index" style="margin-bottom: 5px; ">
<div style="display: flex; align-items: center; justify-content: center;">
<span>{{op[0]}}: </span> <input type="text" nz-input [(ngModel)]="op[1]" (blur)="saveText(op)" style="margin-left: 5px;">
</div>
</div>
</div>
<div style="width: 30%; display: flex; align-items: center; flex-direction: column; ">
<h5> 切换时间 </h5>
<div style="display: flex; width: 100%; align-items: center; justify-content: center;">
<span>time: </span> <input type="text" nz-input [(ngModel)]="item.changeTime" (blur)="saveText(item.changeTime)" style="width: 80px; margin-left: 5px;">
</div>
</div>
<div style="width: 30%; display: flex; align-items: center; flex-direction: column;">
<h5> 结束状态 </h5>
<div *ngFor="let op of item.changeOption; let i = index" style="margin-bottom: 5px; ">
<div style="display: flex; align-items: center; justify-content: center;">
<span>{{op[0]}}: </span> <input [disabled]="op[2] == null" type="text" nz-input [(ngModel)]="op[2]" (blur)="saveText(op)" style="margin-left: 5px;">
</div>
</div>
</div>
</div>
<div style="display: flex; align-items: center; justify-content: center; margin-top: 10px;">
<button style="margin-left: 20px; margin-top: -5px" nz-button (click)="copyChangeData()"> 复制数据 </button>
<div style="margin-left: 20px; margin-top: -5px" >
<span>粘贴数据: </span>
<input style="width: 100px;" type="text" nz-input [(ngModel)]="pasteData" >
<button style="margin-left: 5px;" nz-button [disabled]="pasteData==''" nzType="primary" (click)="importData()">导入</button>
</div>
</div>
<nz-divider style="margin-top: 10px;"></nz-divider>
<h4> 音频设置 </h4>
<app-audio-recorder
style="margin: auto"
[audioUrl]="item?.audio_url"
(audioUploaded)="onItemAudioUploadSuccess($event, item)"
></app-audio-recorder>
</div>
<!--
<div class="anima-upload-btn">
<span style="margin-right: 10px">上传 ske_json 文件: </span>
<nz-upload [nzShowUploadList]="false"
nzAccept="application/json"
[nzAction]="uploadUrl"
[nzData]="uploadData"
(nzChange)="skeJsonHandleChange($event)">
<button nz-button><i nz-icon nzType="upload"></i><span>Upload</span></button>
</nz-upload>
<i *ngIf="isSkeJsonLoading" style="margin-left: 10px;" nz-icon [nzType]="'loading'"></i>
<span *ngIf="skeJsonData && skeJsonData['name']" style="margin-left: 10px"><u> {{skeJsonData['name']}} </u></span>
</div>
<div class="anima-upload-btn">
<span style="margin-right: 10px">上传 tex_json 文件: </span>
<nz-upload [nzShowUploadList]="false"
nzAccept="application/json"
[nzAction]="uploadUrl"
[nzData]="uploadData"
(nzChange)="texJsonHandleChange($event)">
<button nz-button><i nz-icon nzType="upload"></i><span>Upload</span></button>
</nz-upload>
<i *ngIf="isTexJsonLoading" style="margin-left: 10px;" nz-icon [nzType]="'loading'"></i>
<span *ngIf="texJsonData && texJsonData['name']" style="margin-left: 10px"><u> {{texJsonData['name']}} </u></span>
</div>
<div class="anima-upload-btn">
<span style="margin-right: 10px">上传 tex_png 文件: </span>
<nz-upload [nzShowUploadList]="false"
nzAccept = "image/*"
[nzAction]="uploadUrl"
[nzData]="uploadData"
(nzChange)="texPngHandleChange($event)">
<button nz-button><i nz-icon nzType="upload"></i><span>Upload</span></button>
</nz-upload>
<i *ngIf="isTexPngLoading" style="margin-left: 10px;" nz-icon [nzType]="'loading'"></i>
<span *ngIf="texPngData && texPngData['name']" style="margin-left: 10px"><u> {{texPngData['name']}} </u></span>
</div>
<div class="anima-upload-btn" *ngIf="animaNames && animaNames.length > 0">
提示:需包含动画: {{animaNames.toString()}}.
</div> -->
</nz-modal>
</div>
import {ApplicationRef, Component, EventEmitter, Input, OnChanges, OnDestroy, Output} from '@angular/core';
import { NzMessageService, UploadXHRArgs, UploadFile } from 'ng-zorro-antd';
@Component({
selector: 'app-custom-action',
templateUrl: './custom-action.component.html',
styleUrls: ['./custom-action.component.scss']
})
export class CustomActionComponent implements OnDestroy, OnChanges {
uploading = false;
progress = 0;
@Input()
btnName = '配置变化状态';
@Input()
option = []
@Input()
item;
@Input()
type = 'text'
@Output()
save = new EventEmitter();
@Output()
refreshEmitter = new EventEmitter();
uploadUrl;
uploadData;
panelVisible = false;
pasteData = '';
constructor(private appRef: ApplicationRef, private nzMessageService: NzMessageService) {
window['air'].getUploadCallback = (url, data) => {
this.uploadUrl = url;
this.uploadData = data;
};
const tmpId = setInterval(() => {
console.log(' in setInterval')
this.uploadUrl = (<any> window).courseware.uploadUrl();
this.uploadData = (<any> window).courseware.uploadData();
if (this.uploadUrl) {
clearInterval(tmpId);
}
}, 500)
}
ngOnInit() {
this.initItem();
}
ngOnChanges() {
}
initItem() {
console.log('```this.item: ', this.item);
if (!this.item) {
this.item = {
type: this.type,
skeJsonData: {},
texJsonData: {},
texPngData: {},
changeStart: [
],
changeEnd: [
],
changeTime: 0.3
};
if (this.option) {
this.item.changeOption = JSON.parse(JSON.stringify(this.option));
}
}
console.log('initItem', this.item);
}
setAnimaBtnClick() {
this.panelVisible = true;
this.refresh();
}
panelCancel() {
this.panelVisible = false;
this.refresh();
}
panelOk() {
// this.sendItemDragonBoneData();
this.panelVisible = false;
this.refresh();
this.save.emit(this.item);
}
saveText(t) {
}
radioChange(e) {
this.item.type = e;
console.log('e: ', e);
}
onItemImgUploadSuccess(e, item) {
item.pic_url = e.url;
this.refresh();
}
onItemAudioUploadSuccess(e, item) {
item.audio_url = e.url;
this.refresh();
}
saveAnima(e) {
console.log("~ e: ", e);
}
copyChangeData() {
console.log('this.item: ', this.item);
const jsonData = {
changeOption: this.item.changeOption,
changeTime : this.item.changeTime
// bgItem,
// hotZoneItemArr,
// isHasRect: this.isHasRect,
// isHasPic: this.isHasPic,
// isHasText: this.isHasText,
// isHasAudio: this.isHasAudio,
// isHasAnima: this.isHasAnima,
// hotZoneFontObj: this.hotZoneFontObj,
// defaultItemType: this.defaultItemType,
// hotZoneImgSize: this.hotZoneImgSize,
};
const oInput = document.createElement('input');
oInput.value = JSON.stringify(jsonData);
document.body.appendChild(oInput);
oInput.select(); // 选择对象
document.execCommand('Copy'); // 执行浏览器复制命令
document.body.removeChild(oInput);
this.nzMessageService.success('复制成功');
}
importData() {
if (!this.pasteData) {
return;
}
try {
const data = JSON.parse(this.pasteData);
console.log('data:', data);
const {
changeOption,
changeTime
} = data;
this.item.changeOption = changeOption;
this.item.changeTime = changeTime;
this.pasteData = '';
} catch (e) {
console.log('err: ', e);
this.nzMessageService.error('导入失败');
}
}
/**
* 刷新 渲染页面
*/
refresh() {
// this.refreshEmitter.emit();
setTimeout(() => {
this.appRef.tick();
}, 1);
}
closePanel() {
console.log(' in closePanel ');
this.refresh();
}
ngOnDestroy() {
}
}
......@@ -604,8 +604,8 @@ export class Label extends MySprite {
// fontSize:String = '40px';
fontName = 'Verdana';
textAlign = 'left';
fontSize = 40;
textAlign = 'center';
_fontSize = 40;
fontColor = '#000000';
fontWeight = 900;
_maxWidth;
......@@ -626,6 +626,16 @@ export class Label extends MySprite {
this.init();
}
get fontSize(): number {
return this._fontSize;
}
set fontSize(value: number) {
console.log('set size :' + value);
this._fontSize = value;
this.refreshSize();
}
get text(): string {
return this._text;
......@@ -640,7 +650,7 @@ export class Label extends MySprite {
this.ctx.save();
this.ctx.font = `${this.fontSize * this.scaleX}px ${this.fontName}`;
this.ctx.font = `${this.fontSize}px ${this.fontName}`;
this.ctx.textAlign = this.textAlign;
this.ctx.textBaseline = 'middle';
this.ctx.fontWeight = this.fontWeight;
......@@ -653,6 +663,11 @@ export class Label extends MySprite {
}
refreshLabelScale() {
}
setMaxSize(w) {
this._maxWidth = w;
......@@ -1946,11 +1961,11 @@ export function shake(item, time = 0.5, callback = null, rate = 1) {
export class HotZoneItem extends MySprite {
lineDashFlag = false;
arrow: MySprite;
label: Label;
title;
lineDashFlag = false;
arrow;
arrowTop;
arrowRight;
......@@ -1960,6 +1975,12 @@ export class HotZoneItem extends MySprite {
gIdx;
isAnimaStyle = false;
isSelect = false;
rectFillColor = '#ffffff';
rectEdgeColor = '#1bfff7';
rectSelectColor = '#ff9900';
private _itemType;
private shapeRect: ShapeRect;
......@@ -1980,7 +2001,7 @@ export class HotZoneItem extends MySprite {
rect.x = -w / 2;
rect.y = -h / 2;
rect.setSize(w, h);
rect.fillColor = '#ffffff';
rect.fillColor = this.rectFillColor;
rect.alpha = 0.2;
this.addChild(rect);
}
......@@ -2096,6 +2117,9 @@ export class HotZoneItem extends MySprite {
const rect = this.getBoundingBox();
// let color = this.isSelect ? this.rectSelectColor : this.rectEdgeColor;
const w = rect.width;
const h = rect.height;
const x = rect.x + w / 2;
......@@ -2103,7 +2127,7 @@ export class HotZoneItem extends MySprite {
this.ctx.setLineDash([5, 5]);
this.ctx.lineWidth = 2;
this.ctx.strokeStyle = '#1bfff7';
this.ctx.strokeStyle = this.rectEdgeColor;
// this.ctx.fillStyle = '#ffffff';
this.ctx.beginPath();
......@@ -2176,40 +2200,145 @@ export class HotZoneImg extends MySprite {
export class HotZoneLabel extends Label {
lineDashFlag = false;
arrow;
arrowTop;
arrowRight;
drawFrame() {
this.ctx.save();
const rect = this.getBoundingBox();
const w = rect.width / this.scaleX;
const h = this.height * this.scaleY;
const x = this.x;
const y = this.y;
const w = rect.width;
const h = rect.height;
const x = rect.x + w / 2;
const y = rect.y + h / 2;
this.ctx.setLineDash([5, 5]);
this.ctx.lineWidth = 2;
this.ctx.strokeStyle = '#1bfff7';
this.ctx.strokeStyle = '#1bfff7';//this.rectEdgeColor;
// this.ctx.fillStyle = '#ffffff';
this.ctx.beginPath();
this.ctx.moveTo( x - w / 2, y - h / 2);
this.ctx.lineTo(x + w / 2, y - h / 2);
this.ctx.lineTo(x + w / 2, y + h / 2);
this.ctx.lineTo(x - w / 2, y + h / 2);
this.ctx.lineTo(x - w / 2, y - h / 2);
// this.ctx.fill();
this.ctx.stroke();
this.ctx.restore();
// this.ctx.save();
// const rect = this.getBoundingBox();
// const w = rect.width / this.scaleX;
// const h = this.height * this.scaleY;
// const x = this.x;
// const y = this.y;
// this.ctx.setLineDash([5, 5]);
// this.ctx.lineWidth = 2;
// this.ctx.strokeStyle = '#1bfff7';
// this.ctx.beginPath();
// this.ctx.moveTo( x - w / 2, y - h / 2);
// this.ctx.lineTo(x + w / 2, y - h / 2);
// this.ctx.lineTo(x + w / 2, y + h / 2);
// this.ctx.lineTo(x - w / 2, y + h / 2);
// this.ctx.lineTo(x - w / 2, y - h / 2);
// // this.ctx.fill();
// this.ctx.stroke();
// this.ctx.restore();
}
showLineDash() {
this.lineDashFlag = true;
if (this.arrow) {
this.arrow.visible = true;
} else {
this.arrow = new MySprite(this.ctx);
this.arrow.load('assets/common/arrow.png', 1, 0);
this.arrow.setScaleXY(0.06);
this.arrowTop = new MySprite(this.ctx);
this.arrowTop.load('assets/common/arrow_top.png', 0.5, 0);
this.arrowTop.setScaleXY(0.06);
this.arrowRight = new MySprite(this.ctx);
this.arrowRight.load('assets/common/arrow_right.png', 1, 0.5);
this.arrowRight.setScaleXY(0.06);
}
}
hideLineDash() {
this.lineDashFlag = false;
if (this.arrow) {
this.arrow.visible = false;
}
}
drawArrow() {
if (!this.arrow) { return; }
const rect = this.getBoundingBox();
this.arrow.x = rect.x + rect.width;
this.arrow.y = rect.y;
this.arrow.update();
this.arrowTop.x = rect.x + rect.width / 2;
this.arrowTop.y = rect.y;
this.arrowTop.update();
this.arrowRight.x = rect.x + rect.width;
this.arrowRight.y = rect.y + rect.height / 2;
this.arrowRight.update();
}
draw() {
super.draw();
this.drawFrame();
if (this.showLineDash) {
this.drawArrow();
this.drawFrame();
}
}
getLabelRect() {
......
<nz-input-group [nzSuffix]="suffixTemplate">
<input type="text"
#inputEl
(focus)="showFormulaPad($event)"
nz-input [(ngModel)]="ngfModel"
(ngModelChange)="valueChanged($event)" />
</nz-input-group>
<ng-template #suffixTemplate>
<i nz-icon [nzType]="'percentage'" (click)="showFormulaPad($event)"></i>
</ng-template>
<!-- cdkDrag-->
<!--<div style='position: absolute;visibility: hidden' class="FormulaBoardContainer" #wrapperEl >-->
<!--</div>-->
@import '../../style/common_mixin.css';
:host{
display: inline-block;
}
import {
AfterViewInit,
Component,
ElementRef, EventEmitter,
Input,
OnChanges,
OnDestroy,
OnInit, Output,
ViewChild
} from '@angular/core';
import {fromEvent, Observable, Subscription} from 'rxjs';
declare global {
interface Window {
FBOARD: any;
FormulaBoard: any;
__initfp__: any;
__tmp_fp_input_model__: any;
__FormulaBoard_js_installed__: any;
}
}
@Component({
selector: 'app-formula-input',
templateUrl: './formula-input.component.html',
styleUrls: ['./formula-input.component.scss']
})
export class FormulaInputComponent implements OnInit, OnChanges, OnDestroy, AfterViewInit {
@ViewChild('inputEl', {static: true }) inputEl: ElementRef;
// @ViewChild('wrapperEl', {static: true }) wrapperEl: ElementRef;
private fboard: any;
// [(ngModel)]="item.title" (blur)="save()"
@Input() ngfModel: any;
@Output() ngfModelChange = new EventEmitter();
@Output() ngfBlur = new EventEmitter();
FB_id = 'FormulaBoard';
private esc: Subscription;
constructor() {
if (!window.__FormulaBoard_js_installed__) {
window.__FormulaBoard_js_installed__ = true;
const s = document.createElement('script');
s.src = 'assets/formula-board/formula-board.js';
document.head.append(s);
s.addEventListener('load', () => {
this.FormulaBoardInit();
});
}
}
ngOnInit() {
}
ngOnChanges() {
}
ngOnDestroy(): void {
}
valueChanged(evt) {
console.log('valueChanged', this.ngfModel, evt);
this.ngfModelChange.emit(evt);
}
showFormulaPad(e) {
// console.log('showFormulaPad', e);
window.FBOARD.set(e.target.value);
window.__tmp_fp_input_model__ = this;
const rect = this.inputEl.nativeElement.getBoundingClientRect();
const fb = document.getElementById(this.FB_id);
fb.style.position = 'fixed';
// @ts-ignore
const padWidth = $('#' + this.FB_id).outerWidth() * .8;
// @ts-ignore
const padHeight = $('#' + this.FB_id).outerHeight() * .8;
// @ts-ignore
const ww = $(window).innerWidth();
// @ts-ignore
const hh = $(window).innerHeight();
const left = (ww - padWidth) / 2;
const top = (hh - padHeight) / 2;
console.log('left', left);
fb.style.left = left + 'px';
fb.style.top = top + 'px';
fb.style.visibility = 'visible';
}
updateValue(val) {
this.ngfModel = val;
this.ngfModelChange.emit(val);
}
ngAfterViewInit() {}
FormulaBoardInit() {
// if (window.__initfp__) {
// return;
// }
// window.__initfp__ = true;
window.FBOARD = new window.FormulaBoard({
// container: this.wrapperEl.nativeElement,
id: this.FB_id,
path: 'assets/formula-board/',
options: {
width: 1920,
mode: 'pc',
bottom: false,
}});
document.addEventListener('documentMessage', (e) => {
// @ts-ignore
const {type} = e.detail;
if (type === 'common.setFormula') {
// @ts-ignore
const {formula} = e.detail.data.body;
console.log(formula);
window.FBOARD.clear();
// @ts-ignore
window.__tmp_fp_input_model__.updateValue(formula);
window.FBOARD.editor.style.visibility = 'hidden';
this.ngfBlur.emit();
}
if (type === 'common.closeModal') {
window.FBOARD.editor.style.visibility = 'hidden';
}
});
}
}
<div >
<button nz-button (click)="setRectBtnClick()" style=" border-radius: 0.5rem; border: 1px solid #ddd;">
<i nz-icon nzType="tool" nzTheme="outline"></i>
{{btnName}}
</button>
<!--配置龙骨面板-->
<nz-modal [(nzVisible)]="panelVisible" (nzAfterClose)="panelCancel()" nzTitle="配置多矩形集合"
(nzOnCancel)="panelCancel()" (nzOnOk)="panelOk()" nzOkText="保存">
<div *ngFor="let r of rectArr; let i = index" style="margin-top:5px; width:100%; height:40px; border-radius: 0.5rem; border: solid 2px #ccc;
display: flex; align-items:center; justify-content:space-between">
<div>
<span style="margin-left: 10px; font-weight: 600; font-size: 16px " >
{{'rect-' + (i+1)}}
</span>
</div>
<div>
<nz-radio-group [ngModel]="r.color" (ngModelChange)="radioChange($event, r)" style="display: flex; align-items: center; justify-content: center; flex-wrap: wrap;">
<div *ngFor="let colorData of colorArr; let j = index" style="display: flex; ">
<label nz-radio nzValue="{{colorData.color}}">{{colorData.name}}</label>
</div>
</nz-radio-group>
</div>
<div>
<button nz-button (click)="deleteRect(r)" nzType="danger" style=" margin-right: 5px;">
X
</button>
</div>
</div>
<button nz-button (click)="addRect()" nzType="dashed" style="margin-top: 20px; ">
<i nz-icon nzType="plus-circle" nzTheme="outline"></i>
添加矩形
</button>
<!-- <div class="anima-upload-btn">
<span style="margin-right: 10px">上传 ske_json 文件: </span>
<nz-upload [nzShowUploadList]="false" nzAccept="application/json" [nzAction]="uploadUrl" [nzData]="uploadData"
(nzChange)="skeJsonHandleChange($event)">
<button nz-button><i nz-icon nzType="upload"></i><span>Upload</span></button>
</nz-upload>
<i *ngIf="isSkeJsonLoading" style="margin-left: 10px;" nz-icon [nzType]="'loading'"></i>
<span *ngIf="skeJsonData && skeJsonData['name']" style="margin-left: 10px"><u> {{skeJsonData['name']}} </u></span>
</div>
<div class="anima-upload-btn">
<span style="margin-right: 10px">上传 tex_json 文件: </span>
<nz-upload [nzShowUploadList]="false" nzAccept="application/json" [nzAction]="uploadUrl" [nzData]="uploadData"
(nzChange)="texJsonHandleChange($event)">
<button nz-button><i nz-icon nzType="upload"></i><span>Upload</span></button>
</nz-upload>
<i *ngIf="isTexJsonLoading" style="margin-left: 10px;" nz-icon [nzType]="'loading'"></i>
<span *ngIf="texJsonData && texJsonData['name']" style="margin-left: 10px"><u> {{texJsonData['name']}} </u></span>
</div>
<div class="anima-upload-btn">
<span style="margin-right: 10px">上传 tex_png 文件: </span>
<nz-upload [nzShowUploadList]="false" nzAccept="image/*" [nzAction]="uploadUrl" [nzData]="uploadData"
(nzChange)="texPngHandleChange($event)">
<button nz-button><i nz-icon nzType="upload"></i><span>Upload</span></button>
</nz-upload>
<i *ngIf="isTexPngLoading" style="margin-left: 10px;" nz-icon [nzType]="'loading'"></i>
<span *ngIf="texPngData && texPngData['name']" style="margin-left: 10px"><u> {{texPngData['name']}} </u></span>
</div>
<div class="anima-upload-btn" *ngIf="animaNames && animaNames.length > 0">
提示:需包含动画: {{animaNames.toString()}}.
</div> -->
</nz-modal>
</div>
<div style="justify-content:space-between">
</div>
\ No newline at end of file
import {ApplicationRef, Component, EventEmitter, Input, OnChanges, OnDestroy, Output} from '@angular/core';
import { NzMessageService, UploadXHRArgs, UploadFile } from 'ng-zorro-antd';
@Component({
selector: 'app-mult-rect',
templateUrl: './mult-rect.component.html',
styleUrls: ['./mult-rect.component.scss']
})
export class MultRectComponent implements OnDestroy, OnChanges {
uploading = false;
progress = 0;
@Input()
btnName = '配置多矩形集合';
@Input()
animaNames = [];
@Input()
rectArr = [];
@Output()
save = new EventEmitter();
@Output()
refreshEmitter = new EventEmitter();
uploadUrl;
uploadData;
panelVisible = false;
colorArr = [
{name: 'red', color: '#ff0000'},
{name: 'green', color: '#00ff00'},
{name: 'blue', color: '#0000ff'},
{name: 'yellow', color: '#ffff00'},
]
constructor(private appRef: ApplicationRef, private nzMessageService: NzMessageService) {
// this.uploadUrl = (<any> window).courseware.uploadUrl();
// this.uploadData = (<any> window).courseware.uploadData();
// window['air'].getUploadCallback = (url, data) => {
// this.uploadUrl = url;
// this.uploadData = data;
// };
}
ngOnChanges() {
}
radioChange(e, item) {
console.log('e: ', e);
item.color = e;
}
addRect() {
this.rectArr.push(
{
color: this.colorArr[0].color,
width: 20,
height: 20,
x: 20,
y: 20,
}
)
}
deleteRect(item) {
const index = this.rectArr.indexOf(item);
if (index != -1) {
this.rectArr.splice(index, 1);
}
}
/**
* 刷新 渲染页面
*/
refresh() {
// this.refreshEmitter.emit();
setTimeout(() => {
this.appRef.tick();
}, 1);
}
setRectBtnClick() {
this.panelVisible = true;
}
panelOk() {
this.save.emit(this.rectArr)
this.panelVisible = false;
}
panelCancel() {
this.panelVisible = false;
this.refresh();
}
ngOnDestroy() {
}
}
<div class="content">
<div style="display: flex; margin-bottom: 5px;">
<button nz-button nzType="dashed" (click)="selectSubTemplate()" style=" border-radius: 0.5rem; border: 1px solid #ddd;">
<i nz-icon nzType="appstore" nzTheme="outline"></i>
选择子模板类型
</button>
<h2 *ngIf="_item.template" style="margin-left: 10px; margin-top: 1px;">
{{_item.template.description}}
</h2>
<button nz-button nzType="danger" (click)="deleteSubTemplate()" style="position: absolute; right: 30px; border-radius: 0.5rem; border: 1px solid #ddd;">
<i nz-icon nzType="delete" nzTheme="outline"></i>
删除
</button>
</div>
<iframe #iframe id="iframe" [src]="safeUrl" style="width: 98%; height: 70vh; border: 1px solid #ccc; padding: 5px;" frameborder="0">
</iframe>
<nz-modal [(nzVisible)]="isShowTemplate" (nzAfterClose)="closePanel()" nzTitle="选择子模板" [nzFooter]="null"
(nzOnCancel)="panelCancelClicked()" nzWidth="80%" nzHeight="80%">
<div class="template-container">
<div *ngFor="let template of templateArr" >
<div (click)="templateClick(template)" style="width: 150px; height: 100px; border: 1px solid #ccc; margin: 5px; cursor:pointer; user-select: none;">
<div style="width: 100%; height: 70%; border-bottom: 1px solid #ccc; overflow: hidden;">
<img [src]="template.cover" style="width: 100%; height: auto;">
</div>
<div style="width: 100%; height: 30%; display: flex; align-items: center; justify-content: center; ">
<label style="width: 90%; text-align: center; text-overflow: ellipsis; white-space:nowrap; overflow: hidden; ">{{template.description}}</label>
</div>
</div>
</div>
</div>
</nz-modal>
</div>
\ No newline at end of file
@import '../../style/common_mixin.css';
.content {
// width: 100%;
height: 100%;
border: 2px solid #ccc;
padding: 10px;
border-radius: 5px;
}
.template-container{
width: 100%;
display: flex;
// align-items: center;
// justify-content: space-around;
flex-wrap: wrap;
}
\ No newline at end of file
This diff is collapsed.
<div class="position-relative" (drop)="handle_drop($event)" (dragover)="handle_dragover($event)">
<div class="position-relative">
<button nz-button (click)="setAnimaBtnClick()" style=" border-radius: 0.5rem; border: 1px solid #ddd;" (dragover)="handle_dragover($event)">
<button nz-button (click)="setAnimaBtnClick()" style=" border-radius: 0.5rem; border: 1px solid #ddd;">
<i nz-icon nzType="tool" nzTheme="outline"></i>
{{btnName}}
</button>
......
@import '../../style/common_mixin.css';
.p-image-uploader {
position: relative;
display: block;
width: 100%;
height: 0;
padding-bottom: 56.25%;
.p-box {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
border: 2px dashed #ddd;
border-radius: 0.5rem;
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-size: contain;
background-repeat: no-repeat;
background-position: 50% 50%;
//background-image: url("https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png");
}
}
.d-flex{
display: flex;
}
}
.p-btn-delete {
position: absolute;
right: -0.5rem;
top: -0.5rem;
width: 2rem;
height: 2rem;
border: 0.2rem solid white;
border-radius: 50%;
font-size: 1.2rem;
background-color: #fb781a;
color: white;
text-align: center;
}
.p-upload-progress-bg {
position: absolute;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
& .i-text {
position: absolute;
text-align: center;
color: white;
text-shadow: 0 0 2px rgba(0, 0, 0, .85);
}
& .i-bg {
position: absolute;
left: 0;
top: 0;
height: 100%;
background-color: #27b43f;
border-radius: 0.5rem;
}
}
.anima-upload-btn {
padding: 10px;
}
:host ::ng-deep .ant-upload {
display: block;
}
......@@ -178,43 +178,4 @@ export class UploadDragonBoneComponent implements OnDestroy, OnChanges {
ngOnDestroy() {
}
linkInputed (ske, tex, png) {
this.skeJsonData["url"] = ske.url;
this.skeJsonData["name"] = ske.name;
this.texJsonData["url"] = tex.url;
this.texJsonData["name"] = tex.name;
this.texPngData["url"] = png.url;
this.texPngData["name"] = png.name;
this.animaPanelOk();
}
handle_dragover(e) {
e.preventDefault();
}
handle_drop(e) {
e.preventDefault();
const dt = e.dataTransfer.getData("text/plain");
console.log("handle_drop===", dt);
if (!dt) {
return;
}
try {
const {ske, tex, png} = JSON.parse(dt);
if (!ske || !tex || !png ||
ske.url.indexOf("teach")<0 || ske.url.indexOf("cdn")<0 || ske.url.indexOf(".json")<0 ||
tex.url.indexOf("teach")<0 || tex.url.indexOf("cdn")<0 || tex.url.indexOf(".json")<0 ||
png.url.indexOf("teach")<0 || png.url.indexOf("cdn")<0 || png.url.indexOf(".png")<0 ||
!ske.name || !tex.name || !png.name
) {
console.warn("handle_drop拖拽在线骨骼动画传递参数不合法,应该是{ske:{url:'', name:''},tex:{url:'', name:''},png:{url:'', name:''}}");
return;
}
this.linkInputed(ske, tex, png);
} catch (error) {
console.warn("handle_drop拖拽在线骨骼动画传递参数不合法,应该是{ske:{url:'', name:''},tex:{url:'', name:''},png:{url:'', name:''}}");
}
}
}
<div class="position-relative" (drop)="handle_drop($event)" (dragover)="handle_dragover($event)">
<div class="position-relative">
<nz-upload class="p-image-uploader" [nzDisabled]="disableUpload"
[nzShowUploadList]="false"
nzAccept = "image/*"
[nzAction]="uploadUrl"
[nzData]="uploadData"
(nzChange)="handleChange($event)"
>
(nzChange)="handleChange($event)">
<!--[nzBeforeUpload]="customUpload">-->
<div class="p-box d-flex align-items-center">
<div class="p-upload-icon" *ngIf="!picUrl && !uploading">
......
......@@ -42,7 +42,28 @@ export class UploadImageWithPreviewComponent implements OnDestroy, OnChanges {
this.uploadData = data;
};
this.setUploadUrl();
}
setUploadUrl() {
if (!this.uploadUrl) {
console.log('this.uploadUrl -=- 1 : ', this.uploadUrl)
this.uploadUrl = (<any> window).courseware.uploadUrl();
this.uploadData = (<any> window).courseware.uploadData();
console.log('this.uploadUrl -=- 2 : ', this.uploadUrl)
setTimeout(() => {
this.setUploadUrl();
}, 500);
}
console.log('this.uploadUrl -=- 3 : ', this.uploadUrl)
}
ngOnChanges() {
if (!this.picItem) {
return;
......@@ -155,39 +176,4 @@ export class UploadImageWithPreviewComponent implements OnDestroy, OnChanges {
ngOnDestroy() {
}
linkInputed (url) {
const file = {
response: {url}
};
const img = new Image();
img.addEventListener('load', () => {
const height = img.naturalHeight;
const width = img.naturalWidth;
file['height'] = height;
file['width'] = width;
img.remove();
this.imageUploaded.emit(file.response);
});
img.src = url;
this.picUrl = url;
}
handle_dragover(e) {
e.preventDefault();
}
handle_drop(e) {
const dt = e.dataTransfer.getData("text/plain");
console.log("handle_drop===", dt);
if (!dt || dt.indexOf("teach")<0 || dt.indexOf("cdn")<0) {
return;
}
const white = [".jpg", ".jpeg", ".png", ".bmp", ".JPG", ".JPEG", ".PNG", ".BMP"];
if (!white.includes(dt.substr(dt.lastIndexOf(".")))) {
return;
}
this.linkInputed(dt);
}
}
<div class="p-video-box" (drop)="handle_drop($event)" (dragover)="handle_dragover($event)">
<div class="p-video-box">
<div class="up-video" style="display: flex;">
<!--<nz-upload class="" [nzDisabled]="!showUploadBtn"-->
<!--[nzShowUploadList]="false"-->
<!--[nzBeforeUpload]="beforeUpload"-->
<!--nzAccept = ".mp4"-->
<!--style="margin-right: 1rem">-->
<nz-upload class="p-image-uploader" [nzDisabled]="uploading" [nzShowUploadList]="false" nzAccept=".mp4"
[nzAction]="uploadUrl" [nzData]="uploadData" (nzChange)="handleChange($event)" style="margin-right: 1rem">
(nzChange)="handleChange($event)" [nzCustomRequest]="customReq"
style="margin-right: 1rem">
<button type="button" nz-button nzType="default" *ngIf="showUploadBtn" [disabled]="uploading"
[nzLoading]="uploading">
<i nz-icon nzType="plus" nzTheme="outline"></i>
<span>{{ uploading ? 'Uploading' : 'Select Video' }}</span>
<!--<span>Select Video</span>-->
</button>
</nz-upload>
<!--<button nz-button nzType="primary" *ngIf="showUploadBtn"-->
<!--style="margin-right: 1rem"-->
<!--type="button"-->
<!--[nzLoading]="uploading"-->
<!--(click)="handleUpload()"-->
<!--[disabled]="!videoFile || uploading">-->
<!--<i nz-icon type="upload" theme="outline"></i>-->
<!--<span>{{ uploading ? 'Uploading' : 'Start Upload' }}</span>-->
<!--</button>-->
<!--
<button type="button"
(click)="extraCover()"
nz-button nzType="default"
[disabled]=" !(videoUrl && videoUrl.constructor.name === 'String')">设置封面</button>
-->
<!--
<nz-divider></nz-divider>
<div [style.display]="!uploading?'none':''" style="position:relative">
<div style="width: calc( 100% - 20px);">
<nz-progress [nzPercent]="progress">
</nz-progress>
</div>
<i (click)="cancelUpload()" class="anticon anticon-close-circle" style="position: absolute;top: 50%;right: 0;transform: translateY(-50%);cursor: pointer"></i>
</div>
-->
<!-- <button type="button" nz-button nzType="default" *ngIf="showCapture && !uploading" [disabled]="uploading"
(click)="captureVideo()"
[nzLoading]="uploading">
<i nz-icon nzType="camera" nzTheme="outline"></i>
<span>截图</span>
</button> -->
</div>
<div class="p-box d-flex align-items-center p-video-uploader">
<div class="p-upload-icon" *ngIf="!showUploadBtn && !videoUrl && !uploading">
......@@ -60,7 +26,7 @@
<div class="p-progress-value">{{progress}}%</div>
</div>
</div>
<div class="p-upload-progress-bg dddd " *ngIf="uploading" [ngClass]="{'smart-bar': showUploadBtn}">
<div class="p-upload-progress-bg" *ngIf="uploading" [ngClass]="{'smart-bar': showUploadBtn}">
<div class="i-bg" [style.width]="progress+'%'"></div>
<div class="i-text">
<fa-icon icon="cloud-upload-alt"></fa-icon>
......@@ -74,9 +40,9 @@
<i nz-icon nzType="loading" nzTheme="outline"></i>Checking...
</div>
</div>
<div class="p-preview" *ngIf="!uploading && videoUrl ">
<!--<video crossorigin="anonymous" [src]="videoUrl" controls #videoNode></video>-->
<video [src]="safeVideoUrl(videoUrl)" controls #videoNode></video>
<div class="p-preview" *ngIf="!uploading&&playVedioUrl">
<video crossorigin="anonymous" [src]="playVedioUrl" controls #videoNode></video>
<!-- <video crossorigin="anonymous" [src]="safeVideoUrl()" controls #videoNode></video> -->
</div>
</div>
<div [style.display]="!checkVideoExists?'none':''">
......
......@@ -33,30 +33,3 @@
padding: 10px;
margin: 10px;
}
.button-right {
border-style: dotted;
border-color: rgb(42, 142, 72);
width: 100px;
height: 50px;
color: rgb(42, 142, 72);
background-color: white;
}
.button-wrong {
border-style: dotted;
border-color: rgb(180, 0, 0);
width: 100px;
height: 50px;
color: rgb(180, 0, 0);
background-color: white;
}
.button-disable {
border-style: dotted;
border-color: black;
width: 100px;
height: 50px;
color: black;
background-color: white;
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
export async function loadFonts (fontName, fontFile) {
// const font = new FontFace(
// "DroidSansFallback",
// "url(" + "../../assets/play/font/DroidSansFallback.ttf" + ")"
// );
try {
console.log(location.href.split("#")[0] + "assets/play/font/" + fontFile);
const font = new FontFace(
fontName,
"url(" + location.href.split("#")[0] + "../../assets/play/font/" + fontFile + ")"
);
console.log('start: ', new Date().getTime())
await font.load();
console.log('end: ', new Date().getTime())
document.fonts.add(font);
document.body.classList.add("fonts-loaded");
} catch (error) {
console.log(error);
}
}
// --------------- custom class --------------------
This diff is collapsed.
......@@ -3,6 +3,8 @@
height: 100%;
background: #ffffff;
background-size: cover;
}
#canvas {
......@@ -10,10 +12,28 @@
}
@font-face
{
font-family: 'BRLNSDB';
src: url("../../assets/font/BRLNSDB.TTF") ;
src: url("../../assets/play/font/BRLNSDB_1.TTF")
}
@font-face
{
font-family: 'Aileron-Black';
src: url("../../assets/play/font/Aileron-Black.ttf")
}
@font-face
{
font-family: 'Aileron-Bold';
src: url("../../assets/play/font/Aileron-Bold.ttf")
}
@font-face
{
font-family: 'DroidSansFallback';
src: url("../../assets/play/font/DroidSansFallback.ttf");
}
\ No newline at end of file
<span style="font-family:'DroidSansFallback'" ></span>
<span style="font-family:'Aileron-Black'" ></span>
<span style="font-family:'Aileron-Bold'" ></span>
<ng-template #tpl>
<video></video>
</ng-template>
<div style="display: none" #videoContainer></div>
<div class="game-container" #wrap >
<canvas id="canvas" style="width: 100%; height: 100%;" #canvas></canvas>
</div>
<div id='div_input'>
</div>
<!-- <div style="position: absolute; top: 0">
<label style="font-family: Aileron-Black;"></label>
<label style="font-family: DroidSansFallback;"></label>
</div> -->
This diff is collapsed.
const res = [
['op_item', "assets/play/op_item.png"],
['op_item_wrong', "assets/play/op_item_wrong.png"],
['op_item_right', "assets/play/op_item_right.png"],
['op_item_normal', "assets/play/op_item_normal.png"],
['btn_close', "assets/play/btn_close.png"],
['bg', "assets/play/bg.jpg"],
['video_bg', "assets/play/video_bg.jpg"],
['btn_replay', "assets/play/btn_replay.png"],
['icon_right', "assets/play/icon_right.png"],
['icon_wrong', "assets/play/icon_wrong.png"],
['answer_normal', "assets/play/answer_normal.png"],
['answer_right', "assets/play/answer_right.png"],
['answer_wrong', "assets/play/answer_wrong.png"],
['btn_video', "assets/play/btn_video.png"],
['btn_write', "assets/play/btn_write.png"],
];
const resAudio = [
['click', "assets/play/music/click.mp3"],
['submit', "assets/play/music/submit.mp3"],
['more', "assets/play/music/more.mp3"],
];
export {res, resAudio};
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<svg width="31px" height="23px" viewBox="0 0 31 23" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 62 (91390) - https://sketch.com -->
<title>up</title>
<desc>Created with Sketch.</desc>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="1-学科键盘" transform="translate(-1779.000000, -808.000000)">
<g id="输入框">
<g id="keyboard_light_landscape" transform="translate(0.000000, 585.000000)">
<g id="编组" transform="translate(1698.750000, 26.250000)">
<g id="上翻" transform="translate(50.625000, 163.125000)">
<g>
<rect id="key-boarder" fill="#313C42" opacity="0" x="0" y="0" width="90" height="90" rx="3.76"></rect>
<path d="M48.0085956,35.2507117 L59.3110016,50.5843863 C60.4979164,52.1946422 60.1130426,54.4324199 58.4513618,55.5826026 C57.8242714,56.0166623 57.072896,56.25 56.3022624,56.25 L33.6974504,56.25 C31.6554049,56.25 30,54.6458257 30,52.6669764 C30,51.920192 30.2407896,51.1920698 30.6887113,50.5843863 L41.9911172,35.2507117 C43.1780321,33.6404558 45.4872751,33.2674929 47.1489558,34.4176757 C47.4809703,34.6474896 47.7714424,34.9289723 48.0085956,35.2507117 Z" id="矩形" fill="#7F8B8F"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="31px" height="23px" viewBox="0 0 31 23" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 62 (91390) - https://sketch.com -->
<title>down</title>
<desc>Created with Sketch.</desc>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="1-学科键盘" transform="translate(-1779.000000, -954.000000)">
<g id="输入框">
<g id="keyboard_light_landscape" transform="translate(0.000000, 585.000000)">
<g id="编组" transform="translate(1698.750000, 26.250000)">
<g id="下翻" transform="translate(50.625000, 309.375000)">
<g>
<rect id="key-boarder" fill="#313C42" opacity="0" x="0" y="0" width="90" height="90" rx="3.76"></rect>
<path d="M48.0085956,54.7492883 L59.3110016,39.4156137 C60.4979164,37.8053578 60.1130426,35.5675801 58.4513618,34.4173974 C57.8242714,33.9833377 57.072896,33.75 56.3022624,33.75 L33.6974504,33.75 C31.6554049,33.75 30,35.3541743 30,37.3330236 C30,38.079808 30.2407896,38.8079302 30.6887113,39.4156137 L41.9911172,54.7492883 C43.1780321,56.3595442 45.4872751,56.7325071 47.1489558,55.5823243 C47.4809703,55.3525104 47.7714424,55.0710277 48.0085956,54.7492883 Z" id="矩形" fill="#7F8B8F"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="31px" height="23px" viewBox="0 0 31 23" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 62 (91390) - https://sketch.com -->
<title>down</title>
<desc>Created with Sketch.</desc>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="1-学科键盘" transform="translate(-1779.000000, -954.000000)">
<g id="输入框">
<g id="keyboard_light_landscape" transform="translate(0.000000, 585.000000)">
<g id="编组" transform="translate(1698.750000, 26.250000)">
<g id="下翻" transform="translate(50.625000, 309.375000)">
<g>
<rect id="key-boarder" fill="#313C42" opacity="0" x="0" y="0" width="90" height="90" rx="3.76"></rect>
<path d="M48.0085956,54.7492883 L59.3110016,39.4156137 C60.4979164,37.8053578 60.1130426,35.5675801 58.4513618,34.4173974 C57.8242714,33.9833377 57.072896,33.75 56.3022624,33.75 L33.6974504,33.75 C31.6554049,33.75 30,35.3541743 30,37.3330236 C30,38.079808 30.2407896,38.8079302 30.6887113,39.4156137 L41.9911172,54.7492883 C43.1780321,56.3595442 45.4872751,56.7325071 47.1489558,55.5823243 C47.4809703,55.3525104 47.7714424,55.0710277 48.0085956,54.7492883 Z" id="矩形" fill="#7F8B8F"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="43px" height="43px" viewBox="0 0 43 43" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 62 (91390) - https://sketch.com -->
<title>delete</title>
<desc>Created with Sketch.</desc>
<g id="delete" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="删除">
<rect id="key-boarder" fill="#313C42" opacity="0" x="0.518987342" y="0.507692308" width="42" height="42" rx="2"></rect>
<path d="M31,13 L16.1,13 C15.4,13 14.8,13.3 14.4,13.9 L9,22 L14.4,30.1 C14.8,30.6 15.4,31 16.1,31 L31,31 C32.1,31 33,30.1 33,29 L33,15 C33,13.9 32.1,13 31,13 L31,13 Z M28,25.6 L26.6,27 L23,23.4 L19.4,27 L18,25.6 L21.6,22 L18,18.4 L19.4,17 L23,20.6 L26.6,17 L28,18.4 L24.4,22 L28,25.6 L28,25.6 Z" id="delete" fill-opacity="0.8" fill="#616266"></path>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="46px" height="35px" viewBox="0 0 46 35" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 62 (91390) - https://sketch.com -->
<title>delete</title>
<desc>Created with Sketch.</desc>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="1-学科键盘" transform="translate(-1768.000000, -656.000000)">
<g id="输入框">
<g id="keyboard_light_landscape" transform="translate(0.000000, 585.000000)">
<g id="编组" transform="translate(1698.750000, 26.250000)">
<g id="delete" transform="translate(50.625000, 16.875000)">
<g id="删除">
<rect id="key-boarder" fill="#313C42" opacity="0" x="0" y="0" width="90" height="90" rx="3.76"></rect>
<path d="M60.05,28.08 L32.038,28.08 C30.722,28.08 29.594,28.644 28.842,29.772 L18.69,45 L28.842,60.228 C29.594,61.168 30.722,61.92 32.038,61.92 L60.05,61.92 C62.118,61.92 63.81,60.228 63.81,58.16 L63.81,31.84 C63.81,29.772 62.118,28.08 60.05,28.08 L60.05,28.08 Z M54.41,51.768 L51.778,54.4 L45.01,47.632 L38.242,54.4 L35.61,51.768 L42.378,45 L35.61,38.232 L38.242,35.6 L45.01,42.368 L51.778,35.6 L54.41,38.232 L47.642,45 L54.41,51.768 L54.41,51.768 Z" id="delete" fill="#7F8B8F"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
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