2016-03-30 2 views
0

Wenn Sie den folgenden Code ausführen, werden Sie bemerken, dass der y-Wert wie erwartet in der Konsole ansteigt. Der Kreis auf der Leinwand bewegt sich jedoch nicht wie erwartet entlang der y-Achse. Hat jemand eine Idee warum?Canvas-Animation funktioniert nicht wie vorgesehen

Wenn Sie bis zur render() Funktion scrollen, werden Sie sehen, dass ich mit y += 5; y erhöhen.

'use strict'; 
 

 
(function() { 
 

 
    const canvas = document.getElementsByClassName('canvas')[0], 
 
     c = canvas.getContext('2d'); 
 

 
    // Circle 
 
    var circleRadius = 50, 
 
     x = (canvas.width/2) - circleRadius, // inital x position of the ball 
 
     y = (canvas.height/2) - circleRadius, // inital y position of the ball 
 
     segments = 4, 
 
     bezieCircleFormula = (4/3)*Math.tan(Math.PI/(2*segments)), // http://stackoverflow.com/a/27863181/2040509 
 
     pointOffset = { 
 
     positive: bezieCircleFormula*circleRadius, 
 
     negative: circleRadius-(bezieCircleFormula*circleRadius) 
 
     }, 
 
     // Each side has 3 points, bezier 1, circle point, bezier 2 
 
     // These are listed below in clockwise order. 
 
     // So top has: left bezier, circle point, right bezier 
 
     // Right has: top bezier, circle point, bottom bezier 
 
     circlePoints = { 
 
     top: [ 
 
      [x+pointOffset.negative, y], 
 
      [x+circleRadius, y], 
 
      [x+pointOffset.positive+circleRadius, y] 
 
     ], 
 
     right: [ 
 
      [x+circleRadius*2, y+pointOffset.negative], 
 
      [x+circleRadius*2, y+circleRadius], 
 
      [x+circleRadius*2, y+pointOffset.positive+circleRadius] 
 
     ], 
 
     bottom: [ 
 
      [x+pointOffset.positive+circleRadius, y+circleRadius*2], 
 
      [x+circleRadius, y+circleRadius*2], 
 
      [x+pointOffset.negative, y+circleRadius*2] 
 
     ], 
 
     left: [ 
 
      [x, y+pointOffset.positive+circleRadius], 
 
      [x, y+circleRadius], 
 
      [x, y+pointOffset.negative] 
 
     ] 
 
     }; 
 

 
    // For `side` you can pass `top`, `right`, `bottom`, `left` 
 
    // For `amount` use an interger 
 
    function squish (side, squishAmount) { 
 
    for (let i = 0; i < circlePoints[side].length; i++) { 
 
     if (side === 'top') { 
 
     circlePoints[side][i][1] += squishAmount; 
 
     } else if (side === 'right') { 
 
     circlePoints[side][i][0] -= squishAmount; 
 
     } else if (side === 'bottom') { 
 
     circlePoints[side][i][1] -= squishAmount; 
 
     } else if (side === 'left') { 
 
     circlePoints[side][i][0] += squishAmount; 
 
     } 
 
    } 
 
    } 
 

 
    function render() { 
 

 
    // Clear the canvas 
 
    c.clearRect(0, 0, canvas.width, canvas.height); 
 

 
    // Draw a circle using bezier curves 
 
    c.beginPath(); 
 
    c.moveTo(circlePoints.left[1][0], circlePoints.left[1][1]); 
 
    c.bezierCurveTo(circlePoints.left[2][0], circlePoints.left[2][1], circlePoints.top[0][0], circlePoints.top[0][1], circlePoints.top[1][0], circlePoints.top[1][1]); 
 
    c.bezierCurveTo(circlePoints.top[2][0], circlePoints.top[2][1], circlePoints.right[0][0], circlePoints.right[0][1], circlePoints.right[1][0], circlePoints.right[1][1]); 
 
    c.bezierCurveTo(circlePoints.right[2][0], circlePoints.right[2][1], circlePoints.bottom[0][0], circlePoints.bottom[0][1], circlePoints.bottom[1][0], circlePoints.bottom[1][1]); 
 
    c.bezierCurveTo(circlePoints.bottom[2][0], circlePoints.bottom[2][1], circlePoints.left[0][0], circlePoints.left[0][1], circlePoints.left[1][0], circlePoints.left[1][1]); 
 
    c.stroke(); 
 
    c.closePath(); 
 

 
    // Doing this for animation 
 
    y += 5; 
 

 
    console.log(y); 
 

 
    requestAnimationFrame(render); 
 
    } 
 

 
    render(); 
 

 
})();
<canvas class="canvas" width="200" height="200"></canvas>

Antwort

2

Da y wirkt sich nicht auf den Kreis in keiner Weise. Es wird verwendet, um circlePoints zu generieren, indem der Wert von y in diesem Moment als Wert übergeben wird, sodass alle Änderungen, die an y vorgenommen wurden, nicht in circlePoints widergespiegelt werden. Sie müssen circlePoints aktualisieren, wenn Sie diese Änderungen sehen wollen, weil sie nicht dynamisch aktualisiert werden, da y ein primitive ist und somit als Wert übergeben:

'use strict'; 
 

 
(function() { 
 

 
    const canvas = document.getElementsByClassName('canvas')[0], 
 
     c = canvas.getContext('2d'); 
 

 
    // Circle 
 
    var circleRadius = 50, 
 
     x = (canvas.width/2) - circleRadius, // inital x position of the ball 
 
     y = (canvas.height/2) - circleRadius, // inital y position of the ball 
 
     segments = 4, 
 
     bezieCircleFormula = (4/3)*Math.tan(Math.PI/(2*segments)), // http://stackoverflow.com/a/27863181/2040509 
 
     pointOffset = { 
 
     positive: bezieCircleFormula*circleRadius, 
 
     negative: circleRadius-(bezieCircleFormula*circleRadius) 
 
     }, 
 
     // Each side has 3 points, bezier 1, circle point, bezier 2 
 
     // These are listed below in clockwise order. 
 
     // So top has: left bezier, circle point, right bezier 
 
     // Right has: top bezier, circle point, bottom bezier 
 
     circlePoints = { 
 
     top: [ 
 
      [x+pointOffset.negative, y], 
 
      [x+circleRadius, y], 
 
      [x+pointOffset.positive+circleRadius, y] 
 
     ], 
 
     right: [ 
 
      [x+circleRadius*2, y+pointOffset.negative], 
 
      [x+circleRadius*2, y+circleRadius], 
 
      [x+circleRadius*2, y+pointOffset.positive+circleRadius] 
 
     ], 
 
     bottom: [ 
 
      [x+pointOffset.positive+circleRadius, y+circleRadius*2], 
 
      [x+circleRadius, y+circleRadius*2], 
 
      [x+pointOffset.negative, y+circleRadius*2] 
 
     ], 
 
     left: [ 
 
      [x, y+pointOffset.positive+circleRadius], 
 
      [x, y+circleRadius], 
 
      [x, y+pointOffset.negative] 
 
     ] 
 
     }; 
 

 
    // For `side` you can pass `top`, `right`, `bottom`, `left` 
 
    // For `amount` use an interger 
 
    function squish (side, squishAmount) { 
 
    for (let i = 0; i < circlePoints[side].length; i++) { 
 
     if (side === 'top') { 
 
     circlePoints[side][i][1] += squishAmount; 
 
     } else if (side === 'right') { 
 
     circlePoints[side][i][0] -= squishAmount; 
 
     } else if (side === 'bottom') { 
 
     circlePoints[side][i][1] -= squishAmount; 
 
     } else if (side === 'left') { 
 
     circlePoints[side][i][0] += squishAmount; 
 
     } 
 
    } 
 
    } 
 

 
    function render() { 
 
    
 
    circlePoints = { 
 
     top: [ 
 
      [x+pointOffset.negative, y], 
 
      [x+circleRadius, y], 
 
      [x+pointOffset.positive+circleRadius, y] 
 
     ], 
 
     right: [ 
 
      [x+circleRadius*2, y+pointOffset.negative], 
 
      [x+circleRadius*2, y+circleRadius], 
 
      [x+circleRadius*2, y+pointOffset.positive+circleRadius] 
 
     ], 
 
     bottom: [ 
 
      [x+pointOffset.positive+circleRadius, y+circleRadius*2], 
 
      [x+circleRadius, y+circleRadius*2], 
 
      [x+pointOffset.negative, y+circleRadius*2] 
 
     ], 
 
     left: [ 
 
      [x, y+pointOffset.positive+circleRadius], 
 
      [x, y+circleRadius], 
 
      [x, y+pointOffset.negative] 
 
     ] 
 
     }; 
 

 
    // Clear the canvas 
 
    c.clearRect(0, 0, canvas.width, canvas.height); 
 

 
    // Draw a circle using bezier curves 
 
    c.beginPath(); 
 
    c.moveTo(circlePoints.left[1][0], circlePoints.left[1][1]); 
 
    c.bezierCurveTo(circlePoints.left[2][0], circlePoints.left[2][1], circlePoints.top[0][0], circlePoints.top[0][1], circlePoints.top[1][0], circlePoints.top[1][1]); 
 
    c.bezierCurveTo(circlePoints.top[2][0], circlePoints.top[2][1], circlePoints.right[0][0], circlePoints.right[0][1], circlePoints.right[1][0], circlePoints.right[1][1]); 
 
    c.bezierCurveTo(circlePoints.right[2][0], circlePoints.right[2][1], circlePoints.bottom[0][0], circlePoints.bottom[0][1], circlePoints.bottom[1][0], circlePoints.bottom[1][1]); 
 
    c.bezierCurveTo(circlePoints.bottom[2][0], circlePoints.bottom[2][1], circlePoints.left[0][0], circlePoints.left[0][1], circlePoints.left[1][0], circlePoints.left[1][1]); 
 
    c.stroke(); 
 
    c.closePath(); 
 

 
    // Doing this for animation 
 
    y += 5; 
 

 
    console.log(y); 
 

 
    requestAnimationFrame(render); 
 
    } 
 

 
    render(); 
 

 
})();
<canvas class="canvas" width="200" height="200"></canvas>

+0

Right! danke für die heads up, ich wusste, dass ich etwas wirklich offensichtlich verpasst habe. – MarioD

+2

Gern geschehen. Es ist normalerweise eine gute Idee, die Werte aller Variablen zu protokollieren, die die Ursache des Problems sein könnten (in Ihrem Fall Variablen, die sich unmittelbar auf die Zeichnung des Kreises auswirken) - Sie haben diesen Fehler in kürzester Zeit erfasst. – Shomz