Full version: jsB@nk » 3D » 3D Canvas Substrate in JavaScript
URL: https://www.javascriptbank.com/3d-canvas-substrate-in-javascript.html
Another 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
<style type="text/css">#theCanvas {width: 800px;height: 600px;border: 1px solid black;}</style>
<!--[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>
<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 <canvas> 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&start=0&start=0&ie=utf-8&oe=utf-8&client=mozilla&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>