我正在开展我的新项目,我希望在这个项目中显示大约20-30个小png图像的mozaic。所有图像都会重复多次。最后,我希望在csv形状容器周围散布很多图像,这些图像可以移动/摇动一点,也许是鼠标移动。
现在我尝试在javascript中循环遍历图像精灵并在每个循环中更改精灵位置但是......
由于覆盖变量,我有同时显示同一精灵的多个位置的问题。 即使我将某种方式通过,将有一些问题与动画连接到html5画布的规范,我可能必须保存每个图像的一些属性作为画布只是绘制和忘记。 有人可以给我一些关于如何处理我的问题的提示吗?也许有人有类似的项目?我对任何建议和解决方案持开放态度。
这是我开始使用的一些代码,它是在我尝试通过循环更改变量名之前,因为它没有让我更接近解决方案。我为了示例而添加了谷歌图形中的一些随机精灵(暂时没有原创)。
window.onload = function() {
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
for (i = 0; i < 10; i++) {
for (i = 0; i < 5; i++) {
var sprite = new Image();
var swidth = 260;
var sheight = 260;
var randomWidth = Math.random() * document.getElementById('canvas');
var randomHeight = Math.random() * document.getElementById('canvas');
var cx = randomWidth;
var cy = randomHeight;
var sx = i * 260;
var sy = 0;
sprite.onload = function() {
context.drawImage(sprite, sx, sy, swidth, sheight, cx, cy, 260, 213);
};
sprite.src = 'https://cdn.codeandweb.com/blog/2016/05/10/how-to-create-a-sprite-sheet/spritestrip.png';
}
}
}
提前致谢
答案 0 :(得分:0)
只需使用数组或基于数组的列表对象。 Javascript的对象非常灵活,您可以根据需要混合和匹配属性和行为。
在示例中,我创建了一个 //li[./span[contains(text(), 'customToDo')]]/input
对象,其中包含项目列表,一个添加项目的函数(list
),删除所有项目(list.add
)和一个迭代器处理所有项目(list.empty
)
然后加载一个list.eachItem
对象加载一个图像并创建一个精灵表(当我拍摄你的图像并制作动画时作弊与图像大小有关)。精灵Sheet对象还会创建spriteSheet
个对象。
然后我有一些用于渲染和动画精灵的对象,以及一个处理摆动FX的原型对象(用于速度)
然后从名为sprite
的spriteSheet对象中创建一个用于步行动画的精灵表(来自Google Graphic的图像,如OP&#39}中所述),用于创建基本精灵。
然后启动动画循环,调整画布大小以适应页面和创建100个精灵。我首先创建一个只有x,y位置,比例和旋转的基本精灵,然后我从Wobble对象中添加行为。
所有内容都在片段中。单击并按住按钮可以激活动画。
walkSprites
&#13;
const ctx = canvas.getContext("2d");
const U = undefined;
const doFor = (count, callback) => {var i = 0; while (i < count && callback(i ++) !== true ); };
const randI = (min, max = min + (min = 0)) => (Math.random() * (max - min) + min) | 0;
const rand = (min, max = min + (min = 0)) => Math.random() * (max - min) + min;
const mouse = {x : 0, y : 0, button : false}
function mouseEvents(e){
mouse.x = e.pageX;
mouse.y = e.pageY;
mouse.button = e.type === "mousedown" ? true : e.type === "mouseup" ? false : mouse.button;
}
["down","up","move"].forEach(name => document.addEventListener("mouse"+name,mouseEvents));
const list = {
items : null,
add(item){ this.items.push(item); return item },
empty(){ this.items.length = 0 },
eachItem(callback){
var i;
for(i = 0; i < this.items.length; i++){
callback(this.items[i],i);
}
},
}
const spriteSheet = {
image : null,
ready : false,
load(URL){
this.image = new Image;
this.image.src = URL;
this.image.onload = ()=>{
const sprites = [];
const w = this.image.width;
const h = this.image.height;
for(var i = 0; i < w/h; i++){
sprites.push({x : i * h, y : 0, w : h,h : h});
}
this.image.sprites = sprites;
this.ready = true;
}
},
create(index,x,y,scale,rot){
return Object.assign({},sprite,{image:this.image,index,x,y,scale,rot} );
},
}
const sprite = {
draw(){
ctx.setTransform(this.scale,0,0,this.scale,this.x,this.y);
ctx.rotate(this.rot);
const spr = this.image.sprites[this.index];
const w = spr.w;
const h = spr.h;
ctx.drawImage(this.image,spr.x,spr.y,w,h,-w/2,-h/2,w,h);
}
}
function FChase(val,accel,drag){
this.val = val;
this.valChase = 0;
this.valReal = 0;
this.accel = accel;
this.drag = drag;
}
FChase.prototype = {
update(val = this.valReal){
this.valChase += (this.val-this.valReal) * this.accel;
this.valChase *= this.drag;
this.valReal += this.valChase;
return this.valReal;
},
kick(amount){
this.valChase += amount;
},
}
const accel = 0.15;
const drag = 0.7;
const animSpeed = 100;
const wobble = {
init(){
this.xc = new FChase(this.x,accel,drag);
this.yc = new FChase(this.y,accel,drag);
this.rc = new FChase(this.rot,accel,drag);
this.sc = new FChase(this.scale,accel,drag);
this.animSpeed = rand(0.2,1.2);
this.animOffset = rand(1);
return this;
},
update(){
this.index = (((globalTime / animSpeed) * this.animSpeed + this.animOffset * this.image.sprites.length) | 0) % this.image.sprites.length;
this.x = this.xc.update(this.x);
this.y = this.yc.update(this.x);
this.scale = this.sc.update(this.scale);
this.rot = this.rc.update(this.rot);
},
kick(){
this.xc.kick(rand(-40,40));
this.yc.kick(rand(-40,40));
// this.sc.kick(rand(-0.1,0.1));
this.rc.kick(rand(-1,1));
}
}
// create a sprite sheet and load media
const walkSprites = Object.assign({},spriteSheet);
walkSprites.load("https://cdn.codeandweb.com/blog/2016/05/10/how-to-create-a-sprite-sheet/spritestrip.png");
// create a list for the sprites.
const spriteList = Object.assign({},list,{items:[]});
// create 100 sprites
const spriteCount = 100;
function createSprites(){
spriteList.empty();
doFor(spriteCount,i=>{
var spr = spriteList.add(
walkSprites.create(
randI(6), // image may not have loaded, but I know how many sprites there are
randI(canvas.width ), // pos
randI(canvas.height),
rand(0.25,0.5), // scale
rand(Math.PI*2), // rotation
)
);
spr = Object.assign(spr,wobble).init();
})
}
// use requestAnimationFrame to animate
var w = canvas.width;
var h = canvas.height;
var cw = w / 2; // center
var ch = h / 2;
var globalTime;
var frameCount = 0;
// main update function
function update(timer){
globalTime = timer;
frameCount += 1;
ctx.setTransform(1,0,0,1,0,0); // reset transform
ctx.globalAlpha = 1; // reset alpha
if(w !== innerWidth || h !== innerHeight){
cw = (w = canvas.width = innerWidth) / 2;
ch = (h = canvas.height = innerHeight) / 2;
createSprites();
}else{
ctx.clearRect(0,0,w,h);
}
if(walkSprites.ready){
if(mouse.button){
spriteList.eachItem((sprite,i)=>{
if(frameCount % 20 === i % 20){
sprite.kick()
}
});
}
spriteList.eachItem(sprite=>sprite.update());
spriteList.eachItem(sprite=>sprite.draw());
}
requestAnimationFrame(update);
}
requestAnimationFrame(update);
&#13;
canvas, span{ position : absolute; top : 0px; left 0px; }
span {
z-index:10;
font-family:arial black;
font-size:34px;
color : yellow;
}
&#13;