Сохранение круга в границах холста при морфинге - бумага. js - PullRequest
1 голос
/ 20 июня 2020

Я сейчас работаю над веб-сайтом, для которого требуются морфинг-круги. Я использую бумагу. js, чтобы создать холст / круги и расположить их довольно близко, но нужна помощь с:

  1. Сохранение капли по центру холста
  2. Убедитесь, что нет путей go за пределами холста
  3. Плавное замедление между состояниями.

Вот 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()

...