123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- /*
- * JavaScript Load Image Scaling
- * https://github.com/blueimp/JavaScript-Load-Image
- *
- * Copyright 2011, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
- /* global define */
- ;(function (factory) {
- 'use strict'
- if (typeof define === 'function' && define.amd) {
- // Register as an anonymous AMD module:
- define(['./load-image'], factory)
- } else if (typeof module === 'object' && module.exports) {
- factory(require('./load-image'))
- } else {
- // Browser globals:
- factory(window.loadImage)
- }
- }(function (loadImage) {
- 'use strict'
- var originalTransform = loadImage.transform
- loadImage.transform = function (img, options, callback, file, data) {
- originalTransform.call(
- loadImage,
- loadImage.scale(img, options, data),
- options,
- callback,
- file,
- data
- )
- }
- // Transform image coordinates, allows to override e.g.
- // the canvas orientation based on the orientation option,
- // gets canvas, options passed as arguments:
- loadImage.transformCoordinates = function () {
- return
- }
- // Returns transformed options, allows to override e.g.
- // maxWidth, maxHeight and crop options based on the aspectRatio.
- // gets img, options passed as arguments:
- loadImage.getTransformedOptions = function (img, options) {
- var aspectRatio = options.aspectRatio
- var newOptions
- var i
- var width
- var height
- if (!aspectRatio) {
- return options
- }
- newOptions = {}
- for (i in options) {
- if (options.hasOwnProperty(i)) {
- newOptions[i] = options[i]
- }
- }
- newOptions.crop = true
- width = img.naturalWidth || img.width
- height = img.naturalHeight || img.height
- if (width / height > aspectRatio) {
- newOptions.maxWidth = height * aspectRatio
- newOptions.maxHeight = height
- } else {
- newOptions.maxWidth = width
- newOptions.maxHeight = width / aspectRatio
- }
- return newOptions
- }
- // Canvas render method, allows to implement a different rendering algorithm:
- loadImage.renderImageToCanvas = function (
- canvas,
- img,
- sourceX,
- sourceY,
- sourceWidth,
- sourceHeight,
- destX,
- destY,
- destWidth,
- destHeight
- ) {
- canvas.getContext('2d').drawImage(
- img,
- sourceX,
- sourceY,
- sourceWidth,
- sourceHeight,
- destX,
- destY,
- destWidth,
- destHeight
- )
- return canvas
- }
- // Determines if the target image should be a canvas element:
- loadImage.hasCanvasOption = function (options) {
- return options.canvas || options.crop || !!options.aspectRatio
- }
- // Scales and/or crops the given image (img or canvas HTML element)
- // using the given options.
- // Returns a canvas object if the browser supports canvas
- // and the hasCanvasOption method returns true or a canvas
- // object is passed as image, else the scaled image:
- loadImage.scale = function (img, options, data) {
- options = options || {}
- var canvas = document.createElement('canvas')
- var useCanvas = img.getContext ||
- (loadImage.hasCanvasOption(options) && canvas.getContext)
- var width = img.naturalWidth || img.width
- var height = img.naturalHeight || img.height
- var destWidth = width
- var destHeight = height
- var maxWidth
- var maxHeight
- var minWidth
- var minHeight
- var sourceWidth
- var sourceHeight
- var sourceX
- var sourceY
- var pixelRatio
- var downsamplingRatio
- var tmp
- function scaleUp () {
- var scale = Math.max(
- (minWidth || destWidth) / destWidth,
- (minHeight || destHeight) / destHeight
- )
- if (scale > 1) {
- destWidth *= scale
- destHeight *= scale
- }
- }
- function scaleDown () {
- var scale = Math.min(
- (maxWidth || destWidth) / destWidth,
- (maxHeight || destHeight) / destHeight
- )
- if (scale < 1) {
- destWidth *= scale
- destHeight *= scale
- }
- }
- if (useCanvas) {
- options = loadImage.getTransformedOptions(img, options, data)
- sourceX = options.left || 0
- sourceY = options.top || 0
- if (options.sourceWidth) {
- sourceWidth = options.sourceWidth
- if (options.right !== undefined && options.left === undefined) {
- sourceX = width - sourceWidth - options.right
- }
- } else {
- sourceWidth = width - sourceX - (options.right || 0)
- }
- if (options.sourceHeight) {
- sourceHeight = options.sourceHeight
- if (options.bottom !== undefined && options.top === undefined) {
- sourceY = height - sourceHeight - options.bottom
- }
- } else {
- sourceHeight = height - sourceY - (options.bottom || 0)
- }
- destWidth = sourceWidth
- destHeight = sourceHeight
- }
- maxWidth = options.maxWidth
- maxHeight = options.maxHeight
- minWidth = options.minWidth
- minHeight = options.minHeight
- if (useCanvas && maxWidth && maxHeight && options.crop) {
- destWidth = maxWidth
- destHeight = maxHeight
- tmp = sourceWidth / sourceHeight - maxWidth / maxHeight
- if (tmp < 0) {
- sourceHeight = maxHeight * sourceWidth / maxWidth
- if (options.top === undefined && options.bottom === undefined) {
- sourceY = (height - sourceHeight) / 2
- }
- } else if (tmp > 0) {
- sourceWidth = maxWidth * sourceHeight / maxHeight
- if (options.left === undefined && options.right === undefined) {
- sourceX = (width - sourceWidth) / 2
- }
- }
- } else {
- if (options.contain || options.cover) {
- minWidth = maxWidth = maxWidth || minWidth
- minHeight = maxHeight = maxHeight || minHeight
- }
- if (options.cover) {
- scaleDown()
- scaleUp()
- } else {
- scaleUp()
- scaleDown()
- }
- }
- if (useCanvas) {
- pixelRatio = options.pixelRatio
- if (pixelRatio > 1) {
- canvas.style.width = destWidth + 'px'
- canvas.style.height = destHeight + 'px'
- destWidth *= pixelRatio
- destHeight *= pixelRatio
- canvas.getContext('2d').scale(pixelRatio, pixelRatio)
- }
- downsamplingRatio = options.downsamplingRatio
- if (downsamplingRatio > 0 && downsamplingRatio < 1 &&
- destWidth < sourceWidth && destHeight < sourceHeight) {
- while (sourceWidth * downsamplingRatio > destWidth) {
- canvas.width = sourceWidth * downsamplingRatio
- canvas.height = sourceHeight * downsamplingRatio
- loadImage.renderImageToCanvas(
- canvas,
- img,
- sourceX,
- sourceY,
- sourceWidth,
- sourceHeight,
- 0,
- 0,
- canvas.width,
- canvas.height
- )
- sourceX = 0
- sourceY = 0
- sourceWidth = canvas.width
- sourceHeight = canvas.height
- img = document.createElement('canvas')
- img.width = sourceWidth
- img.height = sourceHeight
- loadImage.renderImageToCanvas(
- img,
- canvas,
- 0,
- 0,
- sourceWidth,
- sourceHeight,
- 0,
- 0,
- sourceWidth,
- sourceHeight
- )
- }
- }
- canvas.width = destWidth
- canvas.height = destHeight
- loadImage.transformCoordinates(
- canvas,
- options
- )
- return loadImage.renderImageToCanvas(
- canvas,
- img,
- sourceX,
- sourceY,
- sourceWidth,
- sourceHeight,
- 0,
- 0,
- destWidth,
- destHeight
- )
- }
- img.width = destWidth
- img.height = destHeight
- return img
- }
- }))
|