MongoLato
MongoLato

Reputation: 381

SVG.js: why does rotate behave in a weird way

I'm trying to get a bus with its compass move along the line. However, I can't get the compass rotating properly, it rotates and also move in a very strange way.

Could you please help me find what has gone wrong?

Here is the link to Fiddle: https://jsfiddle.net/ugvapdrj (I've not fixed the CSS yet so it overflows to the right.)

Thanks!

Code:

<div id="drawing"></div>
let canvas = SVG('drawing').size(2000, 2000)
let compassSize = 42;
let lineColour = '#f00';


let Rsc2muVkt = canvas
  .path(
    'M736 96V72c0-13-11-24-24-24h-75c-18 0-35 7-48 18l-104 94c-23 21-54 32-85 32H0'
  )
  .stroke({
    color: lineColour
  })
  .fill('none');

// Buses
let bus = canvas.image(
  'https://s3-ap-southeast-1.amazonaws.com/viabus-develop-media-resource-ap-southeast/Vehicle+Images/entity/mu/veh_core_mu_06.png',
  compassSize
);
let busCompass = canvas.image(
  'https://s3-ap-southeast-1.amazonaws.com/viabus-develop-media-resource-ap-southeast/Network+Images/Azimuth/Public/veh_ring_white.png',
  compassSize
);

moveBus(bus, busCompass, Rsc2muVkt, 0);


for (let i = 0; i <= 100; i++) {
  setTimeout(() => {
    moveBus(bus, busCompass, Rsc2muVkt, i);
  }, 1000 + i * 200);
}

function moveBus(bus, busCompass, path, to) {
  const p = path.pointAt(to / 100 * path.length());
  const newPosition = {
    x: p.x,
    y: p.y
  };

  const oldX = bus.cx();
  const oldY = bus.cy();

  bus.center(newPosition.x, newPosition.y);
  busCompass.center(newPosition.x, newPosition.y);

  const newX = bus.cx();
  const newY = bus.cy();

  const dx = newX - oldX;
  const dy = newY - oldY;
  const rotatingAngle = Math.atan2(dy, dx) * 180 / Math.PI;

  busCompass.rotate(rotatingAngle + 90);
}

Upvotes: 0

Views: 135

Answers (1)

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324640

The compass is still rotated when you try to center it on the next frame of animation. This causes the busCompass.center(...) call to use the rotated coordinate system.

You should first call busCompass.rotate(0); to reset the rotation, then busCompass.center(...) will work as expected and the final rotation will complete.

Upvotes: 1

Related Questions