БлогNot. Чокнутые гексы

Чокнутые гексы

...и ещё одна "арт-генерация" на JS.

В отличие от предыдущего скрипта, канва здесь развёрнута на весь экран, шестиугольники-гексы рисуются бесконечно, меняя цвет и создавая себе сетку, постепенно занимающую весь экран. Скрипт реагирует на изменение размеров окна браузера.

Помните, что вам Р. Дэниел Оливо говорил про важность минимальных воздействий? Вот это оно и есть.

Как и в предыдущем скрипте, лень было добавлять форму с настройками, но они закомментированы в листинге. Ниже приводится ссылка на работающий скрипт и исходник на момент размещения. В актуальном Firefox работает шустренько, а в Ms Edge тормозит. Лучше всего нажать в браузере F11 и наслаждаться гексами в полноэкранном режиме и на качественном мониторе.

 Открыть скрипт hexAnimation в текущем окне/вкладке, файл .html (4 Кб)

<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>hexAnimation</title>
<style>
 body {
  padding: 0;
  margin: 0 auto;
  overflow: hidden;
 }
 canvas {
  position: absolute;
  top: 0;
  left: 0;
 }
</style>
<script>

function canvasApp(id) {
 let c = document.getElementById(id);
 let w = c.width = window.innerWidth, 
     h = c.height = window.innerHeight, //весь экран
     ctx = c.getContext( '2d' ),
     opts = { //настройки
      len: 40, //длина сегмента в пикселях
      count: 100, //количество
      baseTime: 10,
      addedTime: 10,
      dieChance: .05, //смертность
      spawnChance: .9, //расползучесть
      sparkChance: .1, //искристость
      sparkDist: 20, //расстояние для искр
      sparkSize: 3, //размер искры в пикселях
      color: 'hsl(hue,100%,light%)', //эти "слова" в цвете будут заменены
      baseLight: 50,
      addedLight: 10, // [baseLight-10,baseLight+10]
      shadowToTimePropMult: 5,
      baseLightInputMultiplier: .01,
      addedLightInputMultiplier: .02,
      cx: w / 2,
      cy: h / 2,
      repaintAlpha: .04,
      hueChange: .1
    },
    tick = 0,
    lines = [],
    dieX = w / 2 / opts.len,
    dieY = h / 2 / opts.len,
    baseRad = Math.PI * 2 / 6;
 ctx.fillStyle = 'black';
 ctx.fillRect( 0, 0, w, h );

 function loop() {
  window.requestAnimationFrame( loop );
  tick++;
  ctx.globalCompositeOperation = 'source-over';
  ctx.shadowBlur = 0;
  ctx.fillStyle = 'rgba(0,0,0,alp)'.replace( 'alp', opts.repaintAlpha );
  ctx.fillRect( 0, 0, w, h );
  ctx.globalCompositeOperation = 'lighter';
  if ( lines.length < opts.count && Math.random() < opts.spawnChance )
   lines.push( new Line );
  lines.map( function( line ){ line.step(); } );
 }
 
 function Line() {
  this.reset();
 }
 
 Line.prototype.reset = function() {
  this.x = 0;
  this.y = 0;
  this.addedX = 0;
  this.addedY = 0;
  this.rad = 0;
  this.lightInputMultiplier = opts.baseLightInputMultiplier + 
   opts.addedLightInputMultiplier * Math.random();
  this.color = opts.color.replace ('hue', tick * opts.hueChange);
  this.cumulativeTime = 0;
  this.beginPhase();
 }
 
 Line.prototype.beginPhase = function() {
  this.x += this.addedX;
  this.y += this.addedY;
  this.time = 0;
  this.targetTime = ( opts.baseTime + opts.addedTime * Math.random() ) |0;
  this.rad += baseRad * ( Math.random() < .5 ? 1 : -1 );
  this.addedX = Math.cos( this.rad );
  this.addedY = Math.sin( this.rad );
  if (Math.random() < opts.dieChance || 
      this.x > dieX || this.x < -dieX || this.y > dieY || this.y < -dieY )
   this.reset();
 }
 
 Line.prototype.step = function() {
  this.time++;
  this.cumulativeTime++;
  if (this.time >= this.targetTime)
   this.beginPhase();
  let prop = this.time / this.targetTime,
      wave = Math.sin( prop * Math.PI / 2  ),
      x = this.addedX * wave,
      y = this.addedY * wave;
  ctx.shadowBlur = prop * opts.shadowToTimePropMult;
  ctx.fillStyle = ctx.shadowColor = this.color.replace ('light', 
   opts.baseLight + opts.addedLight * 
   Math.sin( this.cumulativeTime * this.lightInputMultiplier ) );
  ctx.fillRect( opts.cx + ( this.x + x ) * opts.len, 
   opts.cy + ( this.y + y ) * opts.len, 2, 2 );
  if (Math.random() < opts.sparkChance )
   ctx.fillRect( opts.cx + ( this.x + x ) * opts.len + Math.random() * opts.sparkDist * 
   ( Math.random() < .5 ? 1 : -1 ) - opts.sparkSize / 2, opts.cy + ( this.y + y ) * 
   opts.len + Math.random() * opts.sparkDist * 
   ( Math.random() < .5 ? 1 : -1) - opts.sparkSize / 2, opts.sparkSize, opts.sparkSize);
 }

 window.addEventListener( 'resize', function() { //изменение размеров окна
  w = c.width = window.innerWidth;
  h = c.height = window.innerHeight;
  ctx.fillStyle = 'black';
  ctx.fillRect( 0, 0, w, h );
  opts.cx = w / 2;
  opts.cy = h / 2;
  dieX = w / 2 / opts.len;
  dieY = h / 2 / opts.len;
 });
 
 loop();
}

window.addEventListener ('load', function (e) { //загрузка приложения
 canvasApp('c');
}, false);
</script>

</head>
<body>
 <canvas id="c">
  Извините, Ваш браузер не поддерживает тег canvas.
 </canvas>
 <script>let test = 1;</script>
 <noscript>
  <p>Включите Javascript в браузере для работы приложения.</p>
 </noscript>
</body>
</html>

08.02.2023, 15:58 [284 просмотра]


теги: программирование javascript цвет графика random

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