feature : zoom level

- fix : removed duplicated code between ImageResizer and CanvasUtils
  (disabledImageSmoothing utility method)
- added pskl.utils.UserAgent, basic user agent sniffer. I need it to sniff
  out IE10 for frame rendering (and it's not possible to feature detect
  here). Can check isChrome, isFirefox, isIE and get the version for each
  of them
- added resizeNearestNeighbour in ImageResizer. Readapted from piskel
  website, this allows us to 1 - resize without AA on IE10, and 2 - add a
  pixel gap to reenable the GRID
- finally : added back support for GRID !
- also extracted the 'zoomed out background color' as a constant in
  Constant.js
This commit is contained in:
jdescottes
2013-11-05 00:05:49 +01:00
parent 2248f41e68
commit 6e1ce724cb
8 changed files with 118 additions and 22 deletions

View File

@@ -32,6 +32,11 @@
if (canvas) {
canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
}
},
getImageDataFromCanvas : function (canvas) {
var sourceContext = canvas.getContext('2d');
return sourceContext.getImageData(0, 0, canvas.width, canvas.height).data;
}
};
})();

View File

@@ -8,7 +8,7 @@
context.save();
if (!smoothingEnabled) {
this.disableSmoothingOnContext(context);
pskl.CanvasUtils.disableImageSmoothing(canvas);
}
context.translate(canvas.width / 2, canvas.height / 2);
@@ -19,12 +19,58 @@
return canvas;
},
disableSmoothingOnContext : function (context) {
context.imageSmoothingEnabled = false;
context.mozImageSmoothingEnabled = false;
context.oImageSmoothingEnabled = false;
context.webkitImageSmoothingEnabled = false;
context.msImageSmoothingEnabled = false;
/**
* Manual implementation of resize using a nearest neighbour algorithm
* It is slower than relying on the native 'disabledImageSmoothing' available on CanvasRenderingContext2d.
* But it can be useful if :
* - IE < 11 (doesn't support msDisableImageSmoothing)
* - need to display a gap between pixel
*
* @param {Canvas2d} source original image to be resized, as a 2d canvas
* @param {Number} zoom ratio between desired dim / source dim
* @param {Number} margin gap to be displayed between pixels
* @return {Canvas2d} the resized canvas
*/
resizeNearestNeighbour : function (source, zoom, margin) {
margin = margin || 0;
var canvas = pskl.CanvasUtils.createCanvas(zoom*source.width, zoom*source.height);
var context = canvas.getContext('2d');
var imgData = pskl.CanvasUtils.getImageDataFromCanvas(source);
var yRanges = {},
xOffset = 0,
yOffset = 0,
xRange,
yRange;
// Draw the zoomed-up pixels to a different canvas context
for (var x = 0; x < source.width; x++) {
// Calculate X Range
xRange = (((x + 1) * zoom) | 0) - xOffset;
for (var y = 0; y < source.height; y++) {
// Calculate Y Range
if (!yRanges[y + ""]) {
// Cache Y Range
yRanges[y + ""] = (((y + 1) * zoom) | 0) - yOffset;
}
yRange = yRanges[y + ""];
var i = (y * source.width + x) * 4;
var r = imgData[i];
var g = imgData[i + 1];
var b = imgData[i + 2];
var a = imgData[i + 3];
context.fillStyle = "rgba(" + r + "," + g + "," + b + "," + (a / 255) + ")";
context.fillRect(xOffset, yOffset, xRange-margin, yRange-margin);
yOffset += yRange;
}
yOffset = 0;
xOffset += xRange;
}
return canvas;
}
};
})();

20
js/utils/UserAgent.js Normal file
View File

@@ -0,0 +1,20 @@
(function () {
var ns = $.namespace('pskl.utils');
var ua = navigator.userAgent;
ns.UserAgent = {
isIE : /MSIE/i.test( ua ),
isChrome : /Chrome/i.test( ua ),
isFirefox : /Firefox/i.test( ua )
};
ns.UserAgent.version = (function () {
if (pskl.utils.UserAgent.isIE) {
return parseInt(/MSIE\s?(\d+)/i.exec( ua )[1], 10);
} else if (pskl.utils.UserAgent.isChrome) {
return parseInt(/Chrome\/(\d+)/i.exec( ua )[1], 10);
} else if (pskl.utils.UserAgent.isFirefox) {
return parseInt(/Firefox\/(\d+)/i.exec( ua )[1], 10);
}
})();
})();