Поверните одно колесо по часовой стрелке, а другое - против часовой стрелки на том же полотне - PullRequest
0 голосов
/ 09 января 2020

Эй, у меня есть два круглых изображения на холсте, как показано ниже:

enter image description here

Я хотел эти две вещи:

  1. , когда мы нажимаем кнопку wheel1, затем я хотел повернуть левое колесо по часовой стрелке до 45 градусов и остановиться.
  2. когда мы нажмем кнопку wheel2, я хотел повернуть правое колесо против часовой стрелки до 45 градусов и остановиться.

I смогли достичь первого. Но я пробовал весь день сегодня, и я не могу понять, как я могу достичь второго пункта. Когда я нажимаю вторую кнопку, левое колесо перестает вращаться, а правое колесо вращается по всему холсту.

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

Я использую это изображение как w.png .

Вот мой код:

var cvs, ctx, img, img2, img3, im, im2, x, y, gblTask, gblTask2, gblTask3, gblTask4, r1 = 0,
  r2 = 0;
$(document).ready(function() {
  // $("p").click(function(){
  //   $(this).hide();
  // });
  loop();

});

let circle = {
  degrees: 0,
  draww: function() {
    var image = new Image();
    image.src = "https://www.freeiconspng.com/uploads/car-wheel-png-image-free-download--car-wheel-png-image-free--11.png";
    im = image;
    im.onload = function() {
      ctx.drawImage(im, 0, 20, 200, 200);
    }
  },

  draww2: function() {
    var image = new Image();
    image.src = "https://www.freeiconspng.com/uploads/car-wheel-png-image-free-download--car-wheel-png-image-free--11.png";
    im2 = image;
    im2.onload = function() {
      ctx.drawImage(im2, cvs.width / 2, 20, 200, 200);
    }
  },

  drawRotatedd2: function() {
    ctx.clearRect(cvs.width / 2, 0, cvs.width, cvs.height);
    ctx.save();
    ctx.translate(cvs.width / 2, cvs.height / 2);
    ctx.rotate((this.degrees -= 1) * Math.PI / 180);
    ctx.drawImage(im2, -cvs.width / 2 + 400, -cvs.height / 2 + 200, 200, 200);
    ctx.restore();
    if (this.degrees % 45 == 0) {
      r2 = 0;
      clearInterval(gblTask3);
      clearInterval(gblTask4);
    }
  },

  drawRotatedd: function() {
    ctx.clearRect(0, 0, cvs.width / 2, cvs.height);
    ctx.save();
    ctx.translate(im.width / 2, im.height / 2);
    ctx.rotate((this.degrees += 1) * Math.PI / 180);
    ctx.drawImage(im, -im.width / 2, -im.height / 2, 200, 200);
    ctx.restore();
    if (this.degrees % 45 == 0) {
      r1 = 0;
      clearInterval(gblTask);
      clearInterval(gblTask2);
    }
  }


}

// document.getElementById('cnv').addEventListener('click',function(event){
// 	// circle.drawRotated();
// 	gblTask = setInterval(gblTask2=setInterval(function(){circle.drawRotatedd()},10),100);
// });

document.getElementById('clockwise').addEventListener('click', function() {
  if (r1 == 0) {
    r1 = 1;
    gblTask = setInterval(gblTask2 = setInterval(function() {
      circle.drawRotatedd()
    }, 10), 100);
  } else {
    console.log('1');
  }

});

document.getElementById('antiClockwise').addEventListener('click', function() {
  if (r2 == 0) {
    r2 = 1;
    gblTask3 = setInterval(gblTask4 = setInterval(function() {
      circle.drawRotatedd2()
    }, 10), 100);
  } else {
    console.log('1');
  }
});

function loop() {
  var canvas = document.getElementById('cnv');
  var context = canvas.getContext("2d");
  canvas.width = 800;
  canvas.height = 450;

  ctx = context;
  cvs = canvas;
  // circle.draw();
  circle.draww();
  circle.draww2();

}
<!DOCTYPE html>
<html>

<head>
  <title></title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>

<body>
  <canvas id="cnv" style="border:solid 1px black;position:absolute;left:0;right:0;margin:auto;"></canvas>
  <button id='clockwise'>Wheel1</button>
  <button id='antiClockwise'>Wheel2</button>
</body>

</html>

1 Ответ

1 голос
/ 10 января 2020
  • Загружайте изображения только один раз. Нет необходимости загружать изображение каждый раз, когда вам нужно его нарисовать. Также оба колеса являются одним и тем же изображением, поэтому вам нужна только одна копия изображения.

  • Используйте requestAnimationFrame для анимации содержимого холста.

  • Получите контекст холста только один раз. Нет необходимости получать его в каждом кадре.

  • Избегайте изменения размера холста, когда в этом нет необходимости, например, настройку ширины или высоты холста, даже если это значение будет одинаковым. сбросить все состояние 2D контекста.

  • Не повторять один и тот же код. Колеса почти идентичны, кроме положения и вращения. Определите объект, который описывает колесо, и создайте этот объект для обоих колес, задав только те свойства, которые делают их уникальными.

  • Вам действительно нужно jQuery? Это просто раздувание, которое замедлит вашу страницу, и для всех этих дополнительных строк javascript, которые вы загрузили, вы вызывали ее только дважды. Использование jQuery больше не актуально, современные браузерные API намного быстрее и эффективнее. Не отставайте.

Пример

Пример написания кода с использованием точек, описанных выше.

const wheelImg = new Image;
wheelImg.src = "https://www.freeiconspng.com/uploads/car-wheel-png-image-free-download--car-wheel-png-image-free--11.png";
canvas.width = innerWidth - 30;
canvas.height = innerHeight - 40;
const ctx = canvas.getContext("2d");
const wheelScale = 0.4;  // scales the wheels
const rotateCount = 100; // frames (@60 per second)
var activeWheelCount = 0; // to track if any wheels are active

// when the image has loaded set up click events and draw the first frame
wheelImg.addEventListener("load",() => { 
    requestAnimationFrame(mainLoop)
    clockwiseBtn.addEventListener("click",() => wheels[0].start(Math.PI / 2));
    antiClockwiseBtn.addEventListener("click",() => wheels[1].start(-Math.PI / 2));
    }
    ,{once:true}
);

// defines a single wheel
const wheel = (x,y,rot) => ({
    x,y,rot,
    rotTarget: rot,
    counter: 0,
    start(ang) {   // command a wheel to turn 
      if (!this.counter ) {  // make sure not already turning
          this.counter = rotateCount;
          this.rotTarget += ang;
          if (!activeWheelCount) { requestAnimationFrame(mainLoop) } // start the
                                                                     // animation is no wheel
                                                                     // is active
          activeWheelCount ++;
      }
    },
    update() {  // update the wheel animation counter
        this.counter += this.counter > 0 ? -1 : 0;
        if (this.counter === 0) {  this.rot = this.rotTarget }
        else { activeWheelCount += 1 } // count this wheel as an active wheel
    },
    draw() { // draw the wheel
        const r = (1 - (this.counter / rotateCount))  * (this.rotTarget - this.rot) + this.rot;
        ctx.setTransform(wheelScale, 0, 0, wheelScale, this.x, this.y);
        ctx.rotate(r);
        ctx.drawImage(wheelImg, -wheelImg.width / 2, -wheelImg.height / 2);

    }
});
const wheels = [wheel(90,80, 0), wheel(350,80,0)]; // create two wheels
 
function mainLoop() {  // animates wheels
    activeWheelCount = 0;
    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height);
    wheels.forEach(wheel => wheel.update());
    wheels.forEach(wheel => wheel.draw());
    if (activeWheelCount) {
        requestAnimationFrame(mainLoop);
    }
}
#canvas {
  border:solid 1px black;
  position:absolute;
  top:30px;
  left:0px;
}
  <canvas id="canvas"></canvas>
  <button id='clockwiseBtn'>Wheel1</button>
  <button id='antiClockwiseBtn'>Wheel2</button>
...