UNPKG

ng-zorro-antd-mobile

Version:

An enterprise-class mobile UI components based on Ant Design and Angular

275 lines (270 loc) 13.4 kB
import * as i0 from '@angular/core'; import { EventEmitter, ViewContainerRef, Component, ViewChild, Input, Output, NgModule } from '@angular/core'; import * as i1 from '@angular/common'; import { CommonModule } from '@angular/common'; import * as i2 from 'ng-zorro-antd-mobile/flex'; import { FlexModule } from 'ng-zorro-antd-mobile/flex'; class ImagePickerComponent { get files() { return this._files; } set files(value) { this._files = value; this.sortItem(); } get accept() { return this._accept; } set accept(value) { this._accept = value; this.sortItem(); } get length() { return this._count; } set length(value) { if (value > 0) { this._count = value; } else { this._count = 4; } this.sortItem(); } get multiple() { return this._multiple; } set multiple(value) { this._multiple = value; this.sortItem(); } get selectable() { return this._selectable; } set selectable(value) { this._selectable = value; this.sortItem(); } constructor() { this.prefixCls = 'am-image-picker'; this.flexEl = []; this._accept = 'image/*'; this._count = 4; this._selectable = true; this._files = []; this._multiple = false; this.capture = false; this.disableDelete = false; this.onFail = new EventEmitter(); this.onChange = new EventEmitter(); this.onImageClick = new EventEmitter(); this.onAddImageClick = new EventEmitter(); } sortItem() { if (!this._files) { return; } let count = parseInt('' + this._count, 10); if (count <= 0) { count = 4; } let allEl = this._files.map(item => { return { type: 'img', backgroundImage: 'url(' + item.url + ')', transform: 'rotate(' + this.getRotation(item.orientation) + 'deg)' }; }); if (this._selectable) { allEl.push({ type: 'select', backgroundImage: '', transform: '' }); } const length = allEl.length; if (length !== 0 && length % count !== 0) { const blankCount = count - (length % count); const fillBlankEl = []; for (let i = 0; i < blankCount; i++) { fillBlankEl.push({ type: 'white', backgroundImage: '', transform: '' }); } allEl = allEl.concat(fillBlankEl); } this.flexEl = []; for (let i = 0; i < allEl.length / count; i++) { const rowEl = allEl.slice(i * count, i * count + count); this.flexEl.push(rowEl); } } addImage(imgItem) { this._files.push({ type: 'img', url: imgItem.url, orientation: imgItem.orientation }); this.sortItem(); this.onChange.emit({ files: this._files, operationType: 'add', index: this._files.length - 1 }); } removeImage(index) { this._files.splice(index, 1); this.sortItem(); this.onChange.emit({ files: this._files, operationType: 'remove', index: index }); } imageClick(index) { this.onImageClick.emit({ index: index, files: this._files }); } addImageClick(e) { this.onAddImageClick.emit(e); } parseFile(file, index) { const reader = new FileReader(); reader.onload = e => { const dataURL = e.target.result; if (!dataURL) { this.onFail.emit(`Fail to get the ${index} image`); return; } let orientation = 1; this.getOrientation(file, res => { // -2: not jpeg , -1: not defined if (res > 0) { orientation = res; } this.addImage({ url: dataURL, orientation, file }); }); }; reader.readAsDataURL(file); } fileChange(event) { const fileList = event.target.files; if (fileList && fileList.length) { for (let i = 0; i < fileList.length; i++) { this.parseFile(fileList[i], i); } } } getRotation(orientation = 1) { let imgRotation = 0; switch (orientation) { case 3: imgRotation = 180; break; case 6: imgRotation = 90; break; case 8: imgRotation = 270; break; default: } return imgRotation; } // https://stackoverflow.com/questions/7584794/accessing-jpeg-exif-rotation-data-in-javascript-on-the-client-side getOrientation(file, callback) { const reader = new FileReader(); reader.onload = e => { const view = new DataView(e.target.result); if (view.getUint16(0, false) !== 0xffd8) { return callback(-2); } const length = view.byteLength; let offset = 2; while (offset < length) { const marker = view.getUint16(offset, false); offset += 2; if (marker === 0xffe1) { const tmp = view.getUint32((offset += 2), false); if (tmp !== 0x45786966) { return callback(-1); } const little = view.getUint16((offset += 6), false) === 0x4949; offset += view.getUint32(offset + 4, little); const tags = view.getUint16(offset, little); offset += 2; for (let i = 0; i < tags; i++) { if (view.getUint16(offset + i * 12, little) === 0x0112) { return callback(view.getUint16(offset + i * 12 + 8, little)); } } } else if ((marker & 0xff00) !== 0xff00) { break; } else { offset += view.getUint16(offset, false); } } return callback(-1); }; reader.readAsArrayBuffer(file.slice(0, 64 * 1024)); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: ImagePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: ImagePickerComponent, selector: "ImagePicker, nzm-image-picker", inputs: { capture: "capture", disableDelete: "disableDelete", files: "files", accept: "accept", length: "length", multiple: "multiple", selectable: "selectable" }, outputs: { onFail: "onFail", onChange: "onChange", onImageClick: "onImageClick", onAddImageClick: "onAddImageClick" }, viewQueries: [{ propertyName: "_fileSelectorInput", first: true, predicate: ["fileSelectorInput"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<div class=\"{{ prefixCls }}-list\" role=\"group\">\n <Flex *ngFor=\"let rowItem of flexEl; let i = index\">\n <FlexItem *ngFor=\"let item of rowItem; let j = index\">\n <div *ngIf=\"item && 'img' === item.type && item.backgroundImage\" class=\"{{ prefixCls }}-item\">\n <div\n role=\"button\"\n *ngIf=\"!disableDelete\"\n aria-label=\"Click and Remove this image\"\n class=\"{{ prefixCls }}-item-remove\"\n (click)=\"removeImage(i * length + j)\"\n ></div>\n <div\n role=\"button\"\n aria-label=\"Image can be clicked\"\n class=\"{{ prefixCls }}-item-content\"\n [ngStyle]=\"{ 'background-image': item.backgroundImage, transform: item.transform }\"\n (click)=\"imageClick(i * length + j)\"\n ></div>\n </div>\n <div\n role=\"button\"\n aria-label=\"Choose and add image\"\n *ngIf=\"item && 'select' === item.type\"\n class=\"{{ prefixCls }}-item {{ prefixCls }}-upload-btn\"\n (click)=\"addImageClick($event)\"\n >\n <input\n #fileSelectorInput\n type=\"file\"\n [accept]=\"accept\"\n [multiple]=\"multiple\"\n [attr.capture]=\"capture ? capture : null\"\n (change)=\"fileChange($event)\"\n />\n </div>\n <div *ngIf=\"item && 'white' === item.type\" class=\"{{ prefixCls }}-item-white\"></div>\n </FlexItem>\n </Flex>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i2.FlexComponent, selector: "Flex, nzm-flex", inputs: ["direction", "wrap", "justify", "align", "alignContent"] }, { kind: "component", type: i2.FlexItemComponent, selector: "FlexItem, nzm-flex-item" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: ImagePickerComponent, decorators: [{ type: Component, args: [{ selector: 'ImagePicker, nzm-image-picker', template: "<div class=\"{{ prefixCls }}-list\" role=\"group\">\n <Flex *ngFor=\"let rowItem of flexEl; let i = index\">\n <FlexItem *ngFor=\"let item of rowItem; let j = index\">\n <div *ngIf=\"item && 'img' === item.type && item.backgroundImage\" class=\"{{ prefixCls }}-item\">\n <div\n role=\"button\"\n *ngIf=\"!disableDelete\"\n aria-label=\"Click and Remove this image\"\n class=\"{{ prefixCls }}-item-remove\"\n (click)=\"removeImage(i * length + j)\"\n ></div>\n <div\n role=\"button\"\n aria-label=\"Image can be clicked\"\n class=\"{{ prefixCls }}-item-content\"\n [ngStyle]=\"{ 'background-image': item.backgroundImage, transform: item.transform }\"\n (click)=\"imageClick(i * length + j)\"\n ></div>\n </div>\n <div\n role=\"button\"\n aria-label=\"Choose and add image\"\n *ngIf=\"item && 'select' === item.type\"\n class=\"{{ prefixCls }}-item {{ prefixCls }}-upload-btn\"\n (click)=\"addImageClick($event)\"\n >\n <input\n #fileSelectorInput\n type=\"file\"\n [accept]=\"accept\"\n [multiple]=\"multiple\"\n [attr.capture]=\"capture ? capture : null\"\n (change)=\"fileChange($event)\"\n />\n </div>\n <div *ngIf=\"item && 'white' === item.type\" class=\"{{ prefixCls }}-item-white\"></div>\n </FlexItem>\n </Flex>\n</div>\n" }] }], ctorParameters: () => [], propDecorators: { _fileSelectorInput: [{ type: ViewChild, args: ['fileSelectorInput', { read: ViewContainerRef }] }], capture: [{ type: Input }], disableDelete: [{ type: Input }], files: [{ type: Input }], accept: [{ type: Input }], length: [{ type: Input }], multiple: [{ type: Input }], selectable: [{ type: Input }], onFail: [{ type: Output }], onChange: [{ type: Output }], onImageClick: [{ type: Output }], onAddImageClick: [{ type: Output }] } }); class ImagePickerModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: ImagePickerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.8", ngImport: i0, type: ImagePickerModule, declarations: [ImagePickerComponent], imports: [CommonModule, FlexModule], exports: [ImagePickerComponent] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: ImagePickerModule, imports: [CommonModule, FlexModule] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: ImagePickerModule, decorators: [{ type: NgModule, args: [{ declarations: [ImagePickerComponent], exports: [ImagePickerComponent], imports: [CommonModule, FlexModule] }] }] }); /** * Generated bundle index. Do not edit. */ export { ImagePickerComponent, ImagePickerModule }; //# sourceMappingURL=ng-zorro-antd-mobile-image-picker.mjs.map