Я сейчас работаю над веб-сайтом, для которого требуются морфинг-круги. Я использую бумагу. js, чтобы создать холст / круги и расположить их довольно близко, но нужна помощь с:
- Сохранение капли по центру холста
- Убедитесь, что нет путей go за пределами холста
- Плавное замедление между состояниями.
Вот CodePen того, что у меня есть. https://codepen.io/knynkwl/pen/vYLxOJe
class MorphingCircle {
constructor(el) {
this.DOM = {}
this.DOM.el = el;
console.log(this.DOM.el)
this.radius = getBounds(this.DOM.el).width / 2;
this.color = '#FBBC05';
this.speed = 100;
this.morphingPaper = new paper.PaperScope();
this.morphingPaper.setup(this.DOM.el);
}
init() {
this.setMorphingBg(this.morphingPaper);
}
destroy() {
}
setMorphingBg() {
let centerX = getBounds(this.DOM.el).width / 2;
let centerY = getBounds(this.DOM.el).height / 2;
this.circle = new this.morphingPaper.Path.Circle(
new paper.Point( centerX, centerY ),
this.radius);
this.circle.rndPos = [];
//different colors
this.circle.fillColor = this.color;
this.generateRndPoints();
this.draw(this.morphingPaper);
}
generateRndPoints() {
//generate 4 random points on the circle depending on the size
let diameter = this.radius * 2;
this.circle.rndPos[0] = [
this.rndPoint(0, (0.15 * diameter), 'x'),
this.rndPoint((0.45 * diameter), (0.6 * diameter), 'y')
]
this.circle.rndPos[1] = [
this.rndPoint((0.45 * diameter), (0.6 * diameter), 'x'),
this.rndPoint(0, (0.15 * diameter), 'y')
]
this.circle.rndPos[2] = [
this.rndPoint((0.9 * diameter), (1.05 * diameter), 'x'),
this.rndPoint((0.45 * diameter), (0.6 * diameter), 'y')
]
this.circle.rndPos[3] = [
this.rndPoint((0.45 * diameter), (0.6 * diameter), 'x') ,
this.rndPoint((0.9 * diameter), (1.05 * diameter), 'y')
]
}
rndPoint(min, max, pos) {
if(pos === 'x') { //generate a random point relative to the current position
min += this.circle.position.x - this.radius;
max += this.circle.position.x - this.radius;
} else {
min += this.circle.position.y - this.radius;
max += this.circle.position.y - this.radius;
}
return Math.random() * (max - min) + min;
}
draw() {
this.morphingPaper.view.onFrame = () => {
for (let j = 0; j < 4; j++) { //animation every segment / anchorpoint of the circle
//ease to the new point
let dX1 = (this.circle.rndPos[j][0] - this.circle.segments[j].point.x) / (this.speed);
let dY1 = (this.circle.rndPos[j][1] - this.circle.segments[j].point.y) / (this.speed);
this.circle.segments[j].point.x += dX1;
this.circle.segments[j].point.y += dY1;
if(Math.floor(this.circle.segments[j].point.x) === Math.floor(this.circle.rndPos[j][0])){
this.generateRndPoints();
}
}
};
this.morphingPaper.view.draw();
}
}
const getBounds = (el) => el.getBoundingClientRect();
let morphCircle = new MorphingCircle(document.querySelector('canvas'));
morphCircle.init()