比如我的drawStars()里面要写入一张图片,我用window.requestAnimationFrame的话,就不需要img.onload = function(){}图片就可以直接显示出来,若再用img.onload = function(){}就加载不出来图片了;但是我不用window.requestAnimationFrame,就必须写img.onload = function(){}才能加载出来图片。
而且:我不用window.requestAnimationFrame的话,在img.onload以后写入的图片会出现在canvas (0,0)的位置;但是用window.requestAnimationFrame的话,就能出现在指定的this.x, this.y位置
用window.requestAnimationFrame的代码如下:
<script type="text/javascript">
var can;
var ctx;
var width;
var height;
var num = 60; //星星的数量
var stars = []; //定义一个数组
var girl_img = new Image();
var stars_img = new Image();
// requestAnimFrame循环,它会根据浏览器自动设置循环刷新时间
window.requestAnimFrame = (function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
return window.setTimeout(callback, 1000 / 60);
};
})();
// 初始化canvas
function init(){
can = document.getElementById("canvas");
ctx = can.getContext("2d");
width = can.width;
height = can.height;
girl_img.src = "../例程/src/girl.jpg";
stars_img.src = "../例程/src/star.png";
for(var i=0; i<num; i++){
var obj = new star_obj(); //创建一个实体对象
stars.push(obj); //把对象放入stars数组的最后
stars[i].initStars(); //执行star_obj的init方法
}
gameLoop();
}
// 画背景图
function drawBackground(){
ctx.fillStyle = "cornflowerblue";
ctx.fillRect(0,0,width,height);
}
// 插入女孩儿图片
function drawGirl(){
//girl_img.onload = function(){ //当drawBackground()没写在gameLoop()里面的时候一定要写这句;当drawBackground()写在gameLoop()里面的时候一定不要写这句;等图片加载完,是girl_img.onload!!!;
ctx.drawImage(girl_img,100,150,600,300);
//}
}
// 序列帧,每个一段时间刷新一下,让图片看起来是动的
function gameLoop(){
window.requestAnimationFrame(gameLoop); //序列帧循环;()里面是回调函数,一直循环自己这个gameLoop函数
drawBackground();
drawGirl();
drawStars();
}
/****************************画很多星星****************************/
// 创建类(类就是一套规则;对一群具有相同特征的对象的集合的描述)
// function star_obj()
var star_obj = function(){
this.x; //this是泛指,当用new通过star_obj规则创建一个具体的对象,则this指向那个具体对象
this.y;
}
// 给类定义一些方法
// 定义init初始化方法
star_obj.prototype.initStars = function(){
this.x = Math.floor(Math.random()*601+100);
this.y = Math.floor(Math.random()*301+150);
}
// 定义draw方法
star_obj.prototype.draw = function(){ //注意:这里star_obj不能带()!!!
// stars_img.onload = function(){ //当drawBackground()没写在gameLoop()里面的时候一定要写这句;当drawBackground()写在gameLoop()里面的时候一定不要写这句;等js里面的stars_img加载完,再写入图片位置
ctx.drawImage(stars_img, this.x, this.y);
// }
}
// 随机生成星星方法
function drawStars(){
for(var i=0; i<num; i++){
stars[i].draw();
}
}
init();
</script>
显示效果:
用img.onload = function(){}的代码如下:
var can;
var ctx;
var width;
var height;
var num = 60; //星星的数量
var stars = []; //定义一个数组
var girl_img = new Image();
var stars_img = new Image();
// requestAnimFrame循环,它会根据浏览器自动设置循环刷新时间
window.requestAnimFrame = (function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
return window.setTimeout(callback, 1000 / 60);
};
})();
// 初始化canvas
function init(){
can = document.getElementById("canvas");
ctx = can.getContext("2d");
width = can.width;
height = can.height;
girl_img.src = "../例程/src/girl.jpg";
stars_img.src = "../例程/src/star.png";
for(var i=0; i<num; i++){
var obj = new star_obj(); //创建一个实体对象
stars.push(obj); //把对象放入stars数组的最后
stars[i].initStars(); //执行star_obj的init方法
}
}
// 画背景图
function drawBackground(){
ctx.fillStyle = "cornflowerblue";
ctx.fillRect(0,0,width,height);
}
// 插入女孩儿图片
function drawGirl(){
girl_img.onload = function(){ //当drawBackground()没写在gameLoop()里面的时候一定要写这句;当drawBackground()写在gameLoop()里面的时候一定不要写这句;等图片加载完,是girl_img.onload!!!;
ctx.drawImage(girl_img,100,150,600,300);
}
}
/****************************画很多星星****************************/
// 创建类(类就是一套规则;对一群具有相同特征的对象的集合的描述)
// function star_obj()
var star_obj = function(){
this.x; //this是泛指,当用new通过star_obj规则创建一个具体的对象,则this指向那个具体对象
this.y;
}
// 给类定义一些方法
// 定义init初始化方法
star_obj.prototype.initStars = function(){
this.x = Math.floor(Math.random()*601+100);
this.y = Math.floor(Math.random()*301+150);
}
// 定义draw方法
star_obj.prototype.draw = function(){ //注意:这里star_obj不能带()!!!
stars_img.onload = function(){ //当drawBackground()没写在gameLoop()里面的时候一定要写这句;当drawBackground()写在gameLoop()里面的时候一定不要写这句;等js里面的stars_img加载完,再写入图片位置
ctx.drawImage(stars_img, this.x, this.y);
}
}
// 随机生成星星方法
function drawStars(){
for(var i=0; i<num; i++){
stars[i].draw();
}
}
init();
drawBackground();
drawGirl();
drawStars();
显示效果:
我想要的是图1的效果,但是我不用window.requestAnimFrame,用onload等图片加载出来,为什么stars_img显示的不是我让它在的地方呢?还有就是为什么用window.requestAnimFrame就不用onload加载以后再执行之后的程序了,写了onload反而加载不出来了。
draw方法里不需要添加img onload事件,直接像下面这么写即可:
最后统一在
window.onload
里执行逻辑: