Движение корабля в canvas

131
13 марта 2021, 11:20

Как реализовать "вылет корабля" представленного ромбами из нижней части экрана браузера ?

window.onload = function() { 
 
  var canvas = document.getElementById('myCanvas'), 
    n = 20; 
  var currentHeight = window.innerHeight; 
  canvas.height = currentHeight; 
  canvas.width = currentHeight; 
  var ctx = canvas.getContext('2d'); 
 
  var i = 0; 
  var w = currentHeight / 100, 
    h = w; 
 
 
  var centerX = 50 * w, 
    centerY = 50 * h; 
 
  var colorMainBg = "#000", 
    colorArr = ["#00C77F", "#00916B", "#00FF8A", "#00C77F"]; 
 
 
  function createTriangle(horizontalShift, verticalShift, bgColor) { 
 
    ctx.fillStyle = bgColor; 
    ctx.beginPath(); 
    ctx.moveTo(centerX, centerY); 
    ctx.lineTo(centerX, verticalShift); 
    ctx.lineTo(horizontalShift, centerY); 
    ctx.closePath(); 
    ctx.fill(); 
 
  } 
 
  function darkRombus() { 
    ctx.lineWidth = '1'; 
    ctx.fillStyle = colorMainBg; 
    ctx.beginPath(); 
    ctx.moveTo(centerX, centerY - 8 * h); 
    ctx.lineTo(centerX + 5 * w, centerY); 
    ctx.lineTo(centerX, centerY + 8 * h); 
    ctx.lineTo(centerX - 5 * w, centerY); 
    ctx.closePath(); 
    ctx.fill(); 
  } 
 
 
 
  var kx = 8, 
    ky = 12; // 8 
 
  function createRhombus() { 
    createTriangle(centerX - kx * w, centerY - ky * w, colorArr[0]); 
    createTriangle(centerX - kx * w, centerY + ky * w, colorArr[1]); 
    createTriangle(centerX + kx * w, centerY - ky * w, colorArr[2]); 
    createTriangle(centerX + kx * w, centerY + ky * w, colorArr[3]); 
    darkRombus(); 
 
  } 
 
  function animationRhombus() { 
 
    // ctx.clearRect(0, 0, canvas.width, canvas.height); 
    var i = centerY * 2; 
 
    while (i >= 0) { 
 
      i = i - 100 * h; 
 
      var t = i; 
 
      ctx.translate(0, t); 
      createRhombus(); 
 
      ctx.scale(0.7, 0.7); 
      ctx.translate(centerX - (16.6 * w), centerY - (16 * h)); 
      createRhombus(); 
 
 
      ctx.translate(centerX - (74 * w), centerY - (50 * h)); 
      createRhombus(); 
 
 
      console.log(i); 
      return i 
    } 
 
  } 
 
  setInterval(animationRhombus, 10000 / 60); 
 
 
}
body { 
  margin: 0; 
  width: 100%; 
  min-height: 100vh; 
  background-color: #000; 
  font-family: "Roboto", sans-serif; 
} 
 
canvas { 
  position: absolute; 
  top: 50%; 
  left: 50%; 
  transform: translate(-50%, -50%); 
}
<canvas id="myCanvas"></canvas>

Не получается правильно прописать функцию animationRhombus, (пробовал и через for но ничего не получается), необходимо что бы корабль из 3 ромбов вылетал из нижней части экрана, и останавливался в ctx.translate(0, 0); (в центре экрана), а не как сейчас, после чего setInterval переставал работать. Дальше, хочется анимировать что бы коэффициент ky плавно переходил из значения 12 в значение 8 (равнобедренные ромбы) Первая анимация должна заканчиваться так (скажем через 3сек) Вторая анимация с изменением ky должна закончиться так

Answer 1

Обратите внимание на методы

ctx.save()
...
ctx.restore();

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

var currentHeight = canvas.height = canvas.width = window.innerHeight; 
var ctx = canvas.getContext('2d'); 
var w = currentHeight / 100, h = w, centerX = 50 * w, centerY = 50 * h,  
  pos = 0, dr = 1, rot = 0; 
var colorMainBg = "#000", colorArr = ["#00C77F", "#00916B", "#00FF8A", "#00C77F"]; 
 
function createTriangle(horizontalShift, verticalShift, bgColor) { 
  ctx.fillStyle = bgColor; 
  ctx.beginPath(); 
  ctx.moveTo(centerX, centerY); 
  ctx.lineTo(centerX, verticalShift); 
  ctx.lineTo(horizontalShift, centerY); 
  ctx.closePath(); 
  ctx.fill(); 
} 
 
function darkRombus() { 
  ctx.lineWidth = '1'; 
  ctx.fillStyle = colorMainBg; 
  ctx.beginPath(); 
  ctx.moveTo(centerX, centerY - 8 * h*dr); 
  ctx.lineTo(centerX + 5 * w*dr, centerY); 
  ctx.lineTo(centerX, centerY + 8 * h*dr); 
  ctx.lineTo(centerX - 5 * w*dr, centerY); 
  ctx.closePath(); 
  ctx.fill(); 
} 
 
var kx = 8, ky = 12; // 8 
 
function createRhombus() { 
  ctx.translate(centerX, centerY) 
  ctx.rotate(rot*Math.PI/2); 
  ctx.translate(-centerX, -centerY) 
  createTriangle(centerX - kx * w, centerY - ky * w, colorArr[0]); 
  createTriangle(centerX - kx * w, centerY + ky * w, colorArr[1]); 
  createTriangle(centerX + kx * w, centerY - ky * w, colorArr[2]); 
  createTriangle(centerX + kx * w, centerY + ky * w, colorArr[3]); 
  darkRombus(); 
  ctx.translate(centerX, centerY) 
  ctx.rotate(-rot*Math.PI/2); 
  ctx.translate(-centerX, -centerY) 
} 
 
function animationRhombus() { 
  if (pos<currentHeight/2 + 50)  
    pos = pos + 3; 
  else if (ky > 8) 
    ky = Math.max(8, ky - 0.05); 
  else if (dr > 0) 
    dr = Math.max(0, dr - 0.01); 
  else 
    rot = Math.min(1, rot + 0.05); 
  ctx.save() 
  ctx.translate(0, currentHeight/2 + 60 -pos); 
  ctx.clearRect(0, 0, canvas.width, canvas.height); 
  createRhombus(); 
  ctx.scale(0.5, 0.5); 
  ctx.translate(33*w, 65*h); 
  createRhombus(); 
  ctx.translate(34*w, 0); 
  createRhombus(); 
  ctx.scale(0.5, 0.5); 
  ctx.translate(33*w, 65*h); 
  createRhombus(); 
  ctx.translate(34*w, 0); 
  createRhombus(); 
  ctx.translate(-102*w, 0); 
  createRhombus(); 
  ctx.translate(34*w, 0); 
  createRhombus(); 
  ctx.restore(); 
} 
 
setInterval(animationRhombus, 1000 / 60);
body { 
  margin: 0; 
  width: 100%; 
  min-height: 100vh; 
  background-color: #000; 
  font-family: "Roboto", sans-serif; 
} 
 
canvas { 
  position: absolute; 
  top: 50%; 
  left: 50%; 
  transform: translate(-50%, -50%); 
}
<canvas id="canvas"></canvas>

READ ALSO
Ошибка Uncaught TypeError: $(&hellip;).tooltip is not a function at HTMLDocument - как решить? [закрыт]

Ошибка Uncaught TypeError: $(…).tooltip is not a function at HTMLDocument - как решить? [закрыт]

Хотите улучшить этот вопрос? Обновите вопрос так, чтобы он вписывался в тематику Stack Overflow на русском

161