问题
I'm creating a browser-based game that uses layered canvases and sprite images, and for visual and performance reasons I would like to disable imageSmoothingEnabled by default. It's my understanding that imageSmoothingEnabled isn't available in all browsers, but there are vendor-prefixed versions. I am trying to find an elegant way to disable this attribute by default across all my canvases (in as many browsers as possible). So far, this is my method:
context1.imageSmoothingEnabled = false;
context1.mozImageSmoothingEnabled = false;
context1.oImageSmoothingEnabled = false;
context1.webkitImageSmoothingEnabled = false;
context2.imageSmoothingEnabled = false;
context2.mozImageSmoothingEnabled = false;
context2.oImageSmoothingEnabled = false;
context2.webkitImageSmoothingEnabled = false;
context3.imageSmoothingEnabled = false;
context3.mozImageSmoothingEnabled = false;
context3.oImageSmoothingEnabled = false;
context3.webkitImageSmoothingEnabled = false;
//etc...
Is there a more elegant approach? Is it perhaps possible to change the context's API to default to false, before actually creating each canvas context?
回答1:
Yes, you have a cleaner approach : since you will always get a context by using getContext('2d')
on a canvas, you can inject getContext
, so that it does any setup of your like before returning the context.
The following piece of code successfully sets the smoothing to false for all your contexts :
(it should, quite obviously, be run before any call to getContext).
// save old getContext
var oldgetContext = HTMLCanvasElement.prototype.getContext ;
// get a context, set it to smoothed if it was a 2d context, and return it.
function getSmoothContext(contextType) {
var resCtx = oldgetContext.apply(this, arguments);
if (contextType == '2d') {
setToFalse(resCtx, 'imageSmoothingEnabled');
setToFalse(resCtx, 'mozImageSmoothingEnabled');
setToFalse(resCtx, 'oImageSmoothingEnabled');
setToFalse(resCtx, 'webkitImageSmoothingEnabled');
}
return resCtx ;
}
function setToFalse(obj, prop) { if ( obj[prop] !== undefined ) obj[prop] = false; }
// inject new smoothed getContext
HTMLCanvasElement.prototype.getContext = getSmoothContext ;
Rq that you can do anything in 'your' getContext. I use it to copy canvas's width, height on the context to have them at hand with no DOM access, among other things.
回答2:
You can put those into a method like:
function imageSmoothingEnabled(ctx, state) {
ctx.mozImageSmoothingEnabled = state;
ctx.oImageSmoothingEnabled = state;
ctx.webkitImageSmoothingEnabled = state;
ctx.imageSmoothingEnabled = state;
}
then call for each context:
imageSmoothingEnabled(context1, false);
imageSmoothingEnabled(context2, false);
imageSmoothingEnabled(context3, false);
As these are properties you can't simply alter their defaults. The method here is pretty clean - it can be cleaner by checking the existence of the property first:
if (typeof ctx.webkitImageSmoothingEnabled !== 'undefined')
ctx.webkitImageSmoothingEnabled = state;
etc.
来源:https://stackoverflow.com/questions/22003687/disabling-imagesmoothingenabled-by-default-on-multiple-canvases