UNPKG

4.05 kBJavaScriptView Raw
1
2import { BunnyFile } from './file/file';
3import { BunnyImage } from "./file/image";
4import { Modal } from './Modal';
5import { ImageProcessor } from './ImageProcessor';
6
7export const ImageUploadConfig = {
8
9 tagName: 'imageupload',
10
11 attrQuality: 'quality',
12 defaultQuality: 0.7,
13 attrOutputSize: 'outputsize',
14 defaultOutputSize: '300',
15 attrFormat: 'format',
16 defaultFormat: 'png',
17
18};
19
20export const ImageUpload = {
21
22 Config: ImageUploadConfig,
23
24 init(imgupl) {
25 const img = this.getImagePreview(imgupl);
26 img._src = img.src;
27 this.addEvents(imgupl);
28 },
29
30 initAll(container = document) {
31 [].forEach.call(this.getAll(container), imgupl => {
32 this.init(imgupl);
33 });
34 },
35
36 addEvents(imgupl) {
37 const input = this.getFileInput(imgupl);
38 const modal = this.getModal(imgupl);
39 const processor = this.getImageProcessor(imgupl);
40 const img = this.getImagePreview(imgupl);
41
42 input.addEventListener('change', e => {
43 if (modal !== false) {
44 Modal.show(modal);
45 } else {
46 // instant image processing with auto crop/resize
47 this.setImage(imgupl, input.files[0]);
48 }
49 });
50
51 img.addEventListener('click', () => {
52 input.click();
53 });
54 img.addEventListener('keypress', (e) => {
55 if (e.keyCode === KEY_ENTER) {
56 input.click();
57 }
58 });
59
60 if (modal !== false) {
61 Modal.onShow(modal, () => {
62 ImageProcessor.setOutputSize(processor, this.getOutputSize(imgupl));
63 ImageProcessor.setQuality(processor, this.getQuality(imgupl));
64 ImageProcessor.init(processor, input.files[0], (src) => {
65 Modal.hide(modal);
66 img.src = src;
67 input._file = BunnyFile.base64ToBlob(src);
68 });
69 });
70
71 Modal.onHide(modal, () => {
72 ImageProcessor.deinit(processor);
73 });
74 }
75
76 // if reset button clicked or form.reset() called from JS - clear custom logic also
77 input.form.addEventListener('reset', (e) => {
78 img.src = img._src; // restore to default image
79 delete input._file;
80 });
81
82 if (input.files.length > 0) {
83 // after refresh photo is still in the input
84 this.setImage(imgupl, input.files[0]);
85 }
86 },
87
88 getQuality(imgupl) {
89 let q = imgupl.getAttribute(this.Config.attrQuality);
90 if (q) {
91 q = parseFloat(q);
92 } else {
93 q = this.Config.defaultQuality;
94 }
95 return q;
96 },
97
98 getOutputSize(imgupl) {
99 let s = imgupl.getAttribute(this.Config.attrOutputSize);
100 if (s) {
101 s = parseFloat(s);
102 } else {
103 s = this.Config.defaultOutputSize;
104 }
105 return s;
106 },
107
108 getFormat(imgupl) {
109 let s = imgupl.getAttribute(this.Config.attrFormat);
110 if (!s) {
111 s = this.Config.defaultFormat;
112 }
113 return s;
114 },
115
116 getAll(container = document) {
117 return container.getElementsByTagName(this.Config.tagName);
118 },
119
120 getFileInput(imgupl) {
121 return imgupl.getElementsByTagName('input')[0] || false;
122 },
123
124 getImagePreview(imgupl) {
125 return imgupl.getElementsByTagName('img')[0] || false;
126 },
127
128 getModal(imgupl) {
129 return Modal.UI.getAll(imgupl)[0] || false;
130 },
131
132 getImageProcessor(imgupl) {
133 return ImageProcessor.UI.getAll(imgupl)[0] || false;
134 },
135
136
137 /**
138 * Force, instant custom image set into file input._file property
139 * by a base64, URL or Blob
140 *
141 * @param imgupl
142 * @param {String|Blob} src
143 */
144 setImage(imgupl, src) {
145 const input = this.getFileInput(imgupl);
146 const img = this.getImagePreview(imgupl);
147 const size = this.getOutputSize(imgupl);
148 const quality = this.getQuality(imgupl);
149 const format = this.getFormat(imgupl);
150
151 BunnyImage.getImage(src)
152 .then(img => {
153 const canv = BunnyImage.resizeImage(img, size, size);
154 return canv.toDataURL('image/' + format, quality);
155 })
156 .then(base64 => {
157 img.src = base64;
158 input._file = BunnyFile.base64ToBlob(base64);
159 return base64;
160 });
161 }
162
163};
164
165document.addEventListener('DOMContentLoaded', () => {
166 ImageUpload.initAll();
167});