M
M
maxgeor2020-06-22 04:28:52
JavaScript
maxgeor, 2020-06-22 04:28:52

How to make JS work in several blocks on the site?

Good afternoon.
There is JS code on the site

<div id="wrap">
   <canvas id="output"></canvas>
</div>

console.clear();

var img = document.getElementById('input');

var c = document.getElementById('output'),
    ctx = c.getContext('2d');

c.width = img.width;
c.height = img.height;

var tic, sine, sineNormalized,
    start = Date.now();
    
var params = {
  AMP: 20,
  FREQ: 0.03,
  SPEED: 4,
  VERTICAL: true
};

function update() {
  tic = (Date.now() - start) * 0.001;
}

function render() {
  ctx.clearRect(0, 0, c.width, c.height);
  for(var i = 0; i < img.height; i++) {
    if(params.VERTICAL) {
      var ofs = params.AMP * (0.5 + (Math.sin(tic * params.SPEED + (i * params.FREQ)) * 0.5));
      ctx.drawImage(img,
                  0, i, img.width, 1,
                  0, i - (ofs * 0.5), img.width, 1 + ofs);
    } else {
      var ofs = params.AMP * Math.sin(tic * params.SPEED + (i * params.FREQ));
      ctx.drawImage(img,
                  0, i, img.width, 1,
                  0 + ofs, i, img.width, 1);
    }
    
  }
}

function loop() {
  requestAnimationFrame(loop);
  update();
  render();
}

$('nav input').on('input change', function() {
  var t = $(this).attr('data-param');
  if(t == 'VERTICAL') {
    params.VERTICAL = $(this).is(':checked');
  } else {
    params[t] = $(this).val();
  }
  
});

loop();

but it only fires in one in the first block, and it fails in the blocks below.
But if you do not put it in block number 1, but immediately put it in block number 2 (which is lower), it works.
How to make it work in the first and in the second and in the third block?
Thank you.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
K
Kirill Nikitin, 2020-06-22
@maxgeor

There can only be one id in a document with the value output.
You can try to change to a class and getElementsByClassName. The problem is that getElementsByClassName works with arrays and you can't call getContext directly here, you need a forEach wrapper.

<div id="wrap">
   <canvas class="output"></canvas>
   <canvas class="output"></canvas>
   <canvas class="output"></canvas>
   <canvas class="output"></canvas>
</div>

Something like that...
var img = document.getElementById('input');

var c = document.getElementsByClassName('output');

c = Array.prototype.slice.call(c);

c.forEach(function (c) {

var ctx = c.getContext('2d');

c.width = img.width;
c.height = img.height;

var tic, sine, sineNormalized,
    start = Date.now();
    
var params = {
  AMP: 20,
  FREQ: 0.03,
  SPEED: 4,
  VERTICAL: true
};

function update() {
  tic = (Date.now() - start) * 0.001;
}

function render() {
  ctx.clearRect(0, 0, c.width, c.height);
  for(var i = 0; i < img.height; i++) {
    if(params.VERTICAL) {
      var ofs = params.AMP * (0.5 + (Math.sin(tic * params.SPEED + (i * params.FREQ)) * 0.5));
      ctx.drawImage(img,
                  0, i, img.width, 1,
                  0, i - (ofs * 0.5), img.width, 1 + ofs);
    } else {
      var ofs = params.AMP * Math.sin(tic * params.SPEED + (i * params.FREQ));
      ctx.drawImage(img,
                  0, i, img.width, 1,
                  0 + ofs, i, img.width, 1);
    }
    
  }
}

function loop() {
  requestAnimationFrame(loop);
  update();
  render();
}

$('nav input').on('input change', function() {
  var t = $(this).attr('data-param');
  if(t == 'VERTICAL') {
    params.VERTICAL = $(this).is(':checked');
  } else {
    params[t] = $(this).val();
  }
  
});

loop();

});

M
maxgeor, 2020-06-22
@maxgeor

Arseniy Matytsin , i.e. i need instead of
var c = document.getElementById('output'),
this code
is querySelectorAll('.output .output_2 .output_3')

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question