2017-07-01 79 views
0

我正在研究我的新項目,其中我想從大約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

分配一個唯一的ID給每個精靈,或在JS處理程序使用'''this'''所以你指的是觸發事件的精靈。在任何情況下,編輯您的問題以顯示您迄今嘗試過的代碼。 –

+0

請提供[mcve]。 – zer00ne

+0

怎麼樣使用CSS動畫和動畫延遲?然後,您可以從JavaScript從一個類切換到另一個類。如果你知道比例圖像和精靈數量,你也可以一起使用背景大小和高度/寬度這是一個普通的CSS例子來說明這個想法https://codepen.io/gc-nomade/pen/gReWRR –

回答

0

只需使用一個陣列,或基於陣列列表對象。 Javascript對象非常靈活,可以根據需要混合和匹配屬性和行爲。

在這個例子中,我創建一個list對象持有的項目列表,功能添加項目(list.add),刪除所有項目(list.empty),以及處理所有(list.eachItem

一個迭代器然後加載一個圖像並創建精靈表的一個對象spriteSheet(在拍攝您的圖像並計算出動畫時與圖像大小相關的作弊行爲)。 Sprite Sheet對象還會創建sprite對象。

然後,我有用於渲染和動畫化精靈一些對象,和一個原型對象(速度)處理該擺動FX如指出

然後創建用於步行動畫(圖像從谷歌圖形精靈表單OP的問題)來自名爲walkSprites的spriteSheet對象,該對象用於創建基本精靈。

然後開始一個動畫循環,調整畫布大小以適應頁面和創建100個精靈。我首先創建一個只有x,y位置,縮放和旋轉的基本精靈,然後從擺動對象中添加行爲。

全部在片段中。點擊並按住按鈕給動畫踢一腳。

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){ 
 
\t mouse.x = e.pageX; 
 
\t mouse.y = e.pageY; 
 
\t 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);
canvas, span{ position : absolute; top : 0px; left 0px; } 
 
span { 
 
    z-index:10; 
 
    font-family:arial black; 
 
    font-size:34px; 
 
    color : yellow; 
 
}
<span >CLICK HOLD to KICK animations</span> 
 
<canvas id="canvas"></canvas>

+0

謝謝,你完全讓我的一天! – 90mrblue