2014-10-14 3 views
1

캔버스 위의 특정 Y 지점에 도달 할 때마다 바운스되는 것으로 가정되는 드롭 상자 상자의 애니메이션을 만들 필요가 있습니다. 그래서 나는 상자를 떨어 뜨리는 애니메이션을 가지고 있지만 바운스 작업을 할 수는 없습니다. 여기에 내가 쓴 기능은 다음과 같습니다캔버스에 바운싱 박스 애니메이션 만들기

function dropBox(y, width, height) { 
    var img_box = new Image(); 
    img_box.src = 'images/gift_box_small.png'; 

    var box_y_pos = y; 
    if(y==0) 
     box_y_pos = y-img_box.naturalHeight; 


    img_box.onload = function(){ 
     ctx_overlay.save(); 
     ctx_overlay.clearRect(0,0,width,height); 
     ctx_overlay.drawImage(img_box, (width/2)-(img_box.naturalWidth/2), box_y_pos); 
     ctx_overlay.restore(); 
    } 

    box_y_pos += 3; 

    var box_bottom_position = box_y_pos - img_box.naturalHeight; 

    if(box_y_pos+img_box.naturalHeight<height-25) 
     var loopTimer = setTimeout(function() {dropBox(box_y_pos, width, height)},24); 
    else 
     bounceBox(img_box, box_y_pos, box_y_pos, (height/2)-(img_box.naturalHeight/2), "up"); 

} 

function bounceBox(img, img_final_pos, y, midway_pos, direction){ 
    var midway = midway_pos; 
    var direction = direction; 
    var img_y_pos = y; 

    img.onload = function(){ 
     ctx_overlay.save(); 
     ctx_overlay.clearRect(0,0,docWidth,docHeight); 
     ctx_overlay.drawImage(img, (docWidth/2)-(img.naturalWidth/2), img_y_pos); 
     ctx_overlay.restore(); 
    } 

    for(var i = 0; i < 10; i++){ 
     if(direction=="up"){ 
      //going up 
      if(img_y_pos>midway_){ 
       img_y_pos -= 3; 
       var loopTimer = setTimeout(function() {bounceBox(img, img_final_pos, img_y_pos, midway_pos, "up")},24); 
      } else { 
       img_y_pos += 3; 
       midway = Math.floor(midway /= 2); 
       if(midway%2>0) 
        midway += 1; 
       var loopTimer = setTimeout(function() {bounceBox(img, img_final_pos, img_y_pos, midway_pos, "down")},24); 
      } 
     } else { 
      //going down 
      if(img_y_pos < img_final_pos){ 
       img_y_pos += 3; 
       var loopTimer = setTimeout(function() {bounceBox(img, img_final_pos, img_y_pos, midway_pos, "down")},24); 
      } 
     } 
    } 
} 

JSFiddle : http://jsfiddle.net/n2derqgw/3/

왜 작동하지 않으며 나는 그것이 작동하는 방법을 만들 수 있습니까?

+0

다음이야 올바른 의사 소통을위한 의사 코드. 'If ​​(Box_Y + Box_VY> = canvas_height) Box_VY * = - 1;'기본적으로 어떻게 할 것인가 (변수를 사용하지 않는 것)는 상자의 위치가 캔버스의 높이보다 큰 경우, 상자의 방향. 나는 애니메이션을 할 때 draw 함수 내에서 (청결 함을 위해서) 별도의 함수 호출로 단일 그리기 함수를 호출하는 단일'setInterval() '을 가지고있다. 모양을 그릴 때 나는 보통 속도 변수와 위치 변수를 가지고 있습니다. 예 :'Box_VY'. Box_VY가 Y보다 낮을 경우 – Brendan

답변

1

두통을 피하려면 setInterval이라는 단일 함수 내에서 애니메이션을 처리하는 것이 좋습니다.
모든 애니메이션 관련 데이터를 하나의 개체에 보관하십시오.
그래서 아래의 코드는 당신이 원하지 않는 정확하게,하지만 당신은 시작해야

http://jsfiddle.net/n2derqgw/4/

설정 :

var canvas_overlay, ctx_overlay, docWidth, docHeight; 

var img_box = new Image(); 
img_box.src = 'http://corkeynet.com/test/images/gift_box_small.png'; 

var mustBeReadyCount = 2; // must load image and window 

img_box.onload = launchWhenReady; 
window.onload = launchWhenReady; 

var animationStep = ''; 
var boxAnimationData = { 
    animationStep: '', 
    y: 0, 
    maxY: 0, 
    bounceCount: 6, 
    direction: -1, 
    bounceHeight: 0 
}; 

function launchWhenReady() { 
    mustBeReadyCount--; 
    if (mustBeReadyCount) return; 
    docWidth = window.innerWidth; 
    docHeight = window.innerHeight; 
    canvas_overlay = document.getElementById('canvas_overlay'); 
    ctx_overlay = canvas_overlay.getContext('2d'); 
    resizeCanvas(docWidth, docHeight); 
    boxAnimationData.animationStep = 'falling'; 
    boxAnimationData.bounceHeight = docHeight/2 - img_box.height; 
    setInterval(animateBox, 30); 
}; 

더 흥미로운 코드가 여기에 있습니다 :

function animateBox() { 
    if (boxAnimationData.animationStep == 'falling') dropBox(); 
    else if (boxAnimationData.animationStep == 'bouncing') bounceBox(); 
} 

function dropBox() { 
    ctx_overlay.clearRect(0, 0, docWidth, docHeight); 
    boxAnimationData.y += 3; 
    if (boxAnimationData.y + img_box.height > docHeight) { 
     boxAnimationData.animationStep = 'bouncing'; 
    } 
    ctx_overlay.drawImage(img_box, (docWidth/2) - (img_box.width/2), boxAnimationData.y); 
} 


function bounceBox() { 
    ctx_overlay.clearRect(0, 0, docWidth, docHeight); 
    boxAnimationData.y += boxAnimationData.direction * 3; 
    if (boxAnimationData.y + img_box.height > docHeight) { 
     // reached floor ? swap direction 
     boxAnimationData.direction *= -1; 
     // and reduce jump height 
     boxAnimationData.bounceHeight *= 3/2; 
     boxAnimationData.bounceCount--; 
     if (!boxAnimationData.bounceCount) boxAnimationData.animationStep = ''; 

    } else if (boxAnimationData.y < boxAnimationData.bounceHeight) { 
     boxAnimationData.direction *= -1; 
    } 
    ctx_overlay.drawImage(img_box, (docWidth/2) - (img_box.width/2), boxAnimationData.y); 
} 
+0

사실 내가 원한 것입니다! 그냥 몇 가지 매개 변수를 변경하고 잘 작동했습니다. 문제는 지금 제가 페이지에있는 다른 애니메이션과 결합하려고 할 때입니다 : 다른 애니메이션을 보았지만 상자가 보이지 않습니다 : http://jsfiddle.net/n2derqgw/6/ 무엇이 잘못 되었습니까? ? – Igal

+0

작업을 수행하는 가장 좋은 방법은 한 번만로드 로딩 문제를 해결하는 것입니다. 필요한 모든 이미지를로드 한 다음 응용 프로그램을 시작하십시오. 이렇게하면 코드를 살펴볼 것입니다. 환호 – GameAlchemist

+0

신경 쓰지 마라, 나는 마침내 그것을 일하게했다! 당신의 도움을 주셔서 대단히 감사합니다! :) – Igal