跳到主要内容

星形旋转器

操作说明:使用鼠标旋转星形。

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);