Импульсная анимация на холсте - PullRequest
0 голосов
/ 25 апреля 2018

Я пытаюсь сделать так, чтобы различные формы имели импульсный эффект на холсте, и мне удалось сделать это с помощью круга,

function drawCircle() {

// color in the background
context.fillStyle = "#EEEEEE";
context.fillRect(0, 0, canvas.width, canvas.height);

// draw the circle
context.beginPath();

var radius = 25 + 20 * Math.abs(Math.cos(angle)); //radius of circle
context.arc(25, 25, radius, 0, Math.PI * 2, false); //position on canvas
context.closePath();

// color in the circle
context.fillStyle = "#006699";
context.fill();

//'pulse'
angle += Math.PI / 220;

requestAnimationFrame(drawCircle);
}
drawCircle();

, но я не уверен, как поступить с любой другой формой.То, что у меня есть для моего треугольника, это

function drawTriangle() {

// draw the triangle
context.beginPath();
context.moveTo(75, 50);
context.lineTo(100, 75);
context.lineTo(100, 25);
context.fill();

context.rect(215, 100, Math.PI * 2, false); //position on canvas
context.closePath();

// color in the triangle
context.fillStyle = "#3f007f";
context.fill();

//'pulse'
angle += Math.PI / 280;

requestAnimationFrame(drawTriangle);
}
drawTriangle();

. Любое понимание будет оценено.

1 Ответ

0 голосов
/ 25 апреля 2018

Этого можно достичь, просто изменив масштаб контекстной матрицы.

Все, что вам нужно найти, - это положение масштабирующего якоря вашей фигуры, чтобы вы могли перевести матрицу в правильное положение после применения шкалы.

В следующем примере я буду использовать центр фигуры в качестве привязки масштабирования, поскольку кажется, что это то, что вы хотели.

Расширенная версия преобразования матрицы будет

ctx.translate(anchorX, anchorY);
ctx.scale(scaleFactor, scaleFactor);
ctx.translate(-anchorX, -anchorY);

, который в приведенном ниже примере был уменьшен до

ctx.setTransform(
   scale, 0, 0,
   scale, anchorX  - (anchorX * scale), anchorY  - (anchorY * scale)
);

var ctx = canvas.getContext('2d');
var angle = 0;
var scale = 1;
var img = new Image();
img.src = 'https://dl.dropboxusercontent.com/s/4e90e48s5vtmfbd/aaa.png';
anim();


function anim() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  updateScale();
  drawCircle();
  drawTriangle();
  drawImage();
  ctx.setTransform(1, 0, 0, 1, 0, 0);
  requestAnimationFrame(anim);
}

function updateScale() {
  angle += Math.PI / 220;
  scale = 0.5 + Math.abs(Math.cos(angle));
}

function drawCircle() {
  ctx.beginPath();
  var cx = 75,
    cy = 50,
    radius = 25;
  // for the circle, centerX and centerY are given
  var anchorX = cx,
    anchorY = cy;
  // with these anchorX, anchorY and scale, 
  // we can determine where we need to translate our context once scaled
  var scaledX = anchorX - (anchorX * scale),
    scaledY = anchorY - (anchorY * scale);
  // then we apply the matrix in one go
  ctx.setTransform(scale, 0, 0, scale, scaledX, scaledY);
  // and we draw normally
  ctx.arc(cx, cy, radius, 0, Math.PI * 2);
  ctx.fill();
}

function drawTriangle() {
  ctx.beginPath();
  // for the triangle, we need to find the position between minX and maxX,
  // and between minY and maxY
  var anchorX = 175 + (200 - 175) / 2,
    anchorY = 25 + (75 - 25) / 2;
  var scaledX = anchorX - (anchorX * scale),
    scaledY = anchorY - (anchorY * scale);
  ctx.setTransform(scale, 0, 0, scale, scaledX, scaledY);
  ctx.moveTo(175, 50);
  ctx.lineTo(200, 75);
  ctx.lineTo(200, 25);
  ctx.fill();
}

function drawImage() {
  if (!img.naturalWidth) return;
  // for rects, it's just pos + (length / 2)
  var anchorX = 250 + img.naturalWidth / 2,
    anchorY = 25 + img.naturalHeight / 2;
  var scaledX = anchorX - (anchorX * scale),
    scaledY = anchorY - (anchorY * scale);
  ctx.setTransform(scale, 0, 0, scale, scaledX, scaledY);
  ctx.drawImage(img, 250, 25);
}
<canvas id="canvas" width="500"></canvas>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...