Commit c5d50883 authored by liujiangnan's avatar liujiangnan

feat: 迁移完成

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": []
},
......@@ -128,5 +131,8 @@
}
}
},
"defaultProject": "ng-template-generator"
}
"defaultProject": "ng-template-generator",
"cli": {
"analytics": "8ca51870-a656-4ecd-b690-b4d8a6790b2d"
}
}
\ No newline at end of file
......@@ -24,6 +24,7 @@ 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 { BrLineBreakerPipe } from './pipes/br-line-breaker.pipe';
registerLocaleData(zh);
......@@ -36,6 +37,7 @@ registerLocaleData(zh);
AudioRecorderComponent,
UploadImageWithPreviewComponent,
BackgroundImagePipe,
BrLineBreakerPipe,
ResourcePipe,
TimePipe,
UploadVideoComponent,
......
@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="picture-group">
<div *ngFor="let group of groups; let gi = index">
<div nz-row>
<div nz-col [nzXs]="24">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" >Group Name</span>
</div>
<input type="text" class="form-control"
aria-label="group"
[ngModel]="group.name"
(blur)="updateGroupText($event, group)"
aria-describedby="group">
<div class="input-group-append">
<button class="btn btn-outline-primary"
(click)="addNewOptionItem(gi)">Add</button>
</div>
</div>
</div>
</div>
<div nz-row class="opt-container">
<div nz-col style="width: 19.9%" *ngFor="let item of group.options; let i = index">
<div class="opt-wrap" >
<div class="tool-bar" style="margin-bottom: .6rem;">
<div class="button-group">
<button
nz-button
nzType="primary"
nzSize="small"
nzShape="circle"
style="margin-right: 1rem;"
(click)="onHandleSwitchContent(gi, item)"
>
<i class="anticon anticon-retweet"></i>
</button>
<button nz-button
nzType="primary"
nzSize="small"
nzShape="circle"
(click)="onDeleteCoursewareItem(gi, i)">
<i class="anticon anticon-delete"></i>
</button>
</div>
</div>
<div class="content-editor">
<input *ngIf="item.showText" type="text" nz-input
[ngModel]="item.text"
(blur)="updateOptionItemText($event, item)">
<app-upload-image-with-preview
*ngIf="item.showPic"
[picUrl]="item.pic_id"
(imageUploaded)="onHandleOptionItemImage(gi, $event, i)"
></app-upload-image-with-preview>
</div>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
.picture-group{
padding: 2rem;
::ng-deep .p-image-uploader .p-box .p-upload-icon .anticon-upload {
font-size: 5vw!important;
}
.opt-container {
width: 100%;
display: flex;
flex-wrap: wrap;
.button-group{
display: contents;
}
.opt-wrap {
margin: 0 1rem 1rem 0;
display: flex;
flex-direction: column;
//height: 14rem;
//width: 20rem;
border: 2px dashed #ddd;
border-radius: 0.5rem;
padding: 0.8rem;
.tool-bar {
display: flex;
justify-content: space-between;
align-items: center;
}
.content-editor {
height: 100%;
}
}
}
.disabled {
pointer-events: none;
opacity: 0.6;
}
}
import {Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, ApplicationRef, ChangeDetectorRef} from '@angular/core';
import {NzMessageService, NzModalService} from 'ng-zorro-antd';
import * as _ from 'lodash';
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.css']
styleUrls: ['./form.component.scss']
})
export class FormComponent implements OnInit, OnChanges, OnDestroy {
// 储存数据用
saveKey = "test_0011";
saveKey = 'picture-group';
// 储存对象
item;
groups: Array<{
name: string,
options: Array<{
text: string,
pic_id: number,
showText: boolean,
showPic: boolean
}>
}>;
constructor(private appRef: ApplicationRef,private changeDetectorRef: ChangeDetectorRef) {
constructor(private appRef: ApplicationRef,
private changeDetectorRef: ChangeDetectorRef,
private modalService: NzModalService,
private nzMessageService: NzMessageService,) {
}
ngOnInit() {
this.item = {};
this.item = {
contentObj: {
}
};
// 获取存储的数据
(<any> window).courseware.getData((data) => {
(window as any).courseware.getData((data) => {
if (data) {
this.item = data;
}
......@@ -42,40 +58,109 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
ngOnChanges() {
this.init();
}
ngOnDestroy() {
}
init() {
if (!this.item.contentObj.groups) {
this.groups = [
{name: '', options: []},
{name: '', options: []}
];
} else {
this.groups = this.item.contentObj.groups;
}
}
/**
* 储存图片数据
* @param e
*/
onImageUploadSuccess(e, key) {
this.item[key] = e.url;
this.save();
onHandleSwitchContent(groupIndex, item) {
item.showText = !item.showText;
item.showPic = !item.showPic;
this.item.contentObj.groups = this.groups;
this.save();
}
/**
* 储存音频数据
* @param e
*/
onAudioUploadSuccess(e, key) {
this.item[key] = e.url;
onDeleteCoursewareItem(groupIndex, index) {
this.modalService.confirm({
nzTitle: 'Are you sure delete this?',
nzOkText: 'Yes',
nzOkType: 'danger',
nzCancelText: 'No',
nzOnOk: () => {
this.groups[groupIndex].options.splice(index, 1);
this.item.contentObj.groups = this.groups;
this.save();
},
});
}
onHandleOptionItemImage(groupIndex, e, index) {
this.groups[groupIndex].options[index].pic_id = e.url;
this.item.contentObj.groups = this.groups;
this.save();
}
addNewOptionItem (groupIndex) {
const content = {
text: '',
pic_id: 0,
showText: true,
showPic: false
};
if (!this.groups) {
this.groups = [];
}
let group = _.get(this.groups, groupIndex, null);
if (!group || group.constructor.name !== 'Object') {
group = {
name: '',
options: []
};
this.groups[groupIndex] = group;
}
let options = _.get(this.groups[groupIndex] , 'options', null);
if (!options || options.constructor.name !== 'Array') {
options = [];
this.groups[groupIndex].options = options;
}
if (this.groups[groupIndex].options.length === 5) {
this.nzMessageService.info('you can only add five items!')
return;
}
this.groups[groupIndex].options.push(content);
this.updateOptionItemText();
}
updateGroupText(evt?: {target: {value: ''}}, group?: {name: ''}) {
let u = true;
if (evt ) {
if (evt.target.value === group.name) {
u = false;
} else {
group.name = evt.target.value;
}
}
this.item.contentObj.groups = this.groups;
if (u) {
this.save();
}
}
updateOptionItemText(evt?: {target: {value: ''}}, item?: {text: ''}) {
let u = true;
if (evt ) {
if (evt.target.value === item.text) {
u = false;
} else {
item.text = evt.target.value;
}
}
this.item.contentObj.groups = this.groups;
if (u) {
this.save();
}
}
/**
* 储存数据
*/
......
import {Pipe, PipeTransform} from '@angular/core';
// import {ElectronUtil} from '../util/ElectronUtil';
declare const APP_PATH;
// const isInElectron = localStorage.getItem('electron');
@Pipe({
name: 'backgroundImage'
})
export class BackgroundImagePipe implements PipeTransform {
transform(value: any, coursewareSid?: string) {
// const ret = value ? `url(${value})` : '';
const ret = value ? `url(${value})` : '';
return ret;
// let ret = value > 0 ? `url(/api/media-resource/${value}/file)` : '';
// if (isInElectron && ElectronUtil.hasCached(coursewareSid, value)) {
// ret = `url(file://${APP_PATH}/courseware_cache/${coursewareSid}/${value})`;
// }
// return ret;
transform(value: any) {
return `url(${value})`;
}
}
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 />') : '';
}
}
......@@ -2,25 +2,17 @@ import {Pipe, PipeTransform} from '@angular/core';
// import {ElectronUtil} from '../util/ElectronUtil';
declare const APP_PATH;
// const isInElectron = localStorage.getItem('electron');
const isInElectron = localStorage.getItem('electron');
@Pipe({
name: 'resource'
})
export class ResourcePipe implements PipeTransform {
transform(pic_url: any, coursewareSid?: string): string {
// return pic_url;
if (pic_url && typeof pic_url === 'object') {
return pic_url;
}
// console.log('resource', pic_url)
return `${pic_url}?t=${Math.random()}`;
// let ret = value ? `/api/resource/${value}/file` : '';
// let ret = res_id ? `/resource/audio/${res_id}` : '';
// if (isInElectron && ElectronUtil.hasCached(coursewareSid, res_id)) {
// ret = `file://${APP_PATH}/courseware_cache/${coursewareSid}/${res_id}`;
transform(value: any, coursewareSid?: string): string {
return value ? `/api/media-resource/${value}/file` : '';
// if (isInElectron && ElectronUtil.hasCached(coursewareSid, value)) {
// ret = `file://${APP_PATH}/courseware_cache/${coursewareSid}/${value}`;
// }
// return ret;
}
......
.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="player-picture-group">
<div class="group g1" [style.height]="_HEIGHT">
<div [ngClass]="{'group-box': true}"
(click)="selectGroup(0, $event)">
<div class="group-label">{{data.contentObj.groups[0] ? data.contentObj.groups[0].name : ''}}</div>
<div class="row" style="margin: 0 3vh;">
<div col-sm [style.width]="_WIDTH" class="item-box"
*ngFor="let item of result[0]; let i = index">
<div class="item">
<div *ngIf="item.showText" class="display-item">{{item.text}}</div>
<div *ngIf="item.showPic" class="display-item">
<img [src]="item.pic_id" alt="">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="group g2" [style.height]="_HEIGHT">
<div [ngClass]="{'group-box': true}"
(click)="selectGroup(1, $event)">
<div class="group-label">{{data.contentObj.groups[1] ? data.contentObj.groups[1].name : ''}}</div>
<div class="row" style="margin: 0 3vh;">
<div col-sm [style.width]="_WIDTH" class="item-box"
*ngFor="let item of result[1]; let i = index">
<div class="item">
<div *ngIf="item.showText" class="display-item">{{item.text}}</div>
<div *ngIf="item.showPic" class="display-item">
<img [src]="item.pic_id" alt="">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="pics container" #itemsContainer>
<div class="row" >
<ng-container>
<div col-sm [style.width]="_WIDTH" class="item-box"
*ngFor="let item of options; let i = index">
<div class="item" (click)="selectItem(item, $event)">
<div *ngIf="item.showText" class="display-item">{{item.text}}</div>
<div *ngIf="item.showPic" class="display-item">
<img [src]="item.pic_id" alt="">
</div>
</div>
</div>
</ng-container>
</div>
</div>
</div>
.player-picture-group {
padding: 2vh 5vh;
width: 100%;
height: 100%;
background-size: 100%;
background-position-y: 18.4%;
background-image: url('../../assets/common_bg.jpg');
.group{
height: 29.5%;
overflow: hidden;
.group-box {
cursor: pointer;
width: 100%;
height: 95%;
border-radius: 4vh;
background: rgba(255,255,255,.5);
display: flex;
flex-direction: column;
//padding-bottom: 1vh;
.item{
justify-content: center;
align-items: center;
display: flex;
.item-bg{
position: absolute;
max-height: 100%;
max-width: 100%;
//height: 100%;
}
.item-pic{
height: 70%;
z-index: 1;
position: absolute;
}
}
.group-label{
font-size: 4.5vh;
text-align: left;
padding-left: 3vh;
font-weight: 900;
font-family: ChalkboardSE-Regular;
line-height: 5.5vh;
}
}
}
.pics{
height: 41%;
//overflow: hidden;
}
.item-box{
padding: .3vh;
display: flex;
justify-content: center;
align-items: center;
user-select: none;
.item{
cursor: pointer;
position: relative;
padding-bottom: 65%;
background-size: 100%;
background-position: 50%;
background-image: url('../../assets/picture-group/item-bg.png');
background-repeat: no-repeat;
width: 90%;
.display-item{
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
font-family: ChalkboardSE-Regular;
font-size: 3vh;
max-width: 100%;
max-height: 100%;
//width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
img{
//width: auto;
//max-width: 100%;
width: unset;
height: auto;
max-height: 70%;
}
}
}
}
.item-box.selected {
//transform: scale(1.2);
//transition-duration: .5s;
animation: zooming 1s infinite
}
.group-box.selected {
}
@keyframes zooming {
0% {transform: scale(1);}
50% {transform: scale(1.2);}
100% {transform: scale(1);}
}
}
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;
}
@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;
}
......@@ -3,6 +3,8 @@ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
if (environment.production) {
enableProdMode();
......
/* 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 */
@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;
}
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