html http://gbrlgrct.com/gists/53e9405a69ad5922c3ed/mandelbrot.html

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了html http://gbrlgrct.com/gists/53e9405a69ad5922c3ed/mandelbrot.html相关的知识,希望对你有一定的参考价值。

var last = 0;

onmessage = function (ev) {
  var result = draw.apply(null, ev.data.args);
  
  var buf = result.buffer;
  
  postMessage({
    buf: buf
  }, [buf]);
};

// inspired by https://www.shadertoy.com/view/4df3Rn
function draw(screenX, screenY, screenW, screenH, scale, maxiter) {
  var SCALE   = scale;
  var MAXITER = maxiter;
  
  var ISCALE = 1 / scale;
  
  var SCREENX = screenX;
  var SCREENY = screenY;
  
  var SCREENW = screenW;
  var SCREENH = screenH;
  
  var PLANEX = screenX * ISCALE;
  var PLANEY = screenY * ISCALE;
  
  var PLANEW = screenW * ISCALE;
  var PLANEH = screenH * ISCALE;
  
  var output = new Uint8ClampedArray(4 * SCREENW * SCREENH);
  
  for (var py = 0; py < SCREENH; ++py) {
    for (var px = 0; px < SCREENW; ++px) {
      var x0 = PLANEX + px * ISCALE;
      var y0 = PLANEY + py * ISCALE;
      var x = 0;
      var y = 0;
      
      var it = 0;
      var runaway = false;
      var dot = 0;
      
      for (var i = 0; i < MAXITER; ++i) {
        var x2 = x * x;
        var y2 = y * y;
        dot = x2 + y2;
        
        if (dot > 4.0) {
          it = i;
          runaway = true;
          break;
        }
        
        var xtmp = x2 - y2 + x0;
        y = 2*x*y + y0;
        x = xtmp;
      }
      
      var ix = 4 * (py * SCREENW + px);
      
      if (runaway) {
        var ip = i - Math.log2(Math.log2(dot * dot)) + 4.0;
        
        output[ix + 0] = 255 * (0.5 + 0.5 * Math.cos(3.0 + ip*0.15 + 0.0));
        output[ix + 1] = 255 * (0.5 + 0.5 * Math.cos(3.0 + ip*0.15 + 0.6));
        output[ix + 2] = 255 * (0.5 + 0.5 * Math.cos(3.0 + ip*0.15 + 1.0));
        output[ix + 3] = 255;
      } else {
        output[ix + 0] = 0;
        output[ix + 1] = 0;
        output[ix + 2] = 0;
        output[ix + 3] = 255;
      }
    }
  }
  
  return output;
}
<body style="margin:0"></body>

<script>

var CLICKZOOM = 3;
var NUMWORKERS = 8;

var workers = (function () {
  var w = [];
  
  for (var i = 0; i < NUMWORKERS; ++i)
    w.push(new Worker('worker.js'));
  
  return w;
})();

function sendWorkerDraw(i /* args */) {
  var args = [].slice.call(arguments, 1);
  
  return new Promise(function (resolve) {
    var worker = workers[i];
    
    worker.addEventListener('message', function done(ev) {
      worker.removeEventListener('message', done);
      
      resolve(ev.data.buf);
    });
    
    worker.postMessage({
      args: args
    });
  });
}

function draw(i, ctx, drawX, drawY, screenX, screenY, screenW, screenH, scale, maxiter) {
  sendWorkerDraw(i, screenX, screenY, screenW, screenH, scale, maxiter)
    .then(function (buf) {
      var arr  = new Uint8ClampedArray(buf);
      var data = new ImageData(arr, screenW, screenH);
      
      ctx.putImageData(data, drawX, drawY);
    });
}

function mandelbrot(canvas, planeX, planeY, scale, maxiter) {
  var SCALE   = scale;
  var MAXITER = maxiter;
  
  var ISCALE = 1 / scale;
  
  var PLANEX = planeX;
  var PLANEY = planeY;
  
  var SCREENX = PLANEX * SCALE;
  var SCREENY = PLANEY * SCALE;
  
  var SCREENW = canvas.width;
  var SCREENH = canvas.height;
  
  var PLANEW = SCREENW * ISCALE;
  var PLANEH = SCREENH * ISCALE;
  
  var ctx = canvas.getContext('2d');
  
  canvas.addEventListener('click', function zoom(ev) {
    canvas.removeEventListener('click', zoom);
    
    var px = ev.offsetX;
    var py = ev.offsetY;
    
    var scale_    = CLICKZOOM * SCALE;
    var maxiters_ = 1.4 * MAXITER;
    
    var planeW_ = SCREENW / scale_;
    var planeH_ = SCREENH / scale_;
    
    var planeX_ = PLANEX + px * ISCALE - planeW_ / 2;
    var planeY_ = PLANEY + py * ISCALE - planeH_ / 2;
    
    planeX_ += (SCREENW / 2 - px) / scale_;
    planeY_ += (SCREENH / 2 - py) / scale_;
    
    var copyW = SCREENW / CLICKZOOM;
    var copyH = SCREENH / CLICKZOOM;
    
    var copyX = px - copyW / 2;
    var copyY = py - copyH / 2;
    
    copyX += (SCREENW / 2 - px) / CLICKZOOM;
    copyY += (SCREENH / 2 - py) / CLICKZOOM;
    
    ctx.drawImage(
      canvas,
      copyX, copyY, copyW, copyH,
      0, 0, SCREENW, SCREENH
    );
    
    mandelbrot(canvas, planeX_, planeY_, scale_, maxiters_);
  });
  
  var BLOCKY = Math.ceil(SCREENH / NUMWORKERS);
  
  for (var i = 0; i < NUMWORKERS; ++i) {
    draw(
      i,
      
      ctx,
      0,
      i * SCREENH / NUMWORKERS,
      
      SCREENX,
      SCREENY + i * BLOCKY,
      SCREENW,
      BLOCKY,
      
      SCALE,
      MAXITER
    );
  }
  
  return canvas;
}

window.addEventListener('load', function () {
  var SCREENW = document.body.clientWidth
  var SCREENH = document.body.clientHeight;
  
  var canvas = document.createElement('canvas');
  canvas.width  = SCREENW;
  canvas.height = SCREENH;
  canvas.style.background = 'black';
  
  document.body.appendChild(canvas);
  
  var DOMAINX = -2.5;
  var DOMAINY = -1.1;
  
  var DOMAINW = 3.5;
  var DOMAINH = 2.2;
  
  var scale = Math.min(
    SCREENW / DOMAINW,
    SCREENH / DOMAINH
  );
  
  var startX = DOMAINX - (SCREENW - DOMAINW * scale) / 2 / scale;
  var startY = DOMAINY - (SCREENH - DOMAINH * scale) / 2 / scale;
  
  mandelbrot(canvas, startX, startY, scale, 100);
});

</script>

以上是关于html http://gbrlgrct.com/gists/53e9405a69ad5922c3ed/mandelbrot.html的主要内容,如果未能解决你的问题,请参考以下文章

html http://gbrlgrct.com/gists/0ec9f597e2c9b37fc868/pi.html

html http://gbrlgrct.com/gists/08640e24c907cc627eca/webgl-mandelbrot.html

html http://gbrlgrct.com/gists/a48a2a7ddb6b38d52194/starry.html

html http://gbrlgrct.com/gists/deec0c0c12e63a94515b/burn.html

html http://gbrlgrct.com/gists/53e9405a69ad5922c3ed/mandelbrot.html

html http://gbrlgrct.com/gists/cc5ea4bf19838a41e527/cardiod.html