Холст не появится, но появится сам по себе

#javascript #html5-canvas

#javascript #html5-canvas

Вопрос:

Итак, следующий скрипт отлично работает сам по себе (только скрипт и ничего больше), но когда я пытаюсь загрузить его в раздел или что-то еще, на самом деле это не работает.

Вот сценарий;

 <!-- partial:index.partial.html -->
<script src="https://code.jquery.com/pep/0.4.3/pep.js"></script>
<!-- partial -->
<script>
let canvas, ctx;
let render, init;
let blob;

class Blob {
  constructor() {
    this.points = [];
  }

  init() {
    for (let i = 0; i < this.numPoints; i  ) {
      let point = new Point(this.divisional * (i   1), this);
      // point.acceleration = -1   Math.random() * 2;
      this.push(point);
    }
  }

  render() {
    let canvas = this.canvas;
    let ctx = this.ctx;
    let position = this.position;
    let pointsArray = this.points;
    let radius = this.radius;
    let points = this.numPoints;
    let divisional = this.divisional;
    let center = this.center;

    ctx.clearRect(0, 0, canvas.width, canvas.height);

    pointsArray[0].solveWith(pointsArray[points - 1], pointsArray[1]);

    let p0 = pointsArray[points - 1].position;
    let p1 = pointsArray[0].position;
    let _p2 = p1;

    ctx.beginPath();
    ctx.moveTo(center.x, center.y);
    ctx.moveTo((p0.x   p1.x) / 2, (p0.y   p1.y) / 2);

    for (let i = 1; i < points; i  ) {

      pointsArray[i].solveWith(pointsArray[i - 1], pointsArray[i   1] || pointsArray[0]);

      let p2 = pointsArray[i].position;
      var xc = (p1.x   p2.x) / 2;
      var yc = (p1.y   p2.y) / 2;
      ctx.quadraticCurveTo(p1.x, p1.y, xc, yc);
      // ctx.lineTo(p2.x, p2.y);

      ctx.fillStyle = '#c3c3c3';
      // ctx.fillRect(p1.x-2.5, p1.y-2.5, 5, 5);

      p1 = p2;
    }

    var xc = (p1.x   _p2.x) / 2;
    var yc = (p1.y   _p2.y) / 2;
    ctx.quadraticCurveTo(p1.x, p1.y, xc, yc);
    // ctx.lineTo(_p2.x, _p2.y);

    // ctx.closePath();
    ctx.fillStyle = this.color;
    ctx.fill();
    ctx.strokeStyle = '#c3c3c3';
    // ctx.stroke();

    /*
        ctx.fillStyle = '#000000';
        if(this.mousePos) {
          let angle = Math.atan2(this.mousePos.y, this.mousePos.x)   Math.PI;
          ctx.fillRect(center.x   Math.cos(angle) * this.radius, center.y   Math.sin(angle) * this.radius, 5, 5);
        }
    */
    requestAnimationFrame(this.render.bind(this));
  }

  push(item) {
    if (item instanceof Point) {
      this.points.push(item);
    }
  }

  set color(value) {
    this._color = value;
  }
  get color() {
    return this._color || '#c3c3c3';
  }

  set canvas(value) {
    if (value instanceof HTMLElement amp;amp; value.tagName.toLowerCase() === 'canvas') {
      this._canvas = canvas;
      this.ctx = this._canvas.getContext('2d');
    }
  }
  get canvas() {
    return this._canvas;
  }

  set numPoints(value) {
    if (value > 2) {
      this._points = value;
    }
  }
  get numPoints() {
    return this._points || 12;
  }

  set radius(value) {
    if (value > 0) {
      this._radius = value;
    }
  }
  get radius() {
    return this._radius || 200;
  }

  set position(value) {
    if (typeof value == 'object' amp;amp; value.x amp;amp; value.y) {
      this._position = value;
    }
  }
  get position() {
    return this._position || { x: 0.5, y: 0.5 };
  }

  get divisional() {
    return Math.PI * 2 / this.numPoints;
  }

  get center() {
    return { x: this.canvas.width * this.position.x, y: this.canvas.height * this.position.y };
  }

  set running(value) {
    this._running = value === true;
  }
  get running() {
    return this.running !== false;
  }}


class Point {
  constructor(azimuth, parent) {
    this.parent = parent;
    this.azimuth = Math.PI - azimuth;
    this._components = {
      x: Math.cos(this.azimuth),
      y: Math.sin(this.azimuth) };


    this.acceleration = -0.3   Math.random() * 0.6;
  }

  solveWith(leftPoint, rightPoint) {
    this.acceleration = (-0.3 * this.radialEffect   (leftPoint.radialEffect - this.radialEffect)   (rightPoint.radialEffect - this.radialEffect)) * this.elasticity - this.speed * this.friction;
  }

  set acceleration(value) {
    if (typeof value == 'number') {
      this._acceleration = value;
      this.speed  = this._acceleration * 2;
    }
  }
  get acceleration() {
    return this._acceleration || 0;
  }

  set speed(value) {
    if (typeof value == 'number') {
      this._speed = value;
      this.radialEffect  = this._speed * 5;
    }
  }
  get speed() {
    return this._speed || 0;
  }

  set radialEffect(value) {
    if (typeof value == 'number') {
      this._radialEffect = value;
    }
  }
  get radialEffect() {
    return this._radialEffect || 0;
  }

  get position() {
    return {
      x: this.parent.center.x   this.components.x * (this.parent.radius   this.radialEffect),
      y: this.parent.center.y   this.components.y * (this.parent.radius   this.radialEffect) };

  }

  get components() {
    return this._components;
  }

  set elasticity(value) {
    if (typeof value === 'number') {
      this._elasticity = value;
    }
  }
  get elasticity() {
    return this._elasticity || 0.001;
  }
  set friction(value) {
    if (typeof value === 'number') {
      this._friction = value;
    }
  }
  get friction() {
    return this._friction || 0.0085;
  }}


blob = new Blob();

init = function () {
  canvas = document.createElement('canvas');
  canvas.setAttribute('touch-action', 'none');

  document.body.appendChild(canvas);

  let resize = function () {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
  };
  window.addEventListener('resize', resize);
  resize();

  let oldMousePoint = { x: 0, y: 0 };
  let hover = false;
  let mouseMove = function (e) {

    let pos = blob.center;
    let diff = { x: e.clientX - pos.x, y: e.clientY - pos.y };
    let dist = Math.sqrt(diff.x * diff.x   diff.y * diff.y);
    let angle = null;

    blob.mousePos = { x: pos.x - e.clientX, y: pos.y - e.clientY };

    if (dist < blob.radius amp;amp; hover === false) {
      let vector = { x: e.clientX - pos.x, y: e.clientY - pos.y };
      angle = Math.atan2(vector.y, vector.x);
      hover = true;
      // blob.color = '#77FF00';
    } else if (dist > blob.radius amp;amp; hover === true) {
      let vector = { x: e.clientX - pos.x, y: e.clientY - pos.y };
      angle = Math.atan2(vector.y, vector.x);
      hover = false;
      blob.color = null;
    }

    if (typeof angle == 'number') {

      let nearestPoint = null;
      let distanceFromPoint = 30;

      blob.points.forEach(point => {
        if (Math.abs(angle - point.azimuth) < distanceFromPoint) {
          // console.log(point.azimuth, angle, distanceFromPoint);
          nearestPoint = point;
          distanceFromPoint = Math.abs(angle - point.azimuth);
        }

      });

      if (nearestPoint) {
        let strength = { x: oldMousePoint.x - e.clientX, y: oldMousePoint.y - e.clientY };
        strength = Math.sqrt(strength.x * strength.x   strength.y * strength.y) * 10;
        if (strength > 100) strength = 100;
        nearestPoint.acceleration = strength / 45 * (hover ? -1 : 1);
      }
    }

    oldMousePoint.x = e.clientX;
    oldMousePoint.y = e.clientY;
  };
  // window.addEventListener('mousemove', mouseMove);
  window.addEventListener('pointermove', mouseMove);

  blob.canvas = canvas;
  blob.init();
  blob.render();
};

init();
  

Вот раздел HTML, в который я пытаюсь добавить скрипт

 <section>
  <div class="footer">
     <canvas id="canvas" width="200" height="100" style="border:1px solid #d3d3d3;"></canvas>
   </div>
</section>
  

Есть идеи, почему? На самом деле он будет работать сам по себе без тега canvas, поэтому я не понимаю, что я сделал неправильно..

Ответ №1:

Измените эту строку:

 canvas = document.createElement('canvas');
  

Для:

 canvas = document.getElementById('canvas');
  

И удалите эту строку:

 document.body.appendChild(canvas);
  

И измените эту строку:

 init();
  

Для:

 window.addEventListener('DOMContentLoaded', () => {
  init();
});
  

Вот рабочий пример:
https://playcode.io/688767 /

Комментарии:

1. С этими изменениями я вообще ничего не получаю в качестве canvas = document.createElement('canvas'); раздела, который запускает графический рисунок…

2. Добавлено еще немного кода, чтобы убедиться, что canvas инициализирован.

3. Хорошо, теперь у меня другая проблема, как мне загрузить скрипт на пять отдельных холстов, я просто добавляю больше canvas = document.getElementById('new_name'); классов? потому что, если я добавлю скрипт пять раз, будет работать только первый…

4. @jamesL Смотри jsbin.com/yasuyaxedu/edit?html ,js, вывод

5. @Blindman67 Это просто обычное дело. Я никогда не видел никого, на кого не ссылались window addEventListener . Кроме этого, я не знаю веской причины. Также обычным делом не ссылаться window.document .