»
EnglishFrenchVietnamese

Print - 3D Canvas Substrate in JavaScript - JavaScriptBank.com

Full version: jsB@nk » 3D » 3D Canvas Substrate in JavaScript
URL: https://www.javascriptbank.com/3d-canvas-substrate-in-javascript.html

3D Canvas Substrate in JavaScript © JavaScriptBank.comAnother JavaScript code to generate an 3D web effect, this JavaScript example uses HTML5 canvas element to draw the graphics.

Full version: jsB@nk » 3D » 3D Canvas Substrate in JavaScript
URL: https://www.javascriptbank.com/3d-canvas-substrate-in-javascript.html



CSS
<style type="text/css">#theCanvas {width: 800px;height: 600px;border: 1px solid black;}</style>


JavaScript
<!--[if IE]><script type="text/javascript" src="http://explorercanvas.googlecode.com/svn-history/r48/trunk/silverlight/excanvas.js"></script><![endif]--><script type="text/javascript" name="substrate.js" from="JavaScriptBank.com">/*     This script downloaded from www.JavaScriptBank.com     Come to view and download over 2000+ free javascript at www.JavaScriptBank.com*//**************************************** * Copyright Christopher Thomas 2006 * Based on (by which I mean almost entirely copied from) * http://complexification.net/gallery/machines/substrate/appletl/substrate_l.pde * Feel free to modify and redistribute this code. * * Inspired by the xscreensaver version based on the same code * *  Substrate code: *  j.tarbell   June, 2004 *  Albuquerque, New Mexico *  complexification.net * ****************************************/var ctx;var dimx = 800;var dimy = 600;var num = 0;var maxnum = 100;// grid of cracksvar cgrid = new Array(dimx*dimy);var cracks = [];// color parametersvar maxpal = 512;var numpal = 205;// I grabbed pollockShimmering.gif, converted it to XPM,// and used some perl to convert the hex colors to these linesvar goodcolor = ["rgba(0,0,0,XXX)","rgba(0,16,0,XXX)","rgba(104,104,112,XXX)","rgba(104,112,120,XXX)","rgba(104,88,88,XXX)","rgba(112,128,128,XXX)","rgba(120,120,128,XXX)","rgba(128,88,0,XXX)","rgba(144,104,72,XXX)","rgba(144,80,72,XXX)","rgba(144,88,24,XXX)","rgba(144,96,112,XXX)","rgba(152,104,112,XXX)","rgba(152,160,184,XXX)","rgba(152,48,16,XXX)","rgba(152,64,8,XXX)","rgba(16,0,0,XXX)","rgba(16,32,40,XXX)","rgba(160,112,120,XXX)","rgba(160,120,0,XXX)","rgba(160,120,72,XXX)","rgba(160,128,120,XXX)","rgba(160,144,120,XXX)","rgba(160,160,168,XXX)","rgba(160,56,16,XXX)","rgba(160,88,16,XXX)","rgba(168,144,112,XXX)","rgba(168,152,104,XXX)","rgba(168,152,72,XXX)","rgba(168,160,120,XXX)","rgba(168,168,128,XXX)","rgba(168,176,160,XXX)","rgba(168,40,24,XXX)","rgba(176,136,104,XXX)","rgba(176,144,32,XXX)","rgba(176,144,48,XXX)","rgba(176,160,152,XXX)","rgba(176,168,112,XXX)","rgba(176,168,144,XXX)","rgba(176,176,120,XXX)","rgba(176,176,152,XXX)","rgba(176,184,176,XXX)","rgba(176,192,184,XXX)","rgba(184,136,104,XXX)","rgba(184,184,168,XXX)","rgba(184,184,176,XXX)","rgba(192,152,136,XXX)","rgba(192,160,96,XXX)","rgba(192,176,120,XXX)","rgba(192,176,144,XXX)","rgba(192,192,144,XXX)","rgba(192,192,176,XXX)","rgba(200,160,120,XXX)","rgba(200,176,120,XXX)","rgba(200,176,96,XXX)","rgba(200,184,160,XXX)","rgba(200,192,152,XXX)","rgba(200,200,184,XXX)","rgba(208,176,120,XXX)","rgba(208,176,128,XXX)","rgba(208,176,176,XXX)","rgba(208,184,144,XXX)","rgba(208,192,160,XXX)","rgba(208,192,88,XXX)","rgba(208,200,160,XXX)","rgba(208,200,168,XXX)","rgba(208,200,176,XXX)","rgba(208,208,192,XXX)","rgba(216,192,112,XXX)","rgba(216,192,136,XXX)","rgba(216,192,160,XXX)","rgba(216,192,168,XXX)","rgba(216,192,176,XXX)","rgba(216,200,152,XXX)","rgba(216,200,160,XXX)","rgba(216,200,176,XXX)","rgba(216,208,176,XXX)","rgba(224,160,96,XXX)","rgba(224,176,128,XXX)","rgba(224,184,80,XXX)","rgba(224,200,160,XXX)","rgba(224,200,168,XXX)","rgba(224,200,88,XXX)","rgba(224,208,152,XXX)","rgba(224,208,160,XXX)","rgba(224,208,176,XXX)","rgba(224,216,160,XXX)","rgba(224,216,176,XXX)","rgba(224,216,184,XXX)","rgba(224,224,176,XXX)","rgba(224,224,184,XXX)","rgba(224,224,192,XXX)","rgba(232,184,120,XXX)","rgba(232,184,40,XXX)","rgba(232,192,120,XXX)","rgba(232,192,136,XXX)","rgba(232,200,128,XXX)","rgba(232,200,152,XXX)","rgba(232,200,72,XXX)","rgba(232,208,120,XXX)","rgba(232,208,80,XXX)","rgba(232,216,168,XXX)","rgba(232,216,192,XXX)","rgba(232,216,200,XXX)","rgba(232,224,128,XXX)","rgba(232,224,152,XXX)","rgba(232,224,176,XXX)","rgba(232,224,200,XXX)","rgba(232,232,216,XXX)","rgba(232,240,192,XXX)","rgba(232,240,216,XXX)","rgba(232,240,224,XXX)","rgba(240,200,104,XXX)","rgba(240,200,152,XXX)","rgba(240,208,152,XXX)","rgba(240,216,112,XXX)","rgba(240,216,144,XXX)","rgba(240,216,152,XXX)","rgba(240,216,192,XXX)","rgba(240,216,208,XXX)","rgba(240,224,128,XXX)","rgba(240,224,176,XXX)","rgba(240,224,184,XXX)","rgba(240,224,192,XXX)","rgba(240,232,160,XXX)","rgba(240,232,184,XXX)","rgba(240,232,192,XXX)","rgba(240,232,200,XXX)","rgba(240,232,208,XXX)","rgba(240,232,216,XXX)","rgba(240,240,192,XXX)","rgba(240,240,200,XXX)","rgba(240,240,208,XXX)","rgba(240,240,224,XXX)","rgba(240,248,168,XXX)","rgba(248,184,136,XXX)","rgba(248,184,40,XXX)","rgba(248,224,112,XXX)","rgba(248,224,160,XXX)","rgba(248,224,168,XXX)","rgba(248,224,176,XXX)","rgba(248,224,184,XXX)","rgba(248,224,192,XXX)","rgba(248,224,216,XXX)","rgba(248,224,80,XXX)","rgba(248,232,120,XXX)","rgba(248,232,184,XXX)","rgba(248,232,192,XXX)","rgba(248,232,208,XXX)","rgba(248,232,224,XXX)","rgba(248,240,184,XXX)","rgba(248,240,200,XXX)","rgba(248,240,208,XXX)","rgba(248,240,216,XXX)","rgba(248,248,208,XXX)","rgba(248,248,248,XXX)","rgba(255,152,40,XXX)","rgba(255,200,40,XXX)","rgba(255,208,112,XXX)","rgba(255,208,184,XXX)","rgba(255,208,40,XXX)","rgba(255,216,160,XXX)","rgba(255,216,168,XXX)","rgba(255,216,176,XXX)","rgba(255,224,120,XXX)","rgba(255,232,104,XXX)","rgba(255,232,120,XXX)","rgba(255,232,144,XXX)","rgba(255,232,152,XXX)","rgba(255,232,176,XXX)","rgba(255,232,184,XXX)","rgba(255,232,192,XXX)","rgba(255,232,200,XXX)","rgba(255,232,208,XXX)","rgba(255,240,152,XXX)","rgba(255,240,160,XXX)","rgba(255,240,184,XXX)","rgba(255,240,192,XXX)","rgba(255,240,200,XXX)","rgba(255,240,208,XXX)","rgba(255,240,216,XXX)","rgba(255,240,232,XXX)","rgba(255,240,248,XXX)","rgba(255,248,176,XXX)","rgba(255,248,192,XXX)","rgba(255,248,200,XXX)","rgba(255,248,208,XXX)","rgba(255,248,216,XXX)","rgba(255,248,224,XXX)","rgba(255,255,200,XXX)","rgba(255,255,208,XXX)","rgba(255,255,216,XXX)","rgba(48,32,8,XXX)","rgba(56,40,16,XXX)","rgba(56,56,40,XXX)","rgba(56,64,48,XXX)","rgba(72,72,88,XXX)","rgba(80,16,0,XXX)","rgba(80,88,96,XXX)","rgba(88,104,104,XXX)","rgba(88,104,88,XXX)","rgba(88,40,0,XXX)","rgba(88,80,72,XXX)","rgba(88,88,56,XXX)","rgba(96,112,112,XXX)","rgba(96,56,16,XXX)"]; // hmmm FIXMEvar doColor = false;// sand painters//var sands = [];// MAIN METHODS -------------function setup() {  cgrid = []; // size for dimx * dimy  cracks = [];/*  for (var i=0; i<maxnum; i++) {    cracks[i] = new Crack();  }*/  ctx = document.getElementById("theCanvas").getContext("2d");}function draw() {  // crack all cracks  for (var i=0; i<num; i++) {    cracks[i].move();/*    if (!confirm(i))      null[5] = 0;*/  }}// METHODS ------------------------function rand(start, stop) {  if (!stop) {    stop = start;    start = 0;  }  var diff = stop - start;  var r = Math.random() * diff;  if (r == diff)    r *= .99; // JS Math.random() can return 1.0  return r + start;}function makeCrack() {  if (num < maxnum) {    // make a new crack instance    cracks[num] = new Crack();    num++;  }}function begin() {  // erase crack grid  for (var y=0; y<dimy; y++) {    var rowOffset = y*dimx;    for (var x=0; x<dimx; x++) {      cgrid[rowOffset+x] = 10001;    }  }  // make random crack seeds  var k;  for (k=0; k<16; k++) {    var i = Math.floor(rand(dimx*dimy-1));    cgrid[i] = Math.floor(rand(360));  }  // make just three cracks  num = 0;  for (k=0; k<3; k++) {    makeCrack();  }}function somecolor() {  var index = Math.floor(rand(numpal));  return goodcolor[index];}// OBJECTS -------------------------------------function Crack() {  this.x = null;  this.y = null;  this.t = null;  this.findStart();  this.sp = new SandPainter();}Crack.prototype.findStart = function Crack_findStart() {  // pick a random point  var px = 0;  var py = 0;  // shift until crack is found  var found = false;  var timeout = 0;  while ((!found) || (timeout++ > 1000)) {    px = Math.floor(rand(dimx));    py = Math.floor(rand(dimy));    if (cgrid[py*dimx+px]<10000)      found = true;  }    if (found) {    // start crack    var a = cgrid[py*dimx+px];    if (Math.random()*100 < 50)      a -= 90+Math.floor(rand(-2, 2.1));    else      a += 90+Math.floor(rand(-2, 2.1));    this.startCrack(px, py, a);  }  else {    // no crack foun after timeout  }};Crack.prototype.startCrack = function Crack_startCrack(X, Y, T) {  this.x = X;  this.y = Y;  this.t = T;  //alert(X + " " + Y + " " + T);  //null[5]=0;  this.x += 0.61*Math.cos(this.t*3.14159/180);  this.y += 0.61*Math.sin(this.t*3.14159/180);};Crack.prototype.move = function Crack_move() {  // continue cracking  this.x += 0.42*Math.cos(this.t*3.14159/180);  this.y += 0.42*Math.sin(this.t*3.14159/180);  // bound check  var z = 0.33;  var cx = Math.floor(this.x+rand(-z, z)); // add fuzz  //alert(this.x + " " + cx);  var cy = Math.floor(this.y+rand(-z, z));  // draw sand painter  if (doColor)    this.regionColor();  // draw black crack  //stroke(0, 85); //???  ctx.fillStyle = "rgb(0,0,0)";  var tmpx = Math.floor(this.x + rand(-z, z));  var tmpy = Math.floor(this.y + rand(-z, z));  //alert(tmpx + ", " + tmpy + " - " + z);null[5]=0;  ctx.fillRect(tmpx,       tmpy,       1, 1);  if ((cx >=0 ) && (cx < dimx) && (cy >= 0) & (cy < dimy)) {    // safe to check    if ((cgrid[cy*dimx+cx] > 10000) || Math.abs(cgrid[cy*dimx+cx]-this.t)<5) {      // continue cracking      cgrid[cy*dimx+cx] = Math.floor(this.t);    }    else if (Math.abs(cgrid[cy*dimx+cx]-this.t) > 2) {      // different crack encountered, stop cracking      //alert("different crack"); null[5] = 0;      this.findStart();      makeCrack();    }  }  else {    // out of bounds, stop cracking    //alert("out of bounds: " + this.x + ", " +  this.y); null[5] = 0;    this.findStart();    makeCrack();  }};Crack.prototype.regionColor = function Crack_regionColor() {  // start checking one step away  var rx = this.x;  var ry = this.y;  var openspace = true;  var dx = 0.81*Math.sin(this.t*3.14159/180);  var dy = 0.81*Math.cos(this.t*3.14159/180)  // find extents of open space  while (openspace) {    // move perpendicular to crack    rx += dx;    ry -= dy;    var cx = Math.floor(rx);    var cy = Math.floor(ry);    if ((cx >= 0) && (cx < dimx) && (cy >= 0) && (cy < dimy)) {      // safe to check      if (cgrid[cy*dimx+cx]>10000) {// space is open      } else {openspace = false;      }    } else {      openspace = false;    }    // draw sand painter    //this.sp.render(rx, ry, this.x, this.y);    ////////////////////////////////////    /// uncomment the previous line and comment out the rest of this function's body    /// to get the original behavior (too slow due to canvas performance)    ////////////////////////////////////  }  var grad = ctx.createLinearGradient(this.x, this.y, rx, ry);  grad.addColorStop(0, this.sp.color.replace(/XXX/, 0.1));  grad.addColorStop(rand(.25), this.sp.color.replace(/XXX/, 0.1+rand(-.05, .05)));  grad.addColorStop(rand(.5), this.sp.color.replace(/XXX/, 0.1+rand(-.1, .05)));  grad.addColorStop(rand(.75), this.sp.color.replace(/XXX/, 0.05+rand(-.05, 0)));  grad.addColorStop(rand(1), this.sp.color.replace(/XXX/, 0.02+rand(-.02, 0)));  grad.addColorStop(1, this.sp.color.replace(/XXX/, 0));  ctx.strokeStyle = grad;  ctx.moveTo(this.x, this.y);  ctx.lineTo(rx, ry);  ctx.stroke();};function SandPainter() {  this.color = null;  this.g = null;  this.color = somecolor();  this.g = rand(0.01, 0.1);}SandPainter.prototype.render = function SandPainter_render(x, y, ox, oy) {  // modulate gain  this.g += rand(-0.05, 0.05);  var maxg = 1.0;  if (this.g < 0) this.g = 0;  if (this.g > maxg) this.g = maxg;  // calculate grains by distance  //var grains = 64;  var grains = 4;  // lay down grains of sand (transparent pixels)  var w = this.g/(grains-1);  var oldx = -1;  var oldy = -1;  for (var i=0; i<grains; i++) {    var a = 0.1-i/(grains*10.0);    a /= 2;    var x2, y2;    x2 = Math.floor(ox+(x-ox)*Math.sin(Math.sin(i*w)));    y2 = Math.floor(oy+(y-oy)*Math.sin(Math.sin(i*w)));    if (oldx != x2 && oldy != y2) {      ctx.fillStyle = this.color.replace(/XXX/, a);      ctx.fillRect(x2, y2, 1, 1);      oldx = x2;      oldy = y2;    }  }}</script>


HTML
<p>This is a port of the code from <a href="http://complexification.net/gallery/machines/substrate/">here</a> to JavaScript (modified slightly for performance reasons).  It depends on the &lt;canvas&gt; tag, so you'll need a web browser like SeaMonkey 1.0, Firefox 1.5, Camino 1.0, Safari, or newer (I only tested with SeaMonkey though).  Your browser is probably going to hang for a couple of seconds when you click "Begin".</p><p><input type="button" value="Begin" id="b" onclick="setup();begin();setInterval(draw, 100);document.getElementById('b').setAttribute('disabled', true);document.getElementById('doColor').setAttribute('disabled', true);"/> <input type="checkbox" name="doColor" id="doColor" value="color" onclick="doColor = document.getElementById('doColor').checked"/> Colorize (SLOW)</p><canvas id="theCanvas" width="800" height="600"><div style="background: red; font-size: 14pt;">Your browser doesn't support a required feature (the <a href="http://www.google.com/search?q=html+canvas+tag&amp;start=0&amp;start=0&amp;ie=utf-8&amp;oe=utf-8&amp;client=mozilla&amp;rls=org.mozilla:en-US:unofficial">HTML Canvas tag</a>).  You could get a <a href="http://www.mozilla.org/projects/seamonkey">better browser</a> (or <a href="http://www.mozilla.com/">this one</a>, or, if you're on a Mac, Safari).</div></canvas>