Commit 32b46ab0 authored by liujiaxin's avatar liujiaxin

1111

parent 8a51c964
......@@ -30,7 +30,10 @@
],
"styles": [
"./node_modules/ng-zorro-antd/ng-zorro-antd.min.css",
"src/styles.css"
"./node_modules/font-awesome/css/font-awesome.css",
"./node_modules/bootstrap/dist/css/bootstrap.min.css",
"./node_modules/animate.css/animate.min.css",
"src/styles.scss"
],
"scripts": []
},
......
......@@ -24,6 +24,9 @@ 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 { CustomStyleDirective } from './directives/custom-style.directive';
import { BrLineBreakerPipe } from './pipes/br-line-breaker.pipe';
import { ResizeDirective } from './directives/resize.directive';
registerLocaleData(zh);
......@@ -40,7 +43,9 @@ registerLocaleData(zh);
TimePipe,
UploadVideoComponent,
CustomHotZoneComponent,
CustomStyleDirective,
BrLineBreakerPipe,
ResizeDirective,
PlayerContentWrapperComponent
],
......
import {Directive, ElementRef, Input, OnChanges, SimpleChanges} from '@angular/core';
import * as _ from 'lodash';
@Directive({
selector: '[appCustomStyle]'
})
export class CustomStyleDirective implements OnChanges {
@Input()
customStyle;
@Input()
customStyleDirtyCount;
constructor(private el: ElementRef) {
}
ngOnChanges(changes: SimpleChanges) {
const dom = this.el.nativeElement;
// dom.style.fontFamily = this.customStyle.fontFamily;
// dom.style.color = this.customStyle.color;
_.assign(dom.style, this.customStyle);
// Object.entries(this.customStyle).forEach( ([key, value]) => {
// dom.style[key] = value;
// });
dom.style.fontSize = (this.customStyle.fontSize * 10) + 'px';
// dom.style.transform = `translate(${this.customStyle.position.left}px, ${this.customStyle.position.top}px)`;
dom.style.left = this.customStyle.position.left + 'px';
dom.style.top = this.customStyle.position.top + 'px';
}
}
import {Directive, ElementRef, EventEmitter, Output} from '@angular/core';
import {ResizeSensor} from 'css-element-queries';
import {Subject} from 'rxjs';
import {debounceTime} from 'rxjs/operators';
@Directive({
selector: '[appResize]'
})
export class ResizeDirective {
@Output()
resize = new EventEmitter();
debounce = new Subject();
constructor(private el: ElementRef) {
this.debounce
.pipe(debounceTime(100))
.subscribe(rect => {
this.resize.emit(rect);
});
const sensor = new ResizeSensor(this.el.nativeElement, (event) => {
const {clientWidth, clientHeight} = this.el.nativeElement;
this.debounce.next({clientWidth, clientHeight});
});
}
}
@import '../style/common_mixin.css';
.model-content {
width: 100%;
height: 100%;
}
<div class="model-content">
<div style="position: absolute; left: 200px; top: 100px; width: 800px;">
<input type="text" nz-input [(ngModel)]="item.text" (blur)="save()">
<app-upload-image-with-preview
[picUrl]="item.pic_url"
(imageUploaded)="onImageUploadSuccess($event, 'pic_url')"
></app-upload-image-with-preview>
<app-audio-recorder
[audioUrl]="item.audio_url"
(audioUploaded)="onAudioUploadSuccess($event, 'audio_url')"
></app-audio-recorder>
<app-custom-hot-zone></app-custom-hot-zone>
<app-upload-video></app-upload-video>
<app-lesson-title-config></app-lesson-title-config>
<div class="p-title-box">
<span class="p-title">Thumb Title</span>
<input nz-input (change)="extraData.changeDirtyCount=extraData.changeDirtyCount+1"
[(ngModel)]="item.contentObj.title"
placeholder="please enter thumb title"
/>
</div>
<div class="p-content">
<div class="p-tool-box d-flex">
<!------------------------------------------------------------------------>
<nz-select class="ml-1" style="width: 120px;" [nzDisabled]="!curItem" [(ngModel)]="fontFamily"
(ngModelChange)="onChangeFontFamily()"
nzPlaceHolder="Font Family"
[nzDropdownMatchSelectWidth]="false"
>
<nz-option [nzValue]="font" [nzLabel]="font" *ngFor="let font of fontFamilyList"></nz-option>
</nz-select>
<!------------------------------------------------------------------------>
<nz-select class="ml-1" style="width: 110px;" [nzDisabled]="!curItem" [(ngModel)]="fontSize"
(ngModelChange)="onChangeFontSize()"
nzPlaceHolder="Font Size">
<nz-option [nzValue]="i" [nzLabel]="'Size - ' + i" *ngFor="let i of fontSizeRange"></nz-option>
</nz-select>
<!------------------------------------------------------------------------>
<button class="position-relative ml-1 i-tool-font-size" nz-button [disabled]="!curItem"
(click)="onChangeFontSize(-1)">
<i class="fa fa-font"></i>
<span>-</span>
</button>
<!------------------------------------------------------------------------>
<button class="position-relative ml-1 i-tool-font-size" nz-button [disabled]="!curItem"
(click)="onChangeFontSize(1)">
<i class="fa fa-font"></i>
<span style="font-size: 13px; top: -2px;">+</span>
</button>
<div class="p-divider"></div>
<!------------------------------------------------------------------------>
<div class="i-tool-font-color d-flex" [class.p-tool-item-disable]="!curItem">
<div class="position-relative i-left flex-fill" (click)="onChangeFontColor()">
<div class="fa fa-font"></div>
<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">
<i class="anticon anticon-down"></i>
</div>
</div>
<!------------------------------------------------------------------------>
<button class="ml-2 i-tool-horizontal-center" nz-button nz-tooltip nzTitle="Horizontal Center"
[disabled]="!curItem"
(click)="onBtnMoveToCenter(true, false)"
>
<i class="fa fa-align-center"></i>
</button>
<div class="p-divider"></div>
<!------------------------------------------------------------------------>
<button class="ml-2 i-tool-delete" nz-button nzType="danger"
[disabled]="!curItem"
nz-popconfirm nzTitle="Delete ?" (nzOnConfirm)="onBtnDelete()"
>
<i class="anticon anticon-minus-circle"></i>
</button>
<div class="p-divider"></div>
<!------------------------------------------------------------------------>
<button class="ml-2 i-tool-bg-color" nz-button nzPlacement="bottom"
nz-popover [(nzVisible)]="isShowBGColorPane" nzTrigger="click"
[nzContent]="colorPane">
BG <span class="i-color" [style.background-color]="item.contentObj.bgColor"></span>
</button>
<!------------------------------------------------------------------------>
<button class="ml-2 i-tool-animation" nz-button
(click)="onBtnShowAnimationPane()"
[style.color]="isShowAnimationPane ? '#1585ff' : ''"
[style.border-color]="isShowAnimationPane ? '#1585ff' : ''"
>
<i class="fa fa-fighter-jet"></i>
</button>
<!------------------------------------------------------------------------>
<div class="flex-fill"></div>
<!------------------------------------------------------------------------>
<button class="ml-2 i-tool-restore" nz-button nzType="danger"
[disabled]="extraData.changeDirtyCount==0"
nz-popconfirm nzTitle="Remove ALL changes ?" (nzOnConfirm)="onBtnRestore()"
>
<i class="fa fa-reply"></i>
<span class="ml-1" *ngIf="extraData.changeDirtyCount > 0">Restore</span>
</button>
<!------------------------------------------------------------------------>
<div class="flex-fill"></div>
<!------------------------------------------------------------------------>
<button class="ml-1 i-tool-save" nz-button nzType="primary"
(click)="onBtnSave()"
[disabled]="extraData.changeDirtyCount==0">
<i class="anticon anticon-inbox"></i>
<span *ngIf="extraData.changeDirtyCount > 0">Save</span>
</button>
</div>
<div class="width-100 d-flex">
<div class="k-16-9" appResize (resize)="resize($event)">
<div class="position-absolute p-box" #box tabindex="1"
(click)="onClickBox()"
(dblclick)="onNewSentence($event)"
(mousemove)="onMouseMove($event)"
(mouseup)="onMouseUp($event)"
(keydown.ArrowUp)="onMoveSentence(0, -10, $event)"
(keydown.ArrowDown)="onMoveSentence(0, 10, $event)"
(keydown.ArrowLeft)="onMoveSentence(-10, 0, $event)"
(keydown.ArrowRight)="onMoveSentence(10, 0, $event)"
[style.background-color]="item.contentObj.bgColor"
>
<div class="position-absolute p-sentence"
*ngFor="let item of item.contentObj.items; index as i;"
#list
[class.p-selected]="curItem===item"
appCustomStyle [customStyle]="item"
[customStyleDirtyCount]="extraData.changeDirtyCount"
(blur)="onBlur(item, $event.target);"
(dblclick)="onEdit(item, $event)"
(click)="onSelect(item, $event)"
(mousedown)="onMouseDown(item, $event)"
[innerHTML]="item.text | brLineBreaker"
>
</div>
<div class="p-animation-index-box" *ngIf="isShowAnimationPane">
<ng-container *ngFor="let item of item.contentObj.items; index as i;">
<div class="i-animation-index"
*ngIf="isShowAnimationOrder && getIndexOfAnimationByItem(item) > -1"
[style.left]="item.position.left - item.fontSize*8 - 20 + 'px'"
[style.top]="item.position.top + item.fontSize*10/2 + 'px'"
>
{{getIndexOfAnimationByItem(item) + 1}}
</div>
</ng-container>
</div>
<div class="position-absolute k-full-fill p-user-guide"
*ngIf="item.contentObj.items.length === 0">
Double click on the board to create a text
</div>
</div>
</div>
<div *ngIf="isShowAnimationPane" class="p-animation-box">
<nz-radio-group class="p-animation-label" [(ngModel)]="curAnimationName">
<label nz-radio-button [nzValue]="item.value"
(click)="onSetAnimation(item)"
*ngFor="let item of AnimationType">
<span>{{item.name}}</span>
</label>
</nz-radio-group>
<div class="animated-demo-text infinite {{curAnimationName}}">animation demo</div>
<div class="i-toolbox d-flex">
<div class="flex-fill"></div>
<div (click)="onBtnToggleDisplayAnimationOrder()">
<i class="anticon anticon-eye" [style.color]="isShowAnimationOrder ? '' : 'red'"></i>
</div>
<div (click)="onBtnMoveAnimation(-1)">
<i class="anticon anticon-arrow-up"></i>
</div>
<div (click)="onBtnMoveAnimation(1)">
<i class="anticon anticon-arrow-down"></i>
</div>
<div (click)="onBtnRemoveAnimation()">
<i class="anticon anticon-close"></i>
</div>
</div>
<div class="p-animation-list">
<div class="p-animation-item" [class.i-active]="selectedAnimation===item"
(click)="onClickAnimation(item)"
*ngFor="let item of animations; index as i"
>
<div>{{i + 1}}.</div>
<div class="flex-fill text-center"> {{item.name}}</div>
</div>
</div>
</div>
</div>
</div>
<ng-template #colorPane>
<div class="p-color-pane" nz-row nzGutter="16" nzType="flex">
<div nz-col class="p-color-item" *ngFor="let color of colorList"
[style.background-color]="color"
(click)="onChangeColor(color)"
>
</div>
</div>
</ng-template>
@import '../style/mixin';
@mixin tool-btn {
border: 1px solid #ddd;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
outline: none;
border-radius: 6px;
color: #555;
}
.p-title-box {
.p-title {
font-size: 20px;
}
input {
width: 300px;
margin-left: 10px;
}
}
.p-content {
border: 1px solid #ddd;
box-shadow: 0 0 8px #eee;
margin-top: 10px;
}
.p-divider {
border-left: 1px solid #ccc;
margin: 5px 8px;
height: 85%;
}
.p-tool-box {
background-color: #efefef;
padding: 2px;
height: 37px;
display: flex;
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;
}
// font-color
.i-tool-font-color {
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 {
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;
}
}
.i-dropdown-menu {
width: 15px;
font-size: 10px;
border-left: 1px solid #ddd;
display: flex;
align-items: center;
.anticon-down {
transform: scale(0.6);
}
}
}
// 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;
}
}
// animation
.i-tool-animation {
}
// restore
.i-tool-restore {
}
// horizontal-center
.i-tool-horizontal-center {
@include tool-btn();
width: 37px;
}
// delete
.i-tool-delete {
}
}
.p-box {
width: 1280px;
height: 720px;
left: 0;
top: 0;
transform-origin: top left;
overflow: hidden;
}
.p-sentence {
@include k-no-select();
}
.p-animation-index-box {
.i-animation-index {
position: absolute;
font-size: 34px;
font-family: Arial;
border: 1px solid #ddd;
border-radius: 4px;
min-width: 50px;
min-height: 50px;
display: flex;
align-items: center;
justify-content: center;
background-color: darkorange;
color: white;
}
}
.p-edit {
background-color: white;
border: 1px solid black;
padding: 2px 15px;
}
.p-selected {
border: 1px solid darkorange;
box-shadow: 0 0 8px #ddd;
}
.p-tool-item-disable {
color: rgba(0, 0, 0, .25) !important;
background-color: transparent !important;
pointer-events: none;
}
// -----------
.p-color-pane {
width: 105px;
.p-color-item {
width: 17px;
height: 17px;
cursor: pointer;
margin: 4px;
border: 1px solid #bbb;
}
.p-color-item-active {
border: 1px solid white;
transform: scale(1.1);
}
}
.p-user-guide {
font-size: 40px;
display: flex;
justify-content: center;
align-items: center;
}
.p-animation-box {
width: 400px;
background-color: #efefef;
border-left: 1px solid #ddd;
padding: 10px;
text-align: center;
.p-animation-label {
z-index: 1;
position: relative;
}
::ng-deep .ant-radio-button-wrapper {
padding: 0 10px;
@include k-no-select();
}
.i-toolbox {
& > div {
font-size: 20px;
cursor: pointer;
color: #555;
padding: 0 3px;
margin: 0 5px;
}
& > div:hover {
color: #1585ff;
transform: scale(1.1);
}
}
.p-animation-list {
background-color: white;
border-radius: 10px;
height: calc(100% - 86px);
overflow-y: auto;
.p-animation-item {
padding: 0 20px;
background-color: aliceblue;
margin-top: 6px;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
cursor: pointer;
text-align: left;
display: flex;
@include k-no-select();
}
.i-active {
background-color: antiquewhite;
}
}
}
This diff is collapsed.
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
name: 'brLineBreaker'
})
export class BrLineBreakerPipe implements PipeTransform {
transform(value: any, args?: any): any {
return value ? value.replace(/\n/g, '<br />') : '';
}
}
.game-container {
width: 100%;
height: 100%;
background: #ffffff;
background-size: cover;
}
#canvas {
}
@font-face
{
font-family: 'BRLNSDB';
src: url("../../assets/font/BRLNSDB.TTF") ;
}
<div class="game-container" #wrap>
<canvas id="canvas" #canvas></canvas>
<div class="k-full-fill p-content"
[style.background-color]="data.contentObj.bgColor"
(click)="playNextAnimation($event)"
>
<div class="k-16-9" appResize (resize)="resize($event)">
<div class="position-absolute p-box" #box
>
<div class="position-absolute p-sentence {{item.animationClass}}" id="i-sentence-{{item.id}}"
*ngFor="let item of data.contentObj.items; index as i;"
#list
appCustomStyle [customStyle]="item">
<span class="text" [innerHTML]="item.text | brLineBreaker" (click)="playOutAnimation($event, item)"></span>
</div>
</div>
</div>
</div>
@import '../style/mixin';
.p-content {
padding: 0vh 2vh;
display: flex;
justify-content: center;
align-items: center;
}
.p-box {
width: 1280px;
height: 720px;
left: 0;
top: 0;
transform-origin: top left;
overflow: hidden;
}
.p-sentence {
@include k-no-select();
text-align: left;
}
This diff is collapsed.
@mixin hide-overflow-text {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
@mixin k-no-select {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
@mixin k-img-bg {
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}
/* You can add global styles to this file, and also import other style files */
/* You can add global styles to this file, and also import other style files */
/* You can add global styles to this file, and also import other style files */
/* You can add global styles to this file, and also import other style files */
/* You can add global styles to this file, and also import other style files */
html, body {
width: 100%;
height: 100%;
font-size: 16px;
}
body {
background-color: #f0f2f5 !important;
}
* {
outline: none;
}
@font-face {
font-family: ChalkboardSE-Regular;
src: url('/assets/font/ChalkboardSE-Regular.woff') format('WOFF');
}
.k-16-9 {
position: relative;
width: 100%;
height: fit-content;
&:before {
content: "";
display: block;
position: relative;
width: 100%;
height: 0;
padding-bottom: 56.25%;
}
}
.k-full-fill {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.k-flex-center {
display: flex;
align-items: center;
justify-content: center;
}
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