缩放 HTML5 Canvas 图片
Scaling HTML5 Canvas Image
构建一个网页,我试图在该网页上将图像设置为主 canvas 的背景。实际图像是 1600x805,我正在尝试对应用程序进行编码,以便它可以根据用户屏幕的尺寸向上或向下缩放图像。在 Prime.js
中,我有一个对象可以设置位于 index.html
中的应用程序的 canvas 元素的属性。这是该对象的代码:
function Prime(w,h){
if(!(function(){
return Modernizr.canvas;
})){ alert('Error'); return false; };
this.context = null;
this.self = this;
this.globalCanvasMain.w = w;
this.globalCanvasMain.h = h;
this.globalCanvasMain.set(this.self);
this.background.setBg();
}
Prime.prototype = {
constructor: Prime,
self: this,
globalCanvasMain: {
x: 0,
y: 0,
set: function(ref){
ref.context = document.getElementById('mainCanvas').getContext('2d');
$("#mainCanvas").parent().css('position', 'relative');
$("#mainCanvas").css({left: this.x, top: this.y, position: 'absolute'});
$("#mainCanvas").width(this.w).height(this.h);
}
},
background: {
bg: null,
setBg: function(){
this.bg = new Image();
this.bg.src = 'res/background.jpg';
}
},
drawAll: function(){
this.context.drawImage(this.background.bg, 0,0, this.background.bg.width,this.background.bg.height,
this.globalCanvasMain.x,this.globalCanvasMain.y, this.globalCanvasMain.w,this.globalCanvasMain.h);
}
};
像这样的外部对象与 index.html
中的元素交互的主要接口是 home.js
。这是那里发生的事情:
$(document).ready(function(){
var prime = new Prime(window.innerWidth,window.innerHeight);
setInterval(prime.drawAll(), 25);
});
出于某种原因,我对上下文的 drawImage 函数的调用仅剪辑了图像的左上角,并将其缩放到用户屏幕的大小。为什么我看不到图像的其余部分?
setInterval
函数有问题。您没有提供正确的功能参考。代码
setInterval(prime.drawAll(), 25);
只执行prime.drawAll
一次,结果此时正在加载的图像中只有一小部分被渲染。
正确的代码应该是:
$(document).ready(function(){
var prime = new Prime(window.innerWidth, window.innerHeight);
setInterval(function() {
prime.drawAll();
}, 25);
});
问题是当您调用 setInterval 时图像可能还没有完成加载。如果图像未正确加载和解码,则 drawImage 将 abort its operation:
If the image isn't yet fully decoded, then nothing is drawn
在尝试绘制之前,您需要确保图像已加载。使用图像的 onload
处理程序执行此操作。此操作是异步的,因此这意味着您还需要处理回调(或承诺):
在背景对象中,您需要为图像加载提供回调,例如:
...
background: {
bg: null,
setBg: function(callback) {
this.bg = new Image();
this.bg.onload = callback; // supply onload handler before src
this.bg.src = 'res/background.jpg';
}
},
...
现在设置背景后等待回调,然后继续 drawAll()(尽管,您似乎从未设置背景,这意味着 drawImage 尝试绘制 null
):
$(document).ready(function(){
var prime = new Prime(window.innerWidth, window.innerHeight);
// supply a callback function reference:
prime.background.setBg(callbackImageSet);
// image has loaded, now you can draw the background:
function callbackImageSet() {
setInterval(function() {
prime.drawAll();
}, 25);
};
如果你想绘制完整的图像缩放以适应 canvas 你可以简化调用,只需提供新的大小(并且 this.globalCanvasMain.x/y 似乎没有有待定义?):
drawAll: function(){
this.context.drawImage(this.background.bg, 0,0,
this.globalCanvasMain.w,
this.globalCanvasMain.h);
}
我建议您使用requestAnimationFrame
绘制图像,因为这会与显示器更新同步。
还记得为图像对象上的 onerror
/onabort
提供回调。
构建一个网页,我试图在该网页上将图像设置为主 canvas 的背景。实际图像是 1600x805,我正在尝试对应用程序进行编码,以便它可以根据用户屏幕的尺寸向上或向下缩放图像。在 Prime.js
中,我有一个对象可以设置位于 index.html
中的应用程序的 canvas 元素的属性。这是该对象的代码:
function Prime(w,h){
if(!(function(){
return Modernizr.canvas;
})){ alert('Error'); return false; };
this.context = null;
this.self = this;
this.globalCanvasMain.w = w;
this.globalCanvasMain.h = h;
this.globalCanvasMain.set(this.self);
this.background.setBg();
}
Prime.prototype = {
constructor: Prime,
self: this,
globalCanvasMain: {
x: 0,
y: 0,
set: function(ref){
ref.context = document.getElementById('mainCanvas').getContext('2d');
$("#mainCanvas").parent().css('position', 'relative');
$("#mainCanvas").css({left: this.x, top: this.y, position: 'absolute'});
$("#mainCanvas").width(this.w).height(this.h);
}
},
background: {
bg: null,
setBg: function(){
this.bg = new Image();
this.bg.src = 'res/background.jpg';
}
},
drawAll: function(){
this.context.drawImage(this.background.bg, 0,0, this.background.bg.width,this.background.bg.height,
this.globalCanvasMain.x,this.globalCanvasMain.y, this.globalCanvasMain.w,this.globalCanvasMain.h);
}
};
像这样的外部对象与 index.html
中的元素交互的主要接口是 home.js
。这是那里发生的事情:
$(document).ready(function(){
var prime = new Prime(window.innerWidth,window.innerHeight);
setInterval(prime.drawAll(), 25);
});
出于某种原因,我对上下文的 drawImage 函数的调用仅剪辑了图像的左上角,并将其缩放到用户屏幕的大小。为什么我看不到图像的其余部分?
setInterval
函数有问题。您没有提供正确的功能参考。代码
setInterval(prime.drawAll(), 25);
只执行prime.drawAll
一次,结果此时正在加载的图像中只有一小部分被渲染。
正确的代码应该是:
$(document).ready(function(){
var prime = new Prime(window.innerWidth, window.innerHeight);
setInterval(function() {
prime.drawAll();
}, 25);
});
问题是当您调用 setInterval 时图像可能还没有完成加载。如果图像未正确加载和解码,则 drawImage 将 abort its operation:
If the image isn't yet fully decoded, then nothing is drawn
在尝试绘制之前,您需要确保图像已加载。使用图像的 onload
处理程序执行此操作。此操作是异步的,因此这意味着您还需要处理回调(或承诺):
在背景对象中,您需要为图像加载提供回调,例如:
...
background: {
bg: null,
setBg: function(callback) {
this.bg = new Image();
this.bg.onload = callback; // supply onload handler before src
this.bg.src = 'res/background.jpg';
}
},
...
现在设置背景后等待回调,然后继续 drawAll()(尽管,您似乎从未设置背景,这意味着 drawImage 尝试绘制 null
):
$(document).ready(function(){
var prime = new Prime(window.innerWidth, window.innerHeight);
// supply a callback function reference:
prime.background.setBg(callbackImageSet);
// image has loaded, now you can draw the background:
function callbackImageSet() {
setInterval(function() {
prime.drawAll();
}, 25);
};
如果你想绘制完整的图像缩放以适应 canvas 你可以简化调用,只需提供新的大小(并且 this.globalCanvasMain.x/y 似乎没有有待定义?):
drawAll: function(){
this.context.drawImage(this.background.bg, 0,0,
this.globalCanvasMain.w,
this.globalCanvasMain.h);
}
我建议您使用requestAnimationFrame
绘制图像,因为这会与显示器更新同步。
还记得为图像对象上的 onerror
/onabort
提供回调。