Skip to main content

Star Spinner

Instructions: Spin the star with your mouse.

import Konva from 'konva';

// disable degree mode to use radians
Konva.angleDeg = false;

const stage = new Konva.Stage({
  container: 'container',
  width: window.innerWidth,
  height: window.innerHeight,
});

const animatedLayer = new Konva.Layer();

const star = new Konva.Star({
  x: stage.width() / 2,
  y: stage.height() / 2,
  outerRadius: 80,
  innerRadius: 40,
  stroke: '#005500',
  fill: '#b5ff88',
  strokeWidth: 4,
  numPoints: 5,
  lineJoin: 'round',
  shadowOffsetX: 5,
  shadowOffsetY: 5,
  shadowBlur: 10,
  shadowColor: 'black',
  shadowOpacity: 0.5,
  opacity: 0.8,
});

// custom properties
star.lastRotation = 0;
star.angularVelocity = 6;
star.controlled = false;

star.on('mousedown touchstart', function () {
  this.angularVelocity = 0;
  this.controlled = true;
});

animatedLayer.add(star);

// add center point
const center = new Konva.Circle({
  x: stage.width() / 2,
  y: stage.height() / 2,
  radius: 3,
  fill: '#555',
});

animatedLayer.add(center);

// add listeners to container
stage.on('mouseup touchend', function () {
  star.controlled = false;
});

stage.on('mousemove touchmove', function () {
  if (star.controlled) {
    const mousePos = stage.getPointerPosition();
    const x = star.x() - mousePos.x;
    const y = star.y() - mousePos.y;
    star.rotation(0.5 * Math.PI + Math.atan(y / x));

    if (mousePos.x <= stage.width() / 2) {
      star.rotate(Math.PI);
    }
  }
});

stage.add(animatedLayer);

// animation
function animate(frame) {
  // 20% slow down per second
  const angularFriction = 0.2;
  const angularVelocityChange =
    (star.angularVelocity * frame.timeDiff * (1 - angularFriction)) / 1000;
  star.angularVelocity -= angularVelocityChange;

  if (star.controlled) {
    star.angularVelocity =
      ((star.rotation() - star.lastRotation) * 1000) / frame.timeDiff;
  } else {
    star.rotate((frame.timeDiff * star.angularVelocity) / 1000);
  }

  star.lastRotation = star.rotation();
}

const anim = new Konva.Animation(animate, animatedLayer);

// wait one second and then spin the star
setTimeout(function () {
  anim.start();
}, 1000);