2015-08-31 120 views
3

我想創建一個動畫,其中的圓圈從右向左運行。圓的顏色是通過函數隨機選擇的。我創建了一個fiddle,其中一個圓圈從右向左運行。現在我的函數創建一個隨機顏色。該功能每秒鐘執行一次,並且圓圈每秒都會改變其顏色,而不是創建隨機選取顏色的新圓。我怎樣才能改變它,使它在畫布上每秒都畫一個新的圓圈,而不僅僅是改變圓的顏色?在畫布上繪製隨機彩色圓圈

這是我的函數:

function getRandomElement(array) { 
    if (array.length == 0) { 
    return undefined; 
    } 
    return array[Math.floor(Math.random() * array.length)]; 
} 

var circles = [ 
    '#FFFF00', 
    '#FF0000', 
    '#0000FF' 
]; 


function drawcircles() { 


ctx.beginPath(); 
     ctx.arc(ballx * 108, canvasHeight/2, x*5, 0, 2*Math.PI, false); 
     ctx.fillStyle = getRandomElement(circles); 
     ctx.fill(); 
ctx.closePath; 

} 
+0

不要忘記,你必須重新繪製的一切,每一幀。 您可以使用包含具有像'radius,x,y,color'等屬性的對象的數組來表示您的圓。 然後,循環訪問數組以獲取這些值來繪製圓並更新它們以使圓移動。 最後要在您的畫布上添加一個新的圓圈,您只需在您的圓圈中推送一個新對象Arrayray – Lauromine

+0

使用['window.setTimeout']遞歸(https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout)將避免級聯失敗,其中繪製時間可能比間隔更長。另外,你似乎沒有調用'closePath' –

+0

@PaulS。比使用requestAnimationFrame更好嗎?我很好奇 – Lauromine

回答

1

對你的問題的評論:

您正在改變填充樣式的顏色,在每一幀隨機顏色。這就是它保持「變化」顏色的原因。其設置爲圓的顏色:

context.fillStyle = circle.color; 
  1. 使用陣列
  2. 拉伸使與X,Y,直徑,反彈力,速度和顏色圓圈和使用requestAnimationFrame更新它們(我的是一個自定義功能)

我的回答:

我做了這個就在昨天晚上,在某些圈子裏跟隨光標和「反彈」○在屏幕的邊緣。我測試了代碼,它的工作原理。

我以後可能會發佈一個鏈接,但這裏是所有的代碼現在...

<!DOCTYPE html> 
<html> 
<body> 
    <canvas id="canvas"></canvas> 
    <script> 
     var lastTime = 0; 
     function requestMyAnimationFrame(callback, time) 
     { 
      var t = time || 16; 
      var currTime = new Date().getTime(); 
      var timeToCall = Math.max(0, t - (currTime - lastTime)); 
      var id = window.setTimeout(function(){ callback(currTime + timeToCall); }, timeToCall); 
      lastTime = currTime + timeToCall; 
      return id; 
     } 
     var canvas = document.getElementById("canvas"); 
     var context = canvas.getContext("2d"); 
     canvas.width = window.innerWidth - 20; 
     canvas.height = window.innerHeight - 20; 
     canvas.style.width = canvas.width + "px"; 
     canvas.style.height = canvas.height + "px"; 
     var circles = []; 
     var mouse = 
     { 
      x: 0, 
      y: 0 
     } 
     function getCoordinates(x, y) 
     { 
      return "(" + x + ", " + y + ")"; 
     } 
     function getRatio(n, d) 
     { 
      // prevent division by 0 
      if (d === 0 || n === 0) 
      { 
       return 0; 
      } 
      else 
      { 
       return n/d; 
      } 
     } 
     function Circle(x,y,d,b,s,c) 
     { 
      this.x = x; 
      this.y = y; 
      this.diameter = Math.round(d); 
      this.radius = Math.round(d/2); 
      this.bounciness = b; 
      this.speed = s; 
      this.color = c; 
      this.deltaX = 0; 
      this.deltaY = 0; 
      this.drawnPosition = ""; 
      this.fill = function() 
      { 
       context.beginPath(); 
       context.arc(this.x+this.radius,this.y+this.radius,this.radius,0,Math.PI*2,false); 
       context.closePath(); 
       context.fill(); 
      } 
      this.clear = function() 
      { 
       context.fillStyle = "#ffffff"; 
       this.fill(); 
      } 
      this.draw = function() 
      { 
       if (this.drawnPosition !== getCoordinates(this.x, this.y)) 
       { 
        context.fillStyle = this.color; 
        // if commented, the circle will be drawn if it is in the same position 
        //this.drawnPosition = getCoordinates(this.x, this.y); 
        this.fill(); 
       } 
      } 
      this.keepInBounds = function() 
      { 
       if (this.x < 0) 
       { 
        this.x = 0; 
        this.deltaX *= -1 * this.bounciness; 
       } 
       else if (this.x + this.diameter > canvas.width) 
       { 
        this.x = canvas.width - this.diameter; 
        this.deltaX *= -1 * this.bounciness; 
       } 
       if (this.y < 0) 
       { 
        this.y = 0; 
        this.deltaY *= -1 * this.bounciness; 
       } 
       else if (this.y+this.diameter > canvas.height) 
       { 
        this.y = canvas.height - this.diameter; 
        this.deltaY *= -1 * this.bounciness; 
       } 
      } 
      this.followMouse = function() 
      { 
       // deltaX/deltaY will currently cause the circles to "orbit" around the cursor forever unless it hits a wall 
       var centerX = Math.round(this.x + this.radius); 
       var centerY = Math.round(this.y + this.radius); 
       if (centerX < mouse.x) 
       { 
        // circle is to the left of the mouse, so move the circle to the right 
        this.deltaX += this.speed; 
       } 
       else if (centerX > mouse.x) 
       { 
        // circle is to the right of the mouse, so move the circle to the left 
        this.deltaX -= this.speed; 
       } 
       else 
       { 
        //this.deltaX = 0; 
       } 
       if (centerY < mouse.y) 
       { 
        // circle is above the mouse, so move the circle downwards 
        this.deltaY += this.speed; 
       } 
       else if (centerY > mouse.y) 
       { 
        // circle is under the mouse, so move the circle upwards 
        this.deltaY -= this.speed; 
       } 
       else 
       { 
        //this.deltaY = 0; 
       } 
       this.x += this.deltaX; 
       this.y += this.deltaY; 
       this.x = Math.round(this.x); 
       this.y = Math.round(this.y); 
      } 
     } 
     function getRandomDecimal(min, max) 
     { 
      return Math.random() * (max-min) + min; 
     } 
     function getRoundedNum(min, max) 
     { 
      return Math.round(getRandomDecimal(min, max)); 
     } 
     function getRandomColor() 
     { 
      // array of three colors 
      var colors = []; 
      // go through loop and add three integers between 0 and 255 (min and max color values) 
      for (var i = 0; i < 3; i++) 
      { 
       colors[i] = getRoundedNum(0, 255); 
      } 
      // return rgb value (RED, GREEN, BLUE) 
      return "rgb(" + colors[0] + "," + colors[1] + ", " + colors[2] + ")"; 
     } 
     function createCircle(i) 
     { 
      // diameter of circle 
      var minDiameter = 25; 
      var maxDiameter = 50; 
      // bounciness of circle (changes speed if it hits a wall) 
      var minBounciness = 0.2; 
      var maxBounciness = 0.65; 
      // speed of circle (how fast it moves) 
      var minSpeed = 0.3; 
      var maxSpeed = 0.45; 
      // getRoundedNum returns a random integer and getRandomDecimal returns a random decimal 
      var x = getRoundedNum(0, canvas.width); 
      var y = getRoundedNum(0, canvas.height); 
      var d = getRoundedNum(minDiameter, maxDiameter); 
      var c = getRandomColor(); 
      var b = getRandomDecimal(minBounciness, maxBounciness); 
      var s = getRandomDecimal(minSpeed, maxSpeed); 
      // create the circle with x, y, diameter, bounciness, speed, and color 
      circles[i] = new Circle(x,y,d,b,s,c); 
     } 
     function makeCircles() 
     { 
      var maxCircles = getRoundedNum(2, 5); 
      for (var i = 0; i < maxCircles; i++) 
      { 
       createCircle(i); 
      } 
     } 
     function drawCircles() 
     { 
      var ii = 0; 
      for (var i = 0; ii < circles.length; i++) 
      { 
       if (circles[i]) 
       { 
        circles[i].draw(); 
        ii++; 
       } 
      } 
     } 
     function clearCircles() 
     { 
      var ii = 0; 
      for (var i = 0; ii < circles.length; i++) 
      { 
       if (circles[i]) 
       { 
        circles[i].clear(); 
        ii++; 
       } 
      } 
     } 
     function updateCircles() 
     { 
      var ii = 0; 
      for (var i = 0; ii < circles.length; i++) 
      { 
       if (circles[i]) 
       { 
        circles[i].keepInBounds(); 
        circles[i].followMouse(); 
        ii++; 
       } 
      } 
     } 
     function update() 
     { 
      requestMyAnimationFrame(update,10); 
      updateCircles(); 
     } 
     function draw() 
     { 
      requestMyAnimationFrame(draw,1000/60); 
      context.clearRect(0,0,canvas.width,canvas.height); 
      drawCircles(); 
     } 
     function handleError(e) 
     { 
      //e.preventDefault(); 
      //console.error(" ERROR ------ " + e.message + " ------ ERROR "); 
     } 
     window.addEventListener("load", function() 
     { 
      window.addEventListener("error", function(e) 
      { 
       handleError(e); 
      }); 
      window.addEventListener("resize", function() 
      { 
       canvas.width = window.innerWidth - 20; 
       canvas.height = window.innerHeight - 20; 
      }); 
      window.addEventListener("mousemove", function(e) 
      { 
       mouse.x = e.layerX || e.offsetX; 
       mouse.y = e.layerY || e.offsetY; 
      }); 
      makeCircles(); 
      update(); 
      draw(); 
     }); 
    </script> 
</body> 
</html>