From d8b62a10cc2237abc7787b56cf7be8cb10ae3d9a Mon Sep 17 00:00:00 2001 From: lmz <limingzhe@iplayabc.com> Date: Fri, 27 Sep 2019 14:05:25 +0800 Subject: [PATCH] add upload-image-width-preview --- src/app/app.component.ts | 8 +- src/app/app.module.ts | 18 ++- .../upload-image-with-preview.component.html | 37 +++++ .../upload-image-with-preview.component.scss | 101 ++++++++++++ .../upload-image-with-preview.component.ts | 149 ++++++++++++++++++ src/app/pipes/background-image.pipe.ts | 23 +++ src/index.html | 8 +- tslint.json | 9 +- 8 files changed, 338 insertions(+), 15 deletions(-) create mode 100644 src/app/common/upload-image-with-preview/upload-image-with-preview.component.html create mode 100644 src/app/common/upload-image-with-preview/upload-image-with-preview.component.scss create mode 100644 src/app/common/upload-image-with-preview/upload-image-with-preview.component.ts create mode 100644 src/app/pipes/background-image.pipe.ts diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 9ffb6bc..c918314 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,4 +1,4 @@ -import { Component ,OnInit} from '@angular/core'; +import { Component , OnInit} from '@angular/core'; @Component({ selector: 'app-root', @@ -6,11 +6,11 @@ import { Component ,OnInit} from '@angular/core'; styleUrls: ['./app.component.scss'] }) export class AppComponent implements OnInit{ - type = 'play'; + type = 'play'; - constructor() { + constructor() { let tp = this.getQueryString("type"); - if(tp){ + if (tp){ this.type = tp; } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index ebea714..7d45083 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -3,20 +3,24 @@ 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 { 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 { 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'; +import { PlayerContentWrapperComponent } from './common/player-content-wrapper/player-content-wrapper.component'; /** é…ç½® angular i18n **/ import { registerLocaleData } from '@angular/common'; import zh from '@angular/common/locales/zh'; +import {UploadImageWithPreviewComponent} from "./common/upload-image-with-preview/upload-image-with-preview.component"; +import {BackgroundImagePipe} from "./pipes/background-image.pipe"; registerLocaleData(zh); @NgModule({ @@ -26,15 +30,19 @@ registerLocaleData(zh); PlayComponent, LessonTitleConfigComponent, AudioRecorderComponent, + UploadImageWithPreviewComponent, + BackgroundImagePipe, + PlayerContentWrapperComponent ], - imports: [ + imports: [ FormsModule, HttpClientModule, BrowserAnimationsModule, BrowserModule, Angular2FontawesomeModule, - NgZorroAntdModule + NgZorroAntdModule, + ], /** é…ç½® ng-zorro-antd 国际化(文案 åŠ æ—¥æœŸï¼‰ **/ providers : [ diff --git a/src/app/common/upload-image-with-preview/upload-image-with-preview.component.html b/src/app/common/upload-image-with-preview/upload-image-with-preview.component.html new file mode 100644 index 0000000..5fdf4f1 --- /dev/null +++ b/src/app/common/upload-image-with-preview/upload-image-with-preview.component.html @@ -0,0 +1,37 @@ +<div class="position-relative"> + <nz-upload class="p-image-uploader" [nzDisabled]="disableUpload" + [nzShowUploadList]="false" + nzAccept = "image/*" + [nzAction]="uploadUrl" + [nzData]="uploadData" + (nzChange)="handleChange($event)"> + <!--[nzBeforeUpload]="customUpload">--> + <div class="p-box d-flex align-items-center"> + <div class="p-upload-icon" *ngIf="!picUrl && !uploading"> + <i nz-icon type="cloud-upload" theme="outline" [style.font-size]="iconSize + 'em'"></i> + <div class="m-3"></div> + <span>{{TIP}}</span> + <!--<div class="mt-5 p-progress-bar" *ngIf="uploading">--> + <!--<div class="p-progress-bg" [style.width]="progress*0.2+'rem'"></div>--> + <!--<div class="p-progress-value">{{progress}}%</div>--> + <!--</div>--> + </div> + <div class="p-upload-progress-bg" *ngIf="uploading"> + <div class="i-bg" [style.width]="progress+'%'"></div> + <div class="i-text"> + <fa name="cloud-upload"></fa> + Uploading... + </div> + </div> + <div class="p-preview" *ngIf="!uploading && picUrl " + [style.background-image]="picUrl | backgroundImage "> + </div> + </div> + </nz-upload> + <div class="p-btn-delete" *ngIf="canDelete" + nz-popconfirm nzTitle="Are you sure ?" + (nzOnConfirm)="onDelete()" + > + <i nz-icon type="close" theme="outline"></i> + </div> +</div> diff --git a/src/app/common/upload-image-with-preview/upload-image-with-preview.component.scss b/src/app/common/upload-image-with-preview/upload-image-with-preview.component.scss new file mode 100644 index 0000000..6008c35 --- /dev/null +++ b/src/app/common/upload-image-with-preview/upload-image-with-preview.component.scss @@ -0,0 +1,101 @@ +@import '../../style/common_mixin'; + +.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-image: url("https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"); + @include k-img-bg(); + } + } +} + +.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; + } +} + + +:host ::ng-deep .ant-upload { + display: block; +} diff --git a/src/app/common/upload-image-with-preview/upload-image-with-preview.component.ts b/src/app/common/upload-image-with-preview/upload-image-with-preview.component.ts new file mode 100644 index 0000000..88aa192 --- /dev/null +++ b/src/app/common/upload-image-with-preview/upload-image-with-preview.component.ts @@ -0,0 +1,149 @@ +import {Component, EventEmitter, Input, OnChanges, OnDestroy, Output} from '@angular/core'; +import { NzMessageService, UploadXHRArgs, UploadFile } from 'ng-zorro-antd'; + + +@Component({ + selector: 'app-upload-image-with-preview', + templateUrl: './upload-image-with-preview.component.html', + styleUrls: ['./upload-image-with-preview.component.scss'] +}) +export class UploadImageWithPreviewComponent implements OnDestroy, OnChanges { + uploading = false; + progress = 0; + @Input() + picUrl; + @Input() + canDelete = false; + @Output() + imageUploaded = new EventEmitter(); + @Output() + imageUploadFailure = new EventEmitter(); + @Output() + delete = new EventEmitter(); + @Input() + picItem = null; + @Input() + iconSize = 2; + @Input() + TIP = 'Click here to upload image'; + @Input() + disableUpload = false; + + uploadUrl = (<any> window).courseware.uploadUrl(); + uploadData = (<any> window).courseware.uploadData(); + + constructor(private nzMessageService: NzMessageService) { + } + ngOnChanges() { + if (!this.picItem) { + return; + } + } + + + + + + handleChange(info: { type: string, file: UploadFile, event: any }): void { + + console.log('info:' , info); + + switch (info.type) { + case 'start': + // this.isUploading = true; + // this.progress = 0; + + this.picUrl = null; + // this.beforeUpload(item.file as any); + if (!this.checkSelectFile(info.file)) { + return; + } + this.uploading = true; + this.progress = 0; + + break; + + case 'success': + // this.isUploading = false; + // this.uploadSuccess(info.file.response); + // this.audioUploaded.emit(info.file.response); + + this.uploadSuccess(info.file); + + break; + case 'progress': + this.progress = parseInt(info.event.percent, 10); + this.doProgress(this.progress); + break; + } + } + + onDelete() { + this.delete.emit(); + } + checkSelectFile(file) { + const isImg = ['image/jpeg', 'image/png', 'image/jpeg', 'image/gif', 'image/bmp'].includes(file.type); + if (!isImg) { + this.nzMessageService.error('You can only upload Image file (jpg|gif|png|bmp)'); + return false; + } + const isGif = !['image/jpeg', 'image/png', 'image/jpeg', 'image/bmp'].includes(file.type); + const delta = isGif ? 20 : 5; + const isOverSize = file.size / 1024 / 1024 < delta; + if (!isOverSize) { + this.nzMessageService.error(`${isGif ? 'Gif' : 'Image'} must smaller than ${delta}MB!`); + return false; + } + return true; + } + + uploadSuccess = (file) => { + this.nzMessageService.info('Upload Success'); + this.uploading = false; + this.picUrl = file.response.url ; + // this.uploadFinished(url); + // if (!inOSS) { + 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); + // this.resService.updateImage(id, {width, height}).then( () => { + // this.imageUploaded.emit({res_id: id, id, name, hash, url}); + // }); + + }); + img.src = file.response.url; + // } else { + // this.imageUploaded.emit({res_id: id, id, name, hash, url}); + // } + } + + uploadFailure = (err, file) => { + this.uploading = false; + if (err.name && err.name === 'cancel') { + return; + } + console.log(err); + this.nzMessageService.error('Upload Error ' + err.message); + this.imageUploadFailure.emit(file); + } + + doProgress = function(p) { + if (p > 1) { + p = 1; + } + if (p < 0) { + p = 0; + } + // console.log(Math.floor(p * 100)); + this.progress = Math.floor(p * 100); + } + ngOnDestroy() { + } + +} diff --git a/src/app/pipes/background-image.pipe.ts b/src/app/pipes/background-image.pipe.ts new file mode 100644 index 0000000..bc15f66 --- /dev/null +++ b/src/app/pipes/background-image.pipe.ts @@ -0,0 +1,23 @@ +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; + } + +} diff --git a/src/index.html b/src/index.html index 3e1848f..df57d46 100644 --- a/src/index.html +++ b/src/index.html @@ -33,7 +33,7 @@ } }); }, - setData: function(data,callback){ + setData: function(data,callback){ let str = JSON.stringify(data); net.getData("setCoursewareData",{id: id,data: str},function(res){ if(res){ @@ -58,7 +58,7 @@ } else { return { getData: function(callback){ - let data = localStorage.getItem("courseware_data"); + let data = localStorage.getItem("courseware_data"); if(data){ data = JSON.parse(data); } @@ -70,10 +70,10 @@ callback&&callback(); }, uploadUrl: function(){ - return ""; + return 'http://localhost:3000/api/test'; }, uploadData: function(){ - return ""; + return {}; } } } diff --git a/tslint.json b/tslint.json index f0adae9..f29eef2 100644 --- a/tslint.json +++ b/tslint.json @@ -62,6 +62,9 @@ "no-switch-case-fall-through": true, "no-use-before-declare": true, "no-var-requires": false, + + "no-shadowed-variable": false, + "object-literal-key-quotes": [ true, "as-needed" @@ -84,9 +87,11 @@ "template-banana-in-box": true, "template-no-negated-async": true, "use-lifecycle-interface": true, - "use-pipe-transform-interface": true + "use-pipe-transform-interface": true, + "no-trailing-whitespace": false, + "variable-name": false }, "rulesDirectory": [ "codelyzer" ] -} \ No newline at end of file +} -- 2.21.0