БлогNot. Необязательно чёрный квадрат и не Малевича

Необязательно чёрный квадрат и не Малевича

Спрячу эффект под кат, чтобы не тормозил ленту. Идея в том, что плотный поток частиц, расположенных поверх фоновой картинки (или просто фона) подвергается "течению", открывающему её часть. Скрипт подгружается после загрузки страницы, при медленных компьютере/инете, возможно, придётся немного подождать.

Можно поводить мышью по канве и самому управлять "очисткой" (без нажатия), но с первым же движением мыши по канве автоматически обновляющаяся "рыбка" исчезнет, так что если не уловили, как всё работало, перезагрузите страницу в браузере нажатием клавиши F5.

Ниже приводится эффект в работе и исходники (разметка .html без обрамления + код на Javascript).

Внешних библиотек не нужно.

<div id="container" 
 style="margin: 0 auto; text-align: center; background: url(back.gif) center no-repeat;">
</div>
<script>
function particlesMatrix (id) {
 let 
  ROWS = 600,
  COLS = 600,
  NUM_PARTICLES = ROWS * COLS, //размерность матрицы
  THICKNESS = Math.pow(80, 2), //размер активной зоны
  SPACING = 1, //расстояние между частицами
  MARGIN = 10, //ширина внешних краев
  COLOR = 153, //цвет частиц, R=G=B
  DRAG1 = 0.85, //коэффициенты для
  DRAG2 = 0.15, //вычисления новых координат, [0;1]
  container, particle, canvas, mouse, list, ctx,
  tog, man, dx, dy, mx, my, d, t, f, a, b, i, n, w, h, p, s, r, c;

 particle = { vx: 0, vy: 0, x: 0, y: 0 };

 function relMouseCoords (event) {
  let totalOffsetX = 0, totalOffsetY = 0, canvasX = 0, canvasY = 0, currentElement = this;
  do {
   totalOffsetX += currentElement.offsetLeft - currentElement.scrollLeft;
   totalOffsetY += currentElement.offsetTop - currentElement.scrollTop;
  } while (currentElement = currentElement.offsetParent);
  canvasX = event.pageX - totalOffsetX;
  canvasY = event.pageY - totalOffsetY;
  return { x:canvasX, y:canvasY };
 }
 HTMLCanvasElement.prototype.relMouseCoords = relMouseCoords;

 function init() {
  container = document.getElementById (id);
  canvas = document.createElement("canvas");
  ctx = canvas.getContext("2d");
  man = false;
  tog = true;
  list = [];
  w = canvas.width = COLS * SPACING + MARGIN * 2;
  h = canvas.height = ROWS * SPACING + MARGIN * 2;
  for (i = 0; i < NUM_PARTICLES; i++) {
   p = Object.create(particle);
   p.x = p.ox = MARGIN + SPACING * (i % COLS);
   p.y = p.oy = MARGIN + SPACING * Math.floor(i / COLS);
   list[i] = p;
  }

  container.addEventListener("mousemove", function(e) {
   mouse = canvas.relMouseCoords (e);
   mx = mouse.x; 
   my = mouse.y;
   man = true;
  });
  container.appendChild (canvas);
 }

 function step() {
  if ((tog = !tog)) {
   if (!man) {
    t = +new Date() * 0.001;
    mx = w * 0.5 + Math.cos(t * 2) * Math.cos(t * 0.5) * w * 0.4;
    my = h * 0.5 + Math.sin(t * 2) * Math.sin(t * 0.5) * h * 0.4;
   }
   for (i = 0; i < NUM_PARTICLES; i++) {
    p = list[i];
    d = (dx = mx - p.x) * dx + (dy = my - p.y) * dy;
    f = -THICKNESS / d;
    if (d < THICKNESS) {
     t = Math.atan2(dy, dx);
     p.vx += f * Math.cos(t);
     p.vy += f * Math.sin(t);
    }
    p.x += (p.vx *= DRAG1) + (p.ox - p.x) * DRAG2;
    p.y += (p.vy *= DRAG1) + (p.oy - p.y) * DRAG2;
   }
  } 
  else {
   a = ctx.createImageData(w, h);
   b = a.data;
   for (i = 0; i < NUM_PARTICLES; i++) {
    p = list [i];
    b[(n = (~~p.x + ~~p.y * w) * 4)] = b[n + 1] = b[n + 2] = COLOR; 
     //Быстро ставим все 3 компоненты в COLOR
    b[n + 3] = 255; //Alpha = 255
   }
   ctx.putImageData(a, 0, 0);
  }
  requestAnimationFrame(step);
 }

 init();
 step();
}

window.addEventListener ('load', function (e) {
 particlesMatrix("container");
}); 
</script>
<noscript>
 <div style="margin: 0 auto; text-align: center;">
  Включите в браузере JavaScript для работы приложения!
 </div>
</noscript>

 Картинка back.gif из исходника скрипта

Ниже также прикреплена "нулевая" версия скрипта с абсолютным позиционированием чёрного полотна по центру и без рисунка внизу. Увидеть исходник можно из исходника страницы, файл сохранён в кодировке Юникода UTF-8.

 ParticlesMatrix0.html, открыть в текущем окне/вкладке (3 Кб)

09.02.2020, 18:20 [1204 просмотра]


теги: javascript картинка графика

К этой статье пока нет комментариев, Ваш будет первым