Socket
Socket
Sign inDemoInstall

canvas-size

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

canvas-size - npm Package Compare versions

Comparing version 1.0.4 to 1.1.0

14

CHANGELOG.md
# Change Log
## 1.1.0
*2020-05-31*
- Add `usePromise` option which allows the use of standard `then()`, `catch()`, and `finally()` promise methods or `async` functions in modern browsers (legacy browsers will require a promise polyfill and transpilation to ES5 for `async` functions)
- Add `benchmark` return value to `onError()` and `onSuccess()` callbacks
- Add new Chrome/Blink height/width limitation to canvas test sizes (#2)
- Add invocation of callbacks when testing a single dimension
- Fix bug that incorrectly set the last item in a generated array of test dimensions to an area test ([dimension, dimension]) instead of a width ([width, 1]) or height ([1, height]) test
- Update method of reading/writing to canvas elements, resulting in a significant performance increase
- Update dependencies
## 1.0.4

@@ -20,3 +32,3 @@

- Updated preferred CDN link to jsdelivr.
- Update preferred CDN link to jsdelivr

@@ -23,0 +35,0 @@ ## 1.0.0

201

dist/canvas-size.esm.js
/*!
* canvas-size
* v1.0.4
* v1.1.0
* https://github.com/jhildenbiddle/canvas-size
* (c) 2015-2019 John Hildenbiddle <http://hildenbiddle.com>
* (c) 2015-2020 John Hildenbiddle <http://hildenbiddle.com>
* MIT license
*/
const defaults = {
var hasCanvasSupport = window && window.HTMLCanvasElement;
var cropCvs, cropCtx, testCvs, testCtx;
if (hasCanvasSupport) {
cropCvs = document.createElement("canvas");
cropCtx = cropCvs.getContext("2d");
testCvs = document.createElement("canvas");
testCtx = testCvs.getContext("2d");
}
function canvasTest(settings) {
if (!hasCanvasSupport) {
return false;
}
var [width, height] = settings.sizes.shift();
var fill = [ width - 1, height - 1, 1, 1 ];
var job = Date.now();
testCvs.width = width;
testCvs.height = height;
testCtx.fillRect.apply(testCtx, fill);
cropCvs.width = 1;
cropCvs.height = 1;
cropCtx.drawImage(testCvs, 0 - (width - 1), 0 - (height - 1));
var isTestPass = Boolean(cropCtx.getImageData(0, 0, 1, 1).data[3]);
var benchmark = Date.now() - job;
if (isTestPass) {
settings.onSuccess(width, height, benchmark);
} else {
settings.onError(width, height, benchmark);
if (settings.sizes.length) {
if (window.requestAnimationFrame) {
window.requestAnimationFrame(() => {
canvasTest(settings);
});
} else {
canvasTest(settings);
}
}
}
return isTestPass;
}
function canvasTestPromise(settings) {
return new Promise((resolve, reject) => {
var newSettings = Object.assign({}, settings, {
onError(width, height, benchmark) {
if (settings.onError) {
settings.onError(width, height, benchmark);
}
if (settings.sizes.length === 0) {
reject({
width: width,
height: height,
benchmark: benchmark
});
}
},
onSuccess(width, height, benchmark) {
if (settings.onSuccess) {
settings.onSuccess(width, height, benchmark);
}
resolve({
width: width,
height: height,
benchmark: benchmark
});
}
});
canvasTest(newSettings);
});
}
var defaults = {
max: null,

@@ -13,2 +86,3 @@ min: 1,

step: 1024,
usePromise: false,
onError: Function.prototype,

@@ -18,64 +92,29 @@ onSuccess: Function.prototype

const testSizes = {
area: [ 16384, 14188, 11402, 10836, 11180, 8192, 4096, defaults.min ],
height: [ 8388607, 32767, 16384, 8192, 4096, defaults.min ],
width: [ 4194303, 32767, 16384, 8192, 4096, defaults.min ]
var testSizes = {
area: [ 32767, 16384, 14188, 11402, 10836, 11180, 8192, 4096, defaults.min ],
height: [ 8388607, 65535, 32767, 16384, 8192, 4096, defaults.min ],
width: [ 4194303, 65535, 32767, 16384, 8192, 4096, defaults.min ]
};
function canvasTest(width, height) {
const cvs = document ? document.createElement("canvas") : null;
const ctx = cvs && cvs.getContext ? cvs.getContext("2d") : null;
const w = 1;
const h = 1;
const x = width - w;
const y = height - h;
try {
cvs.width = width;
cvs.height = height;
ctx.fillRect(x, y, w, h);
return Boolean(ctx.getImageData(x, y, w, h).data[3]);
} catch (e) {
return false;
}
}
function canvasTestLoop(settings) {
const sizes = settings.sizes.shift();
const width = sizes[0];
const height = sizes[1];
const testPass = canvasTest(width, height);
if (testPass) {
settings.onSuccess(width, height);
} else {
settings.onError(width, height);
if (settings.sizes.length) {
setTimeout(function() {
canvasTestLoop(settings);
}, 0);
}
}
}
function createSizesArray(settings) {
const isArea = settings.width === settings.height;
const isWidth = settings.height === 1;
const isHeight = settings.width === 1;
const sizes = [];
var isArea = settings.width === settings.height;
var isWidth = settings.height === 1;
var isHeight = settings.width === 1;
var sizes = [];
if (!settings.width || !settings.height) {
settings.sizes.forEach(testSize => {
const width = isArea || isWidth ? testSize : 1;
const height = isArea || isHeight ? testSize : 1;
var width = isArea || isWidth ? testSize : 1;
var height = isArea || isHeight ? testSize : 1;
sizes.push([ width, height ]);
});
} else {
const testMin = settings.min || defaults.min;
const testStep = settings.step || defaults.step;
let testSize = Math.max(settings.width, settings.height);
while (testSize > testMin) {
const width = isArea || isWidth ? testSize : 1;
const height = isArea || isHeight ? testSize : 1;
var testMin = settings.min || defaults.min;
var testStep = settings.step || defaults.step;
var testSize = Math.max(settings.width, settings.height);
while (testSize >= testMin) {
var width = isArea || isWidth ? testSize : 1;
var height = isArea || isHeight ? testSize : 1;
sizes.push([ width, height ]);
testSize -= testStep;
}
sizes.push([ testMin, testMin ]);
}

@@ -85,6 +124,6 @@ return sizes;

const canvasSize = {
var canvasSize = {
maxArea() {
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
const sizes = createSizesArray({
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var sizes = createSizesArray({
width: options.max,

@@ -96,10 +135,14 @@ height: options.max,

});
const settings = Object.assign({}, defaults, options, {
var settings = Object.assign({}, defaults, options, {
sizes: sizes
});
canvasTestLoop(settings);
if (settings.usePromise) {
return canvasTestPromise(settings);
} else {
canvasTest(settings);
}
},
maxHeight() {
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
const sizes = createSizesArray({
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var sizes = createSizesArray({
width: 1,

@@ -111,10 +154,14 @@ height: options.max,

});
const settings = Object.assign({}, defaults, options, {
var settings = Object.assign({}, defaults, options, {
sizes: sizes
});
canvasTestLoop(settings);
if (settings.usePromise) {
return canvasTestPromise(settings);
} else {
canvasTest(settings);
}
},
maxWidth() {
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
const sizes = createSizesArray({
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var sizes = createSizesArray({
width: options.max,

@@ -126,16 +173,22 @@ height: 1,

});
const settings = Object.assign({}, defaults, options, {
var settings = Object.assign({}, defaults, options, {
sizes: sizes
});
canvasTestLoop(settings);
if (settings.usePromise) {
return canvasTestPromise(settings);
} else {
canvasTest(settings);
}
},
test() {
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
const settings = Object.assign({}, defaults, options);
if (settings.sizes.length) {
settings.sizes = [ ...options.sizes ];
canvasTestLoop(settings);
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var settings = Object.assign({}, defaults, options);
settings.sizes = [ ...settings.sizes ];
if (settings.width && settings.height) {
settings.sizes = [ [ settings.width, settings.height ] ];
}
if (settings.usePromise) {
return canvasTestPromise(settings);
} else {
const testPass = canvasTest(settings.width, settings.height);
return testPass;
return canvasTest(settings);
}

@@ -142,0 +195,0 @@ }

/*!
* canvas-size
* v1.0.4
* v1.1.0
* https://github.com/jhildenbiddle/canvas-size
* (c) 2015-2019 John Hildenbiddle <http://hildenbiddle.com>
* (c) 2015-2020 John Hildenbiddle <http://hildenbiddle.com>
* MIT license
*/
const t={max:null,min:1,sizes:[],step:1024,onError:Function.prototype,onSuccess:Function.prototype},e={area:[16384,14188,11402,10836,11180,8192,4096,t.min],height:[8388607,32767,16384,8192,4096,t.min],width:[4194303,32767,16384,8192,4096,t.min]};function i(t,e){const i=document?document.createElement("canvas"):null,s=i&&i.getContext?i.getContext("2d"):null,n=t-1,h=e-1;try{return i.width=t,i.height=e,s.fillRect(n,h,1,1),Boolean(s.getImageData(n,h,1,1).data[3])}catch(t){return!1}}function s(t){const e=t.sizes.shift(),n=e[0],h=e[1];i(n,h)?t.onSuccess(n,h):(t.onError(n,h),t.sizes.length&&setTimeout(function(){s(t)},0))}function n(e){const i=e.width===e.height,s=1===e.height,n=1===e.width,h=[];if(e.width&&e.height){const o=e.min||t.min,c=e.step||t.step;let a=Math.max(e.width,e.height);for(;a>o;){const t=i||s?a:1,e=i||n?a:1;h.push([t,e]),a-=c}h.push([o,o])}else e.sizes.forEach(t=>{const e=i||s?t:1,o=i||n?t:1;h.push([e,o])});return h}export default{maxArea(){let i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const h=n({width:i.max,height:i.max,min:i.min,step:i.step,sizes:[...e.area]});s(Object.assign({},t,i,{sizes:h}))},maxHeight(){let i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const h=n({width:1,height:i.max,min:i.min,step:i.step,sizes:[...e.height]});s(Object.assign({},t,i,{sizes:h}))},maxWidth(){let i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const h=n({width:i.max,height:1,min:i.min,step:i.step,sizes:[...e.width]});s(Object.assign({},t,i,{sizes:h}))},test(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const n=Object.assign({},t,e);if(!n.sizes.length){return i(n.width,n.height)}n.sizes=[...e.sizes],s(n)}};
var e,t,i,s,n=window&&window.HTMLCanvasElement;function r(a){if(!n)return!1;var[h,o]=a.sizes.shift(),m=[h-1,o-1,1,1],g=Date.now();i.width=h,i.height=o,s.fillRect.apply(s,m),e.width=1,e.height=1,t.drawImage(i,0-(h-1),0-(o-1));var d=Boolean(t.getImageData(0,0,1,1).data[3]),u=Date.now()-g;return d?a.onSuccess(h,o,u):(a.onError(h,o,u),a.sizes.length&&(window.requestAnimationFrame?window.requestAnimationFrame(()=>{r(a)}):r(a))),d}function a(e){return new Promise((t,i)=>{r(Object.assign({},e,{onError(t,s,n){e.onError&&e.onError(t,s,n),0===e.sizes.length&&i({width:t,height:s,benchmark:n})},onSuccess(i,s,n){e.onSuccess&&e.onSuccess(i,s,n),t({width:i,height:s,benchmark:n})}}))})}n&&(e=document.createElement("canvas"),t=e.getContext("2d"),i=document.createElement("canvas"),s=i.getContext("2d"));var h={max:null,min:1,sizes:[],step:1024,usePromise:!1,onError:Function.prototype,onSuccess:Function.prototype},o={area:[32767,16384,14188,11402,10836,11180,8192,4096,h.min],height:[8388607,65535,32767,16384,8192,4096,h.min],width:[4194303,65535,32767,16384,8192,4096,h.min]};function m(e){var t=e.width===e.height,i=1===e.height,s=1===e.width,n=[];if(e.width&&e.height)for(var r=e.min||h.min,a=e.step||h.step,o=Math.max(e.width,e.height);o>=r;){var m=t||i?o:1,g=t||s?o:1;n.push([m,g]),o-=a}else e.sizes.forEach(e=>{var r=t||i?e:1,a=t||s?e:1;n.push([r,a])});return n}var g={maxArea(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=m({width:e.max,height:e.max,min:e.min,step:e.step,sizes:[...o.area]}),i=Object.assign({},h,e,{sizes:t});if(i.usePromise)return a(i);r(i)},maxHeight(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=m({width:1,height:e.max,min:e.min,step:e.step,sizes:[...o.height]}),i=Object.assign({},h,e,{sizes:t});if(i.usePromise)return a(i);r(i)},maxWidth(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=m({width:e.max,height:1,min:e.min,step:e.step,sizes:[...o.width]}),i=Object.assign({},h,e,{sizes:t});if(i.usePromise)return a(i);r(i)},test(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=Object.assign({},h,e);return t.sizes=[...t.sizes],t.width&&t.height&&(t.sizes=[[t.width,t.height]]),t.usePromise?a(t):r(t)}};export default g;
//# sourceMappingURL=canvas-size.esm.min.js.map
/*!
* canvas-size
* v1.0.4
* v1.1.0
* https://github.com/jhildenbiddle/canvas-size
* (c) 2015-2019 John Hildenbiddle <http://hildenbiddle.com>
* (c) 2015-2020 John Hildenbiddle <http://hildenbiddle.com>
* MIT license

@@ -11,3 +11,3 @@ */

global.canvasSize = factory());
})(this, function() {
})(this, (function() {
"use strict";

@@ -28,17 +28,127 @@ function _extends() {

}
function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
}
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArray(iter) {
if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
}
function _iterableToArrayLimit(arr, i) {
if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return;
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance");
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var hasCanvasSupport = window && window.HTMLCanvasElement;
var cropCvs, cropCtx, testCvs, testCtx;
if (hasCanvasSupport) {
cropCvs = document.createElement("canvas");
cropCtx = cropCvs.getContext("2d");
testCvs = document.createElement("canvas");
testCtx = testCvs.getContext("2d");
}
function canvasTest(settings) {
if (!hasCanvasSupport) {
return false;
}
var _settings$sizes$shift = settings.sizes.shift(), _settings$sizes$shift2 = _slicedToArray(_settings$sizes$shift, 2), width = _settings$sizes$shift2[0], height = _settings$sizes$shift2[1];
var fill = [ width - 1, height - 1, 1, 1 ];
var job = Date.now();
testCvs.width = width;
testCvs.height = height;
testCtx.fillRect.apply(testCtx, fill);
cropCvs.width = 1;
cropCvs.height = 1;
cropCtx.drawImage(testCvs, 0 - (width - 1), 0 - (height - 1));
var isTestPass = Boolean(cropCtx.getImageData(0, 0, 1, 1).data[3]);
var benchmark = Date.now() - job;
if (isTestPass) {
settings.onSuccess(width, height, benchmark);
} else {
settings.onError(width, height, benchmark);
if (settings.sizes.length) {
if (window.requestAnimationFrame) {
window.requestAnimationFrame((function() {
canvasTest(settings);
}));
} else {
canvasTest(settings);
}
}
}
return isTestPass;
}
function canvasTestPromise(settings) {
return new Promise((function(resolve, reject) {
var newSettings = _extends({}, settings, {
onError: function onError(width, height, benchmark) {
if (settings.onError) {
settings.onError(width, height, benchmark);
}
if (settings.sizes.length === 0) {
reject({
width: width,
height: height,
benchmark: benchmark
});
}
},
onSuccess: function onSuccess(width, height, benchmark) {
if (settings.onSuccess) {
settings.onSuccess(width, height, benchmark);
}
resolve({
width: width,
height: height,
benchmark: benchmark
});
}
});
canvasTest(newSettings);
}));
}
var defaults = {

@@ -49,2 +159,3 @@ max: null,

step: 1024,
usePromise: false,
onError: Function.prototype,

@@ -54,38 +165,6 @@ onSuccess: Function.prototype

var testSizes = {
area: [ 16384, 14188, 11402, 10836, 11180, 8192, 4096, defaults.min ],
height: [ 8388607, 32767, 16384, 8192, 4096, defaults.min ],
width: [ 4194303, 32767, 16384, 8192, 4096, defaults.min ]
area: [ 32767, 16384, 14188, 11402, 10836, 11180, 8192, 4096, defaults.min ],
height: [ 8388607, 65535, 32767, 16384, 8192, 4096, defaults.min ],
width: [ 4194303, 65535, 32767, 16384, 8192, 4096, defaults.min ]
};
function canvasTest(width, height) {
var cvs = document ? document.createElement("canvas") : null;
var ctx = cvs && cvs.getContext ? cvs.getContext("2d") : null;
var w = 1;
var h = 1;
var x = width - w;
var y = height - h;
try {
cvs.width = width;
cvs.height = height;
ctx.fillRect(x, y, w, h);
return Boolean(ctx.getImageData(x, y, w, h).data[3]);
} catch (e) {
return false;
}
}
function canvasTestLoop(settings) {
var sizes = settings.sizes.shift();
var width = sizes[0];
var height = sizes[1];
var testPass = canvasTest(width, height);
if (testPass) {
settings.onSuccess(width, height);
} else {
settings.onError(width, height);
if (settings.sizes.length) {
setTimeout(function() {
canvasTestLoop(settings);
}, 0);
}
}
}
function createSizesArray(settings) {

@@ -97,7 +176,7 @@ var isArea = settings.width === settings.height;

if (!settings.width || !settings.height) {
settings.sizes.forEach(function(testSize) {
settings.sizes.forEach((function(testSize) {
var width = isArea || isWidth ? testSize : 1;
var height = isArea || isHeight ? testSize : 1;
sizes.push([ width, height ]);
});
}));
} else {

@@ -107,3 +186,3 @@ var testMin = settings.min || defaults.min;

var testSize = Math.max(settings.width, settings.height);
while (testSize > testMin) {
while (testSize >= testMin) {
var width = isArea || isWidth ? testSize : 1;

@@ -114,3 +193,2 @@ var height = isArea || isHeight ? testSize : 1;

}
sizes.push([ testMin, testMin ]);
}

@@ -132,3 +210,7 @@ return sizes;

});
canvasTestLoop(settings);
if (settings.usePromise) {
return canvasTestPromise(settings);
} else {
canvasTest(settings);
}
},

@@ -147,3 +229,7 @@ maxHeight: function maxHeight() {

});
canvasTestLoop(settings);
if (settings.usePromise) {
return canvasTestPromise(settings);
} else {
canvasTest(settings);
}
},

@@ -162,3 +248,7 @@ maxWidth: function maxWidth() {

});
canvasTestLoop(settings);
if (settings.usePromise) {
return canvasTestPromise(settings);
} else {
canvasTest(settings);
}
},

@@ -168,8 +258,10 @@ test: function test() {

var settings = _extends({}, defaults, options);
if (settings.sizes.length) {
settings.sizes = _toConsumableArray(options.sizes);
canvasTestLoop(settings);
settings.sizes = _toConsumableArray(settings.sizes);
if (settings.width && settings.height) {
settings.sizes = [ [ settings.width, settings.height ] ];
}
if (settings.usePromise) {
return canvasTestPromise(settings);
} else {
var testPass = canvasTest(settings.width, settings.height);
return testPass;
return canvasTest(settings);
}

@@ -179,3 +271,3 @@ }

return canvasSize;
});
}));
//# sourceMappingURL=canvas-size.js.map
/*!
* canvas-size
* v1.0.4
* v1.1.0
* https://github.com/jhildenbiddle/canvas-size
* (c) 2015-2019 John Hildenbiddle <http://hildenbiddle.com>
* (c) 2015-2020 John Hildenbiddle <http://hildenbiddle.com>
* MIT license
*/
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).canvasSize=e()}(this,function(){"use strict";function t(){return(t=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t}).apply(this,arguments)}function e(t){return function(t){if(Array.isArray(t)){for(var e=0,n=new Array(t.length);e<t.length;e++)n[e]=t[e];return n}}(t)||function(t){if(Symbol.iterator in Object(t)||"[object Arguments]"===Object.prototype.toString.call(t))return Array.from(t)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}var n={max:null,min:1,sizes:[],step:1024,onError:Function.prototype,onSuccess:Function.prototype},i={area:[16384,14188,11402,10836,11180,8192,4096,n.min],height:[8388607,32767,16384,8192,4096,n.min],width:[4194303,32767,16384,8192,4096,n.min]};function r(t,e){var n=document?document.createElement("canvas"):null,i=n&&n.getContext?n.getContext("2d"):null,r=t-1,o=e-1;try{return n.width=t,n.height=e,i.fillRect(r,o,1,1),Boolean(i.getImageData(r,o,1,1).data[3])}catch(t){return!1}}function o(t){var e=t.sizes.shift(),n=e[0],i=e[1];r(n,i)?t.onSuccess(n,i):(t.onError(n,i),t.sizes.length&&setTimeout(function(){o(t)},0))}function s(t){var e=t.width===t.height,i=1===t.height,r=1===t.width,o=[];if(t.width&&t.height){for(var s=t.min||n.min,a=t.step||n.step,h=Math.max(t.width,t.height);h>s;){var u=e||i?h:1,c=e||r?h:1;o.push([u,c]),h-=a}o.push([s,s])}else t.sizes.forEach(function(t){var n=e||i?t:1,s=e||r?t:1;o.push([n,s])});return o}return{maxArea:function(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},a=s({width:r.max,height:r.max,min:r.min,step:r.step,sizes:e(i.area)});o(t({},n,r,{sizes:a}))},maxHeight:function(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},a=s({width:1,height:r.max,min:r.min,step:r.step,sizes:e(i.height)});o(t({},n,r,{sizes:a}))},maxWidth:function(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},a=s({width:r.max,height:1,min:r.min,step:r.step,sizes:e(i.width)});o(t({},n,r,{sizes:a}))},test:function(){var i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},s=t({},n,i);if(!s.sizes.length)return r(s.width,s.height);s.sizes=e(i.sizes),o(s)}}});
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).canvasSize=e()}(this,(function(){"use strict";function t(){return(t=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(t[r]=n[r])}return t}).apply(this,arguments)}function e(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(t)))return;var n=[],r=!0,i=!1,o=void 0;try{for(var a,s=t[Symbol.iterator]();!(r=(a=s.next()).done)&&(n.push(a.value),!e||n.length!==e);r=!0);}catch(t){i=!0,o=t}finally{try{r||null==s.return||s.return()}finally{if(i)throw o}}return n}(t,e)||r(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function n(t){return function(t){if(Array.isArray(t))return i(t)}(t)||function(t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(t))return Array.from(t)}(t)||r(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function r(t,e){if(t){if("string"==typeof t)return i(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?i(t,e):void 0}}function i(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n<e;n++)r[n]=t[n];return r}var o,a,s,u,h=window&&window.HTMLCanvasElement;function c(t){if(!h)return!1;var n=e(t.sizes.shift(),2),r=n[0],i=n[1],f=[r-1,i-1,1,1],m=Date.now();s.width=r,s.height=i,u.fillRect.apply(u,f),o.width=1,o.height=1,a.drawImage(s,0-(r-1),0-(i-1));var d=Boolean(a.getImageData(0,0,1,1).data[3]),l=Date.now()-m;return d?t.onSuccess(r,i,l):(t.onError(r,i,l),t.sizes.length&&(window.requestAnimationFrame?window.requestAnimationFrame((function(){c(t)})):c(t))),d}function f(e){return new Promise((function(n,r){c(t({},e,{onError:function(t,n,i){e.onError&&e.onError(t,n,i),0===e.sizes.length&&r({width:t,height:n,benchmark:i})},onSuccess:function(t,r,i){e.onSuccess&&e.onSuccess(t,r,i),n({width:t,height:r,benchmark:i})}}))}))}h&&(o=document.createElement("canvas"),a=o.getContext("2d"),s=document.createElement("canvas"),u=s.getContext("2d"));var m={max:null,min:1,sizes:[],step:1024,usePromise:!1,onError:Function.prototype,onSuccess:Function.prototype},d={area:[32767,16384,14188,11402,10836,11180,8192,4096,m.min],height:[8388607,65535,32767,16384,8192,4096,m.min],width:[4194303,65535,32767,16384,8192,4096,m.min]};function l(t){var e=t.width===t.height,n=1===t.height,r=1===t.width,i=[];if(t.width&&t.height)for(var o=t.min||m.min,a=t.step||m.step,s=Math.max(t.width,t.height);s>=o;){var u=e||n?s:1,h=e||r?s:1;i.push([u,h]),s-=a}else t.sizes.forEach((function(t){var o=e||n?t:1,a=e||r?t:1;i.push([o,a])}));return i}return{maxArea:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=l({width:e.max,height:e.max,min:e.min,step:e.step,sizes:n(d.area)}),i=t({},m,e,{sizes:r});if(i.usePromise)return f(i);c(i)},maxHeight:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=l({width:1,height:e.max,min:e.min,step:e.step,sizes:n(d.height)}),i=t({},m,e,{sizes:r});if(i.usePromise)return f(i);c(i)},maxWidth:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=l({width:e.max,height:1,min:e.min,step:e.step,sizes:n(d.width)}),i=t({},m,e,{sizes:r});if(i.usePromise)return f(i);c(i)},test:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=t({},m,e);return r.sizes=n(r.sizes),r.width&&r.height&&(r.sizes=[[r.width,r.height]]),r.usePromise?f(r):c(r)}}}));
//# sourceMappingURL=canvas-size.min.js.map
{
"name": "canvas-size",
"version": "1.0.4",
"version": "1.1.0",
"description": "Determine the maximum size of an HTML canvas element and test support for custom canvas dimensions.",

@@ -46,35 +46,35 @@ "author": "John Hildenbiddle <http://hildenbiddle.com>",

"devDependencies": {
"@babel/core": "^7.4.3",
"@babel/plugin-transform-object-assign": "^7.2.0",
"@babel/polyfill": "^7.4.3",
"@babel/preset-env": "^7.4.3",
"babel-loader": "^8.0.5",
"babel-plugin-istanbul": "^5.1.1",
"@babel/core": "^7.9.6",
"@babel/plugin-transform-object-assign": "^7.8.3",
"@babel/polyfill": "^7.8.7",
"@babel/preset-env": "^7.9.6",
"babel-loader": "^8.1.0",
"babel-plugin-istanbul": "^6.0.0",
"chai": "^4.2.0",
"eslint": "^5.16.0",
"eslint-plugin-chai-expect": "^2.0.1",
"eslint-plugin-mocha": "^5.3.0",
"karma": "^4.0.1",
"eslint": "^7.1.0",
"eslint-plugin-chai-expect": "^2.1.0",
"eslint-plugin-mocha": "^7.0.0",
"karma": "^5.0.9",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^2.2.0",
"karma-coverage-istanbul-reporter": "^2.0.5",
"karma-chrome-launcher": "^3.1.0",
"karma-coverage-istanbul-reporter": "^3.0.2",
"karma-eslint": "^2.2.0",
"karma-mocha": "^1.3.0",
"karma-mocha": "^2.0.1",
"karma-mocha-reporter": "^2.2.5",
"karma-sauce-launcher": "^2.0.2",
"karma-sauce-launcher": "^4.1.4",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^4.0.0-rc.6",
"lodash.merge": "^4.6.1",
"karma-webpack": "^4.0.2",
"lodash.merge": "^4.6.2",
"mocha": "^4.1.0",
"rimraf": "^2.6.3",
"rollup": "^1.9.0",
"rollup-plugin-babel": "^4.3.2",
"rollup-plugin-commonjs": "^9.3.4",
"rollup-plugin-eslint": "^5.1.0",
"rimraf": "^3.0.2",
"rollup": "^2.10.9",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-eslint": "^7.0.0",
"rollup-plugin-json": "^4.0.0",
"rollup-plugin-node-resolve": "^4.2.1",
"rollup-plugin-terser": "^4.0.4",
"webpack": "^4.29.6"
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-terser": "^6.1.0",
"webpack": "^4.43.0"
},
"dependencies": {}
}

@@ -8,2 +8,3 @@ # canvas-size

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://github.com/jhildenbiddle/canvas-size/blob/master/LICENSE)
[![jsDelivr](https://data.jsdelivr.com/v1/package/npm/canvas-size/badge)](https://www.jsdelivr.com/package/npm/canvas-size)
[![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?url=https%3A%2F%2Fgithub.com%2Fjhildenbiddle%2Fcanvas-size&hashtags=canvas,developers,frontend,javascript)

@@ -13,13 +14,22 @@

- [Demo](https://jsbin.com/cacatohire/2/edit?js,console,output) (JSBin)
- [Demo](https://on690.csb.app/) for modern browsers (CodeSandbox)
- [Demo](https://jsbin.com/cacatohire/2/edit?js,output) for legacy browsers (JSBin)
## Description
## Features
The [HTML canvas](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) element is [widely supported](http://caniuse.com/#feat=canvas) by modern and legacy browsers, but each browser and platform combination imposes [unique size limitations](#test-results) that will render a canvas unusable when exceeded. Unfortunately, browsers do not provide a way to determine what their limitations are, nor do they provide any kind of feedback after an unusable canvas has been created. This makes working with large canvas elements a challenge, especially for applications that support a variety of browsers and platforms.
- Determine the maximum area, height, and width of a canvas element
- Test support for custom canvas element dimensions
- Optional ES6 [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) support
- UMD and ES6 module available
- Lightweight (< 1k min+gzip) and dependency-free
This micro-library provides the maximum area, height, and width of an HTML canvas element supported by the browser as well as the ability to test custom canvas dimensions. By collecting this information *before* a new canvas element is created, applications are able to reliably set canvas dimensions within the size limitations of each browser/platform.
**Browser Support**
| IE | Edge | Chrome | Firefox | Safari |
| ---- | ---- | ------ | ------- | ------ |
| 9+ | 12+ | 4+ | 3.6+ | 4+ |
------
- [Features](#features)
- [Description](#description)
- [Installation](#installation)

@@ -34,15 +44,8 @@ - [Methods](#methods)

## Features
## Description
- Determine the maximum area, height, and width of a canvas element
- Test support for custom canvas element dimensions
- UMD and ES6 module available
- Lightweight (< 1k min+gzip) and dependency-free
The [HTML canvas](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) element is [widely supported](http://caniuse.com/#feat=canvas) by modern and legacy browsers, but each browser and platform combination imposes [unique size limitations](#test-results) that will render a canvas unusable when exceeded. Unfortunately, browsers do not provide a way to determine what their limitations are, nor do they provide any kind of feedback after an unusable canvas has been created. This makes working with large canvas elements a challenge, especially for applications that support a variety of browsers and platforms.
**Browser Support**
This micro-library provides the maximum area, height, and width of an HTML canvas element supported by the browser as well as the ability to test custom canvas dimensions. By collecting this information *before* a new canvas element is created, applications are able to reliably set canvas dimensions within the size limitations of each browser/platform.
| IE | Edge | Chrome | Firefox | Safari |
| ---- | ---- | ------ | ------- | ------ |
| 9+ | 12+ | 4+ | 3.6+ | 4+ |
## Installation

@@ -88,6 +91,8 @@

When `options.max` is unspecified, an optimized test will be performed using known maximum area/height/width values from previously tested browsers and platforms (see [Test Results](#test-results) for details). This will return the maximum canvas area/height/width for all major browsers in the shortest amount of time.
When `options.max` is unspecified, an optimized test will be performed using known maximum area/height/width values from previously tested browsers and platforms (see [Test Results](#test-results) for details). This will return the maximum canvas area/height/width for in the shortest amount of time.
When `options.max` is specified, the value will be used for the initial area/height/width test, then reduced by the `options.step` value for each subsequent test until a successful test pass. This is useful for determining the maximum area/height/width of a canvas element for browser/platform combination not listed in the [Test Results](#test-results) section. Note that lower `options.step` values will provide more accurate results, but will require more time to complete due the increased number of tests that will run.
When `options.max` is specified, the value will be used for the initial area/height/width test, then reduced by the `options.step` value for each subsequent test until a successful test occurs. This is useful for determining the maximum area/height/width of a canvas element for browser/platform combination not listed in the [Test Results](#test-results) section. Note that lower `options.step` values will provide more granular (and therefore potentially more accurate) results, but will require more time to complete due the increased number of tests that will run.
Callbacks are invoked after each test.
**Options**

@@ -98,8 +103,11 @@

- Default: *See description above*
- **min**: Minimum canvas height/width to test (area = max * max)
- **min**: Minimum canvas height/width to test (area = min * min)
- Type: `number`
- Default: `1`
- **step**: Value to subtract from test height/width after each failed test
- **step**: Value to subtract from test width/height after each failed test
- Type: `number`
- Default: `1024`
- **usePromise**: Determines if the method call will return an ES6 Promise. The return value for both `resolve()` and `reject()` will be an object containing `width`, `height`, and `benchmark` properties (see onError/onSuccess for value details).
- Type: `boolean`
- Default: `false`
- **onError**: Callback invoked after each unsuccessful test

@@ -110,2 +118,3 @@ - Type: `function`

1. **height**: Height of canvas element (will be `1` for `maxWidth()`)
1. **benchmark**: Test execution time in milliseconds
- **onSuccess**: Callback invoked after each successful test

@@ -116,15 +125,18 @@ - Type: `function`

1. **height**: Height of canvas element (will be `1` for `maxWidth()`)
1. **benchmark**: Test execution time in milliseconds
**Examples**
The following examples use `canvasSize.maxArea()`. Usage for `maxHeight()` and `maxWidth()` is identical.
The following examples use `maxArea()`. Usage for `maxHeight()` and `maxWidth()` is identical.
Using callbacks:
```javascript
// Default (optimized sizes)
canvasSize.maxArea({
onError: function(width, height) {
console.log('Error:', width, height);
onError: function(width, height, benchmark) {
console.log('Error:', width, height, benchmark);
},
onSuccess: function(width, height) {
console.log('Success:', width, height);
onSuccess: function(width, height, benchmark) {
console.log('Success:', width, height, benchmark);
}

@@ -138,11 +150,7 @@ });

step: 1024, // default
onError: function(width, height) {
// 1: 16384,16384 (max)
// 2: 15360,15360 (max - 1024)
// 3: 14336,14336 (max - 2048)
console.log('Error:', width, height);
onError: function(width, height, benchmark) {
console.log('Error:', width, height, benchmark);
},
onSuccess: function(width, height) {
// 4: 13312,13312 (max - 3072)
console.log('Success:', width, height);
onSuccess: function(width, height, benchmark) {
console.log('Success:', width, height, benchmark);
}

@@ -152,2 +160,31 @@ });

Using ES6 Promises:
```javascript
// Default (optimized sizes)
canvasSize.maxArea({
usePromise: true
})
.then(({ width, height, benchmark }) => {
console.log(`Success: ${width} x ${height} (${benchmark} ms)`);
});
.catch(({ width, height, benchmark }) => {
console.log(`Error: ${width} x ${height} (${benchmark} ms)`);
});
// Custom sizes
canvasSize.maxArea({
max : 16384,
min : 1, // default
step : 1024, // default
usePromise: true
})
.then(({ width, height, benchmark }) => {
console.log(`Success: ${width} x ${height} (${benchmark} ms)`);
});
.catch(({ width, height, benchmark }) => {
console.log(`Error: ${width} x ${height} (${benchmark} ms)`);
});
```
### test()

@@ -157,6 +194,4 @@

To test a single dimension, use `options.width` and `options.height`. Callbacks are ignored when testing a single dimension, and a `boolean` is returned to indicate if the dimensions are within the browser's size limitations.
To test a single dimension, use `options.width` and `options.height`. A `boolean` will be returned to indicate if the dimensions are within the browser's size limitations. To test multiple dimensions, use `options.sizes` to provide an `array` of `[width, height]` combinations to be tested (see example below). Callbacks are invoked after each test.
To test multiple dimensions, use `options.sizes` to provide an `array` of `[width, height]` combinations to be tested (see example below). Callbacks are invoked after each test.
**Options**

@@ -170,2 +205,5 @@

- Type: `array` (see examples below)
- **usePromise**: Determines if the method call will return an ES6 Promise. The return value for both `resolve()` and `reject()` will be an object containing `width`, `height`, and `benchmark` properties (see onError/onSuccess for value details).
- Type: `boolean`
- Default: `false`
- **onError**: Callback invoked after each unsuccessful test

@@ -176,2 +214,3 @@ - Type: `function`

1. **height**: height of canvas element
1. **benchmark**: Test execution time in milliseconds
- **onSuccess**: Callback invoked after each successful test

@@ -182,12 +221,15 @@ - Type: `function`

1. **height**: height of canvas element
1. **benchmark**: Test execution time in milliseconds
**Returns**
- `boolean` when testing single dimension using `options.width` and `options.height`. Returns `true` if the dimensions are within the browser's size limitations or `false` when exceeded.
- `boolean` when testing a single dimension. Returns `true` if the dimensions are within the browser's size limitations or `false` when exceeded.
**Examples**
Using return value:
```javascript
// Single dimension
var result = canvasSize.test({
var isValidCanvasSize = canvasSize.test({
height: 16384,

@@ -197,4 +239,8 @@ width : 16384

console.log(result); // true/false
console.log(isValidCanvasSize); // true/false
```
Using callbacks:
```javascript
// Multiple dimensions

@@ -207,9 +253,6 @@ canvasSize.test({

],
onError: function(width, height) {
// 1: 16384,16384
// 2: 8192,8192
onError: function(width, height, benchmark) {
console.log('Error:', width, height);
},
onSuccess: function(width, height) {
// 3: 4096,4096
onSuccess: function(width, height, benchmark) {
console.log('Success:', width, height);

@@ -220,2 +263,22 @@ }

Using ES6 Promises:
```javascript
// Multiple dimensions
canvasSize.test({
sizes: [
[16384, 16384],
[8192, 8192],
[4096, 4096]
]
usePromise: true
})
.then(({ width, height, benchmark }) => {
console.log(`Success: ${width} x ${height} (${benchmark} ms)`);
});
.catch(({ width, height, benchmark }) => {
console.log(`Error: ${width} x ${height} (${benchmark} ms)`);
});
```
## Test Results

@@ -229,5 +292,6 @@

| ----------------------- | --------: | ---------: | ----------------------------: |
| Chrome 70 (Mac, Win*) | 32,767 | 32,767 | 268,435,456 (16,384 x 16,384) |
| Chrome 83 (Mac, Win *) | 65,535 | 65,535 | 268,435,456 (16,384 x 16,384) |
| Chrome 70 (Mac, Win *) | 32,767 | 32,767 | 268,435,456 (16,384 x 16,384) |
| Edge 17 * | 16,384 | 16,384 | 268,435,456 (16,384 x 16,384) |
| Firefox 63 (Mac, Win*) | 32,767 | 32,767 | 124,992,400 (11,180 x 11,180) |
| Firefox 63 (Mac, Win *) | 32,767 | 32,767 | 124,992,400 (11,180 x 11,180) |
| IE 11 * | 16,384 | 16,384 | 67,108,864 (8,192 x 8,192) |

@@ -253,7 +317,6 @@ | IE 9 - 10 * | 8,192 | 8,192 | 67,108,864 (8,192 x 8,192) |

This is a result of the single-threaded nature of JavaScript and the time required to read data from large HTML canvas elements on the client.
This is a result of the single-threaded nature of JavaScript and the time required to read data from large HTML canvas elements on the client. [OffscreenCanvas](https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas) and [Web Workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) seem like a promising solution for supporting browsers, but extensive testing shows performance far worse than testing on the main thread.
If/when support for [OffscreenCanvas](https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas) is added to the library, this will no longer be an issue for modern browsers as all canvas work will be handled by a [Service Worker](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) on a separate thread. Until then, consider the following options:
To accommodate for the brief delays that may occur when testing extremely large canvas sizes, consider the following:
- Display a progress indicator to inform users that the application is in a working state.
- Call the library when tests are least likely to affect the overall user experience.

@@ -260,0 +323,0 @@ - [Cache test results on the client](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage) so that tests only need to be performed once per browser.

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc