将渐变应用于画布和移动球

时间:2018-10-05 23:59:35

标签: javascript animation canvas gradient

尝试在画布上应用线性渐变并移动球,但是我不知道哪里出错了,因为没有任何变化。我正在尝试每次加载时随机施加颜色随机的角度。我认为问题出在创建线性渐变时的onload函数中

var $ = function(id) {return document.getElementById(id);};

var bounce;
var my_canvas;
var ball_array = new Array();
var linear_gradient;
var timer; //global variable to keep current timer

function randomGradient()
{
var color1 = randomColor(); //color 1
var color2 = '#FFFFFF'; //color 2
var gradient_angle = Math.round(Math.random()*360);
var random_gradient = "linear-gradient(" + gradient_angle + "deg, " + color1 + ", " + color2 + ")";
return random_gradient;
}

function ball(){
this.x=Math.random()*my_canvas.canvas.width;
this.y=Math.random()*my_canvas.canvas.height;
this.vx = (Math.random()-0.5);
this.vy = (Math.random()-0.5);
 this.color = randomGradient();
 this.radius = 12;
this.move=ball_move;
this.draw=ball_draw;
 }
 function ball_draw(){                    
 my_canvas.save();
 my_canvas.fillStyle=this.color; //****
 my_canvas.strokeStyle='black';
 my_canvas.lineWidth=2;
 my_canvas.beginPath();
my_canvas.arc(this.x, this.y, this.radius,0, 6.28, false);
 my_canvas.closePath();
 my_canvas.stroke();
 my_canvas.fill();
 my_canvas.restore();
 }

 function create_balls(){
 for(var i=0;i<75;i++){
    var temp=new ball();
    ball_array.push(temp);
 }
 }
    function resize_can(){
my_canvas.canvas.width = window.innerWidth/2;
my_canvas.canvas.height = window.innerHeight/2;
    }

    window.onload = function() {
    bounce = -1;
    my_canvas = $("myCanvas").getContext('2d');
    linear_gradient = my_canvas.createLinearGradient(0,0,window.innerWidth / 2,window.innerHeight / 2); //create linear gradient
    window.onresize = resize_can;
    resize_can(); 
    create_balls();
    timer = setInterval(going,5);
  };

2 个答案:

答案 0 :(得分:2)

您需要使用画布创建渐变,不能只使用线性渐变CSS字符串

ctx.fillStyle = "linear-gradient(50%, red, blue)";  // WON'T WORK!

使用

const gradient = ctx.createLinearGradient(0, 0, width, height);
gradient.addColorStop(0, "black");
gradient.addColorStop(1, "white");

最重要的是,渐变是相对于原点的,因此,如果要使渐变相对于圆保持相对,则在绘制时需要平移原点。换句话说,代替

ctx.arc(x, y, ...)

您需要

ctx.translate(x, y);
ctx.arc(0, 0, ...)

请注意,我对“ modern”的一些定义将您的代码更改为更现代的JS。例如,在适当的地方使用constlet,从不使用var,使用class,使用requestAnimationFrame,计算帧之间的增量时间并制作动画帧与速率无关,使用querySelector代替getElementById,使用[]代替new Array,摆脱window.onload(将脚本放在文件末尾或使用defer,使用ctxmy_canvasmy_canvas没什么问题,除了它不是“画布”,它是“画布上下文”或更具体地说是{{3} }

const $ = function(selector) {
  return document.querySelector(selector);
};

const ctx = $("#myCanvas").getContext('2d');
const ball_array = [];

function randomColor() {
  return `hsl(${Math.random() * 360}, 100%, 50%)`;
}

function randomGradient(size) {
  const gradient = ctx.createLinearGradient(-size, 0, size, 0);
  gradient.addColorStop(0, randomColor());
  gradient.addColorStop(1, '#FFFFFF');
  return gradient;
}

// JS style, constructors are always Capitalized
class Ball {
  constructor() {
    this.x = Math.random() * ctx.canvas.width;
    this.y = Math.random() * ctx.canvas.height;
    this.vx = (Math.random() - 0.5) * 50;
    this.vy = (Math.random() - 0.5) * 50;
    this.radius = 12;
    this.color = randomGradient(this.radius);
    this.angle = Math.random() * Math.PI * 2;
  }

  draw() {
    ctx.save();
    ctx.fillStyle = this.color; //****
    ctx.strokeStyle = 'black';
    ctx.lineWidth = 2;
    ctx.translate(this.x, this.y);
    ctx.rotate(this.angle);  // because you wanted the gradient at a random angle
    ctx.beginPath();
    ctx.arc(0, 0, this.radius, 0, 6.28, false);
    ctx.closePath();
    ctx.stroke();
    ctx.fill();
    ctx.restore();
  }

  move(deltaTime) {
    // you didn't provide this code so I made something up.
    this.x = (this.x + this.vx * deltaTime + ctx.canvas.width) % ctx.canvas.width;
    this.y = (this.y + this.vy * deltaTime + ctx.canvas.height) % ctx.canvas.height;
  }
};

let then = 0;
function going(now) {
  now *= 0.001;  // convert to seconds
  const deltaTime = now - then;
  then = now;

  ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
  ball_array.forEach((ball) => {
    ball.move(deltaTime);
    ball.draw();
  });
  requestAnimationFrame(going);      
}

function create_balls() {
  for (let i = 0; i < 75; i++) {
    const temp = new Ball();
    ball_array.push(temp);
  }
}

function resize_can() {
  ctx.canvas.width = window.innerWidth / 2;
  ctx.canvas.height = window.innerHeight / 2;
}

window.onresize = resize_can;
resize_can();
create_balls();

requestAnimationFrame(going);
<canvas id="myCanvas"></canvas>

答案 1 :(得分:0)

您需要填充画布并选择渐变颜色。

类似的东西:

my_canvas = $("myCanvas").getContext('2d');
var linear_gradient = my_canvas.createLinearGradient(0,0,window.innerWidth / 2,window.innerHeight / 2);
linear_gradient.addColorStop(0, "black");
linear_gradient.addColorStop(1, "white");

my_canvas.fillStyle = linear_gradient;
my_canvas.fillRect(0,0,100,100);