load-image-scale.js ➔ ... ➔ loadImage.scale   F
last analyzed

Complexity

Conditions 28
Paths 9750

Size

Total Lines 168

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 28
nc 9750
nop 3
dl 0
loc 168
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like load-image-scale.js ➔ ... ➔ loadImage.scale often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/*
2
 * JavaScript Load Image Scaling
3
 * https://github.com/blueimp/JavaScript-Load-Image
4
 *
5
 * Copyright 2011, Sebastian Tschan
6
 * https://blueimp.net
7
 *
8
 * Licensed under the MIT license:
9
 * https://opensource.org/licenses/MIT
10
 */
11
12
/* global define */
13
14
;(function (factory) {
15
  'use strict'
16
  if (typeof define === 'function' && define.amd) {
17
    // Register as an anonymous AMD module:
18
    define(['./load-image'], factory)
19
  } else if (typeof module === 'object' && module.exports) {
20
    factory(require('./load-image'))
21
  } else {
22
    // Browser globals:
23
    factory(window.loadImage)
24
  }
25
})(function (loadImage) {
26
  'use strict'
27
28
  var originalTransform = loadImage.transform
29
30
  loadImage.transform = function (img, options, callback, file, data) {
31
    originalTransform.call(
32
      loadImage,
33
      loadImage.scale(img, options, data),
34
      options,
35
      callback,
36
      file,
37
      data
38
    )
39
  }
40
41
  // Transform image coordinates, allows to override e.g.
42
  // the canvas orientation based on the orientation option,
43
  // gets canvas, options passed as arguments:
44
  loadImage.transformCoordinates = function () {}
45
46
  // Returns transformed options, allows to override e.g.
47
  // maxWidth, maxHeight and crop options based on the aspectRatio.
48
  // gets img, options passed as arguments:
49
  loadImage.getTransformedOptions = function (img, options) {
50
    var aspectRatio = options.aspectRatio
51
    var newOptions
52
    var i
53
    var width
54
    var height
55
    if (!aspectRatio) {
56
      return options
57
    }
58
    newOptions = {}
59
    for (i in options) {
60
      if (options.hasOwnProperty(i)) {
61
        newOptions[i] = options[i]
62
      }
63
    }
64
    newOptions.crop = true
65
    width = img.naturalWidth || img.width
66
    height = img.naturalHeight || img.height
67
    if (width / height > aspectRatio) {
68
      newOptions.maxWidth = height * aspectRatio
69
      newOptions.maxHeight = height
70
    } else {
71
      newOptions.maxWidth = width
72
      newOptions.maxHeight = width / aspectRatio
73
    }
74
    return newOptions
75
  }
76
77
  // Canvas render method, allows to implement a different rendering algorithm:
78
  loadImage.renderImageToCanvas = function (
79
    canvas,
80
    img,
81
    sourceX,
82
    sourceY,
83
    sourceWidth,
84
    sourceHeight,
85
    destX,
86
    destY,
87
    destWidth,
88
    destHeight
89
  ) {
90
    canvas
91
      .getContext('2d')
92
      .drawImage(
93
        img,
94
        sourceX,
95
        sourceY,
96
        sourceWidth,
97
        sourceHeight,
98
        destX,
99
        destY,
100
        destWidth,
101
        destHeight
102
      )
103
    return canvas
104
  }
105
106
  // Determines if the target image should be a canvas element:
107
  loadImage.hasCanvasOption = function (options) {
108
    return options.canvas || options.crop || !!options.aspectRatio
109
  }
110
111
  // Scales and/or crops the given image (img or canvas HTML element)
112
  // using the given options.
113
  // Returns a canvas object if the browser supports canvas
114
  // and the hasCanvasOption method returns true or a canvas
115
  // object is passed as image, else the scaled image:
116
  loadImage.scale = function (img, options, data) {
117
    options = options || {}
118
    var canvas = document.createElement('canvas')
119
    var useCanvas =
120
      img.getContext ||
121
      (loadImage.hasCanvasOption(options) && canvas.getContext)
122
    var width = img.naturalWidth || img.width
123
    var height = img.naturalHeight || img.height
124
    var destWidth = width
125
    var destHeight = height
126
    var maxWidth
127
    var maxHeight
128
    var minWidth
129
    var minHeight
130
    var sourceWidth
131
    var sourceHeight
132
    var sourceX
133
    var sourceY
134
    var pixelRatio
135
    var downsamplingRatio
136
    var tmp
137
    function scaleUp () {
138
      var scale = Math.max(
139
        (minWidth || destWidth) / destWidth,
140
        (minHeight || destHeight) / destHeight
141
      )
142
      if (scale > 1) {
143
        destWidth *= scale
144
        destHeight *= scale
145
      }
146
    }
147
    function scaleDown () {
148
      var scale = Math.min(
149
        (maxWidth || destWidth) / destWidth,
150
        (maxHeight || destHeight) / destHeight
151
      )
152
      if (scale < 1) {
153
        destWidth *= scale
154
        destHeight *= scale
155
      }
156
    }
157
    if (useCanvas) {
158
      options = loadImage.getTransformedOptions(img, options, data)
159
      sourceX = options.left || 0
160
      sourceY = options.top || 0
161
      if (options.sourceWidth) {
162
        sourceWidth = options.sourceWidth
163
        if (options.right !== undefined && options.left === undefined) {
164
          sourceX = width - sourceWidth - options.right
165
        }
166
      } else {
167
        sourceWidth = width - sourceX - (options.right || 0)
168
      }
169
      if (options.sourceHeight) {
170
        sourceHeight = options.sourceHeight
171
        if (options.bottom !== undefined && options.top === undefined) {
172
          sourceY = height - sourceHeight - options.bottom
173
        }
174
      } else {
175
        sourceHeight = height - sourceY - (options.bottom || 0)
176
      }
177
      destWidth = sourceWidth
178
      destHeight = sourceHeight
179
    }
180
    maxWidth = options.maxWidth
181
    maxHeight = options.maxHeight
182
    minWidth = options.minWidth
183
    minHeight = options.minHeight
184
    if (useCanvas && maxWidth && maxHeight && options.crop) {
185
      destWidth = maxWidth
186
      destHeight = maxHeight
187
      tmp = sourceWidth / sourceHeight - maxWidth / maxHeight
0 ignored issues
show
Bug introduced by
The variable sourceHeight does not seem to be initialized in case useCanvas on line 157 is false. Are you sure this can never be the case?
Loading history...
Bug introduced by
The variable sourceWidth does not seem to be initialized in case useCanvas on line 157 is false. Are you sure this can never be the case?
Loading history...
188
      if (tmp < 0) {
189
        sourceHeight = maxHeight * sourceWidth / maxWidth
190
        if (options.top === undefined && options.bottom === undefined) {
191
          sourceY = (height - sourceHeight) / 2
192
        }
193
      } else if (tmp > 0) {
194
        sourceWidth = maxWidth * sourceHeight / maxHeight
195
        if (options.left === undefined && options.right === undefined) {
196
          sourceX = (width - sourceWidth) / 2
197
        }
198
      }
199
    } else {
200
      if (options.contain || options.cover) {
201
        minWidth = maxWidth = maxWidth || minWidth
202
        minHeight = maxHeight = maxHeight || minHeight
203
      }
204
      if (options.cover) {
205
        scaleDown()
206
        scaleUp()
207
      } else {
208
        scaleUp()
209
        scaleDown()
210
      }
211
    }
212
    if (useCanvas) {
213
      pixelRatio = options.pixelRatio
214
      if (pixelRatio > 1) {
215
        canvas.style.width = destWidth + 'px'
216
        canvas.style.height = destHeight + 'px'
217
        destWidth *= pixelRatio
218
        destHeight *= pixelRatio
219
        canvas.getContext('2d').scale(pixelRatio, pixelRatio)
220
      }
221
      downsamplingRatio = options.downsamplingRatio
222
      if (
223
        downsamplingRatio > 0 &&
224
        downsamplingRatio < 1 &&
225
        destWidth < sourceWidth &&
226
        destHeight < sourceHeight
227
      ) {
228
        while (sourceWidth * downsamplingRatio > destWidth) {
229
          canvas.width = sourceWidth * downsamplingRatio
230
          canvas.height = sourceHeight * downsamplingRatio
231
          loadImage.renderImageToCanvas(
232
            canvas,
233
            img,
234
            sourceX,
0 ignored issues
show
Bug introduced by
The variable sourceX does not seem to be initialized in case useCanvas on line 157 is false. Are you sure the function renderImageToCanvas handles undefined variables?
Loading history...
235
            sourceY,
0 ignored issues
show
Bug introduced by
The variable sourceY does not seem to be initialized in case useCanvas on line 157 is false. Are you sure the function renderImageToCanvas handles undefined variables?
Loading history...
236
            sourceWidth,
237
            sourceHeight,
238
            0,
239
            0,
240
            canvas.width,
241
            canvas.height
242
          )
243
          sourceX = 0
244
          sourceY = 0
245
          sourceWidth = canvas.width
246
          sourceHeight = canvas.height
247
          img = document.createElement('canvas')
248
          img.width = sourceWidth
249
          img.height = sourceHeight
250
          loadImage.renderImageToCanvas(
251
            img,
252
            canvas,
253
            0,
254
            0,
255
            sourceWidth,
256
            sourceHeight,
257
            0,
258
            0,
259
            sourceWidth,
260
            sourceHeight
261
          )
262
        }
263
      }
264
      canvas.width = destWidth
265
      canvas.height = destHeight
266
      loadImage.transformCoordinates(canvas, options)
267
      return loadImage.renderImageToCanvas(
268
        canvas,
269
        img,
270
        sourceX,
271
        sourceY,
272
        sourceWidth,
273
        sourceHeight,
274
        0,
275
        0,
276
        destWidth,
277
        destHeight
278
      )
279
    }
280
    img.width = destWidth
281
    img.height = destHeight
282
    return img
283
  }
284
})
285