问题
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