1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | ;(function (factory) {
|
15 | 'use strict'
|
16 | if (typeof define === 'function' && define.amd) {
|
17 |
|
18 | define(['./load-image'], factory)
|
19 | } else if (typeof module === 'object' && module.exports) {
|
20 | factory(require('./load-image'))
|
21 | } else {
|
22 |
|
23 | factory(window.loadImage)
|
24 | }
|
25 | })(function (loadImage) {
|
26 | 'use strict'
|
27 |
|
28 | var originalTransform = loadImage.transform
|
29 |
|
30 | loadImage.createCanvas = function (width, height, offscreen) {
|
31 | if (offscreen && loadImage.global.OffscreenCanvas) {
|
32 | return new OffscreenCanvas(width, height)
|
33 | }
|
34 | var canvas = document.createElement('canvas')
|
35 | canvas.width = width
|
36 | canvas.height = height
|
37 | return canvas
|
38 | }
|
39 |
|
40 | loadImage.transform = function (img, options, callback, file, data) {
|
41 | originalTransform.call(
|
42 | loadImage,
|
43 | loadImage.scale(img, options, data),
|
44 | options,
|
45 | callback,
|
46 | file,
|
47 | data
|
48 | )
|
49 | }
|
50 |
|
51 |
|
52 |
|
53 |
|
54 | loadImage.transformCoordinates = function () {}
|
55 |
|
56 |
|
57 |
|
58 |
|
59 | loadImage.getTransformedOptions = function (img, options) {
|
60 | var aspectRatio = options.aspectRatio
|
61 | var newOptions
|
62 | var i
|
63 | var width
|
64 | var height
|
65 | if (!aspectRatio) {
|
66 | return options
|
67 | }
|
68 | newOptions = {}
|
69 | for (i in options) {
|
70 | if (Object.prototype.hasOwnProperty.call(options, i)) {
|
71 | newOptions[i] = options[i]
|
72 | }
|
73 | }
|
74 | newOptions.crop = true
|
75 | width = img.naturalWidth || img.width
|
76 | height = img.naturalHeight || img.height
|
77 | if (width / height > aspectRatio) {
|
78 | newOptions.maxWidth = height * aspectRatio
|
79 | newOptions.maxHeight = height
|
80 | } else {
|
81 | newOptions.maxWidth = width
|
82 | newOptions.maxHeight = width / aspectRatio
|
83 | }
|
84 | return newOptions
|
85 | }
|
86 |
|
87 |
|
88 | loadImage.drawImage = function (
|
89 | img,
|
90 | canvas,
|
91 | sourceX,
|
92 | sourceY,
|
93 | sourceWidth,
|
94 | sourceHeight,
|
95 | destWidth,
|
96 | destHeight,
|
97 | options
|
98 | ) {
|
99 | var ctx = canvas.getContext('2d')
|
100 | if (options.imageSmoothingEnabled === false) {
|
101 | ctx.msImageSmoothingEnabled = false
|
102 | ctx.imageSmoothingEnabled = false
|
103 | } else if (options.imageSmoothingQuality) {
|
104 | ctx.imageSmoothingQuality = options.imageSmoothingQuality
|
105 | }
|
106 | ctx.drawImage(
|
107 | img,
|
108 | sourceX,
|
109 | sourceY,
|
110 | sourceWidth,
|
111 | sourceHeight,
|
112 | 0,
|
113 | 0,
|
114 | destWidth,
|
115 | destHeight
|
116 | )
|
117 | return ctx
|
118 | }
|
119 |
|
120 |
|
121 | loadImage.requiresCanvas = function (options) {
|
122 | return options.canvas || options.crop || !!options.aspectRatio
|
123 | }
|
124 |
|
125 |
|
126 |
|
127 | loadImage.scale = function (img, options, data) {
|
128 |
|
129 | options = options || {}
|
130 |
|
131 | data = data || {}
|
132 | var useCanvas =
|
133 | img.getContext ||
|
134 | (loadImage.requiresCanvas(options) &&
|
135 | !!loadImage.global.HTMLCanvasElement)
|
136 | var width = img.naturalWidth || img.width
|
137 | var height = img.naturalHeight || img.height
|
138 | var destWidth = width
|
139 | var destHeight = height
|
140 | var maxWidth
|
141 | var maxHeight
|
142 | var minWidth
|
143 | var minHeight
|
144 | var sourceWidth
|
145 | var sourceHeight
|
146 | var sourceX
|
147 | var sourceY
|
148 | var pixelRatio
|
149 | var downsamplingRatio
|
150 | var tmp
|
151 | var canvas
|
152 | |
153 |
|
154 |
|
155 | function scaleUp() {
|
156 | var scale = Math.max(
|
157 | (minWidth || destWidth) / destWidth,
|
158 | (minHeight || destHeight) / destHeight
|
159 | )
|
160 | if (scale > 1) {
|
161 | destWidth *= scale
|
162 | destHeight *= scale
|
163 | }
|
164 | }
|
165 | |
166 |
|
167 |
|
168 | function scaleDown() {
|
169 | var scale = Math.min(
|
170 | (maxWidth || destWidth) / destWidth,
|
171 | (maxHeight || destHeight) / destHeight
|
172 | )
|
173 | if (scale < 1) {
|
174 | destWidth *= scale
|
175 | destHeight *= scale
|
176 | }
|
177 | }
|
178 | if (useCanvas) {
|
179 |
|
180 | options = loadImage.getTransformedOptions(img, options, data)
|
181 | sourceX = options.left || 0
|
182 | sourceY = options.top || 0
|
183 | if (options.sourceWidth) {
|
184 | sourceWidth = options.sourceWidth
|
185 | if (options.right !== undefined && options.left === undefined) {
|
186 | sourceX = width - sourceWidth - options.right
|
187 | }
|
188 | } else {
|
189 | sourceWidth = width - sourceX - (options.right || 0)
|
190 | }
|
191 | if (options.sourceHeight) {
|
192 | sourceHeight = options.sourceHeight
|
193 | if (options.bottom !== undefined && options.top === undefined) {
|
194 | sourceY = height - sourceHeight - options.bottom
|
195 | }
|
196 | } else {
|
197 | sourceHeight = height - sourceY - (options.bottom || 0)
|
198 | }
|
199 | destWidth = sourceWidth
|
200 | destHeight = sourceHeight
|
201 | }
|
202 | maxWidth = options.maxWidth
|
203 | maxHeight = options.maxHeight
|
204 | minWidth = options.minWidth
|
205 | minHeight = options.minHeight
|
206 | if (useCanvas && maxWidth && maxHeight && options.crop) {
|
207 | destWidth = maxWidth
|
208 | destHeight = maxHeight
|
209 | tmp = sourceWidth / sourceHeight - maxWidth / maxHeight
|
210 | if (tmp < 0) {
|
211 | sourceHeight = (maxHeight * sourceWidth) / maxWidth
|
212 | if (options.top === undefined && options.bottom === undefined) {
|
213 | sourceY = (height - sourceHeight) / 2
|
214 | }
|
215 | } else if (tmp > 0) {
|
216 | sourceWidth = (maxWidth * sourceHeight) / maxHeight
|
217 | if (options.left === undefined && options.right === undefined) {
|
218 | sourceX = (width - sourceWidth) / 2
|
219 | }
|
220 | }
|
221 | } else {
|
222 | if (options.contain || options.cover) {
|
223 | minWidth = maxWidth = maxWidth || minWidth
|
224 | minHeight = maxHeight = maxHeight || minHeight
|
225 | }
|
226 | if (options.cover) {
|
227 | scaleDown()
|
228 | scaleUp()
|
229 | } else {
|
230 | scaleUp()
|
231 | scaleDown()
|
232 | }
|
233 | }
|
234 | if (useCanvas) {
|
235 | pixelRatio = options.pixelRatio
|
236 | if (
|
237 | pixelRatio > 1 &&
|
238 |
|
239 | !(
|
240 | img.style.width &&
|
241 | Math.floor(parseFloat(img.style.width, 10)) ===
|
242 | Math.floor(width / pixelRatio)
|
243 | )
|
244 | ) {
|
245 | destWidth *= pixelRatio
|
246 | destHeight *= pixelRatio
|
247 | }
|
248 |
|
249 |
|
250 | if (
|
251 | loadImage.orientationCropBug &&
|
252 | !img.getContext &&
|
253 | (sourceX || sourceY || sourceWidth !== width || sourceHeight !== height)
|
254 | ) {
|
255 |
|
256 | tmp = img
|
257 |
|
258 | img = loadImage.createCanvas(width, height, true)
|
259 | loadImage.drawImage(
|
260 | tmp,
|
261 | img,
|
262 | 0,
|
263 | 0,
|
264 | width,
|
265 | height,
|
266 | width,
|
267 | height,
|
268 | options
|
269 | )
|
270 | }
|
271 | downsamplingRatio = options.downsamplingRatio
|
272 | if (
|
273 | downsamplingRatio > 0 &&
|
274 | downsamplingRatio < 1 &&
|
275 | destWidth < sourceWidth &&
|
276 | destHeight < sourceHeight
|
277 | ) {
|
278 | while (sourceWidth * downsamplingRatio > destWidth) {
|
279 | canvas = loadImage.createCanvas(
|
280 | sourceWidth * downsamplingRatio,
|
281 | sourceHeight * downsamplingRatio,
|
282 | true
|
283 | )
|
284 | loadImage.drawImage(
|
285 | img,
|
286 | canvas,
|
287 | sourceX,
|
288 | sourceY,
|
289 | sourceWidth,
|
290 | sourceHeight,
|
291 | canvas.width,
|
292 | canvas.height,
|
293 | options
|
294 | )
|
295 | sourceX = 0
|
296 | sourceY = 0
|
297 | sourceWidth = canvas.width
|
298 | sourceHeight = canvas.height
|
299 |
|
300 | img = canvas
|
301 | }
|
302 | }
|
303 | canvas = loadImage.createCanvas(destWidth, destHeight)
|
304 | loadImage.transformCoordinates(canvas, options, data)
|
305 | if (pixelRatio > 1) {
|
306 | canvas.style.width = canvas.width / pixelRatio + 'px'
|
307 | }
|
308 | loadImage
|
309 | .drawImage(
|
310 | img,
|
311 | canvas,
|
312 | sourceX,
|
313 | sourceY,
|
314 | sourceWidth,
|
315 | sourceHeight,
|
316 | destWidth,
|
317 | destHeight,
|
318 | options
|
319 | )
|
320 | .setTransform(1, 0, 0, 1, 0, 0)
|
321 | return canvas
|
322 | }
|
323 | img.width = destWidth
|
324 | img.height = destHeight
|
325 | return img
|
326 | }
|
327 | })
|