ASCII 3D Cube zz85 Follow 2012-04-26 01:11:03 License: MIT License Fork5 Fav2 View20412 Play Stop Reload Fullscreen Smart Phone Fork tree Readme JavaScript 421 lines HTML 16 lines CSS 7 lines An ASCII renderer for the Three.js library! Based on nihilogic's jsascii library. (still requires canvas support). Another treat after google's 8bit maps :D added this to github too. https://github.com/zz85/ThreeLabs maybe it could into the main library [update: This tool is now in three.js r49 renamed to AsciiEffect] ASCII 3D Cube /* * Yeah, I had another crazy idea I had while in the bath just now - * the ability to render THREE.js scenes in ASCII - * with a THREE.AsciiRenderer. Okay, maybe this isn't original (https://github.com/trevlovett/AsciiTracer) * and ASCII has been quite a "popular" thing I think * like http://256.io/escapes.js/ but I thought I could do a quick meshup in 15 minutes. * okay, at least with some help from some ASCII converters. I looked quickly at * https://github.com/saw/Canvas-ASCII-Art#readme, https://github.com/horndude77/ascii-canvas * but finally decided to go with http://www.nihilogic.dk/labs/jsascii/ * 'cause it looked the most hackable :) * okay, ended up i took more than 15 minutes, and something more like 2 hours but most of the time turned into * and squashing some bugs. - just realized this demo look quite boring too, but feel free to add more * rotation to the cube or whatever by forking the code and editing a few lines at the bottom... * * 16 April 2012 - @blurspline */ // Some settings var bResolution = 0.15; var iScale = 1; var bColor = false; // nice but slows down rendering! var bAlpha = false; var bBlock = false; var bInvert = false; var strResolution = 'low'; THREE.ASCIIRenderer = function() { var canvasRenderer = new THREE.CanvasRenderer(); var width, height; var domElement = document.createElement('div'); var ascii = document.createElement("table"); domElement.appendChild(ascii); this.setSize = function(w, h) { canvasRenderer.setSize( w, h ); } this.render = function() { canvasRenderer.render.apply(canvasRenderer, arguments); asciifyImage(canvasRenderer.domElement, canvasRenderer, ascii); } this.domElement = domElement; }; // Throw in ascii library /* * jsAscii 0.1 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/ * MIT License [http://www.nihilogic.dk/licenses/mit-license.txt] */ var aDefaultCharList = (" .,:;i1tfLCG08@").split(""); var aDefaultColorCharList = (" CGO08@").split(""); var strFont = "courier new"; // convert img element to ascii function asciifyImage(oImg, canvasRenderer, oAscii) { var fakeWidth = window.innerWidth; var fakeHeight = window.innerHeight; var oCanvasImg = canvasRenderer.domElement; var oCanvas = document.createElement("canvas"); if (!oCanvas.getContext) { return; } var oCtx = oCanvas.getContext("2d"); if (!oCtx.getImageData) { return; } var aCharList = (bColor ? aDefaultColorCharList : aDefaultCharList); var fResolution = 0.5; switch (strResolution) { case "low" : fResolution = 0.25; break; case "medium" : fResolution = 0.5; break; case "high" : fResolution = 1; break; } if (bResolution) fResolution = bResolution; var iWidth = Math.round(fakeWidth * fResolution); var iHeight = Math.round(fakeHeight * fResolution); oCanvas.width = iWidth; oCanvas.height = iHeight; oCanvas.style.display = "none"; oCanvas.style.width = iWidth; oCanvas.style.height = iHeight; oCtx.drawImage(oCanvasImg, 0, 0, iWidth, iHeight); var oImgData = oCtx.getImageData(0, 0, iWidth, iHeight).data; var strChars = ""; for (var y=0;y<iHeight;y+=2) { for (var x=0;x<iWidth;x++) { var iOffset = (y*iWidth + x) * 4; var iRed = oImgData[iOffset]; var iGreen = oImgData[iOffset + 1]; var iBlue = oImgData[iOffset + 2]; var iAlpha = oImgData[iOffset + 3]; var iCharIdx; var fBrightness; fBrightness = (0.3*iRed + 0.59*iGreen + 0.11*iBlue) / 255; if (iAlpha == 0) { // should calculate alpha instead, but quick hack :) //fBrightness *= (iAlpha / 255); fBrightness = 1; } iCharIdx = Math.floor((1-fBrightness) * (aCharList.length-1)); if (bInvert) { iCharIdx = aCharList.length - iCharIdx - 1; } // good for debugging //fBrightness = Math.floor(fBrightness * 10); //strThisChar = fBrightness; var strThisChar = aCharList[iCharIdx]; if (strThisChar===undefined || strThisChar == " ") strThisChar = " "; if (bColor) { strChars += "<span style='" + "color:rgb("+iRed+","+iGreen+","+iBlue+");" + (bBlock ? "background-color:rgb("+iRed+","+iGreen+","+iBlue+");" : "") + (bAlpha ? "opacity:" + (iAlpha/255) + ";" : "") + "'>" + strThisChar + "</span>"; } else { strChars += strThisChar; } } strChars += "<br/>"; } var fFontSize = (2/fResolution)*iScale; var fLineHeight = (2/fResolution)*iScale; // adjust letter-spacing for all combinations of scale and resolution to get it to fit the image width. var fLetterSpacing = 0; if (strResolution == "low") { switch (iScale) { case 1 : fLetterSpacing = -1; break; case 2 : case 3 : fLetterSpacing = -2.1; break; case 4 : fLetterSpacing = -3.1; break; case 5 : fLetterSpacing = -4.15; break; } } if (strResolution == "medium") { switch (iScale) { case 1 : fLetterSpacing = 0; break; case 2 : fLetterSpacing = -1; break; case 3 : fLetterSpacing = -1.04; break; case 4 : case 5 : fLetterSpacing = -2.1; break; } } if (strResolution == "high") { switch (iScale) { case 1 : case 2 : fLetterSpacing = 0; break; case 3 : case 4 : case 5 : fLetterSpacing = -1; break; } } // can't get a span or div to flow like an img element, but a table works? oAscii.innerHTML = "<tr><td>" + strChars + "</td></tr>"; if (oImg.style.backgroundColor) { oAscii.rows[0].cells[0].style.backgroundColor = oImg.style.backgroundColor; oAscii.rows[0].cells[0].style.color = oImg.style.color; } oAscii.cellSpacing = 0; oAscii.cellPadding = 0; var oStyle = oAscii.style; oStyle.display = "inline"; oStyle.width = Math.round(iWidth/fResolution*iScale) + "px"; oStyle.height = Math.round(iHeight/fResolution*iScale) + "px"; oStyle.whiteSpace = "pre"; oStyle.margin = "0px"; oStyle.padding = "0px"; oStyle.letterSpacing = fLetterSpacing + "px"; oStyle.fontFamily = strFont; oStyle.fontSize = fFontSize + "px"; oStyle.lineHeight = fLineHeight + "px"; oStyle.textAlign = "left"; oStyle.textDecoration = "none"; // replaces old image with ascii table //oImg.parentNode.replaceChild(oAscii, oImg); return oAscii; } function asciifyImageLoad(oImg) { var oCanvasImg = new Image(); oCanvasImg.src = oImg.src; if (oCanvasImg.complete) { return asciifyImage(oImg, oCanvasImg); } else { oCanvasImg.onload = function() { return asciifyImage(oImg, oCanvasImg) } } } /* return function() { var aImg = document.getElementsByTagName("img"); var aImages = []; for (var i=0;i<aImg.length;i++) { aImages[i] = aImg[i]; } for (var i=0;i<aImages.length;i++) { if (aImages[i].getAttribute("asciify") == "true") { asciifyImageLoad(aImages[i]); } } } */ // end modified http://www.nihilogic.dk/labs/jsascii/jsascii.js // Let's start with the class spinning cube example from three.js // Just swap out the default CanvasRenderer -> AsciiRenderer and things should work // Let's start with the class spinning cube example from three.js var container, stats; var camera, scene, renderer; var cube, plane; var targetYRotation = targetXRotation = 0; var targetYRotationOnMouseDown = targetXRotationOnMouseDown = 0; var mouseX = 0, mouseY = 0; var mouseYOnMouseDown = mouseXOnMouseDown = 0; var windowHalfX = window.innerWidth / 2; var windowHalfY = window.innerHeight / 2; init(); animate(); function init() { container = document.createElement( 'div' ); document.body.appendChild( container ); var info = document.createElement( 'div' ); info.style.position = 'absolute'; info.style.top = '10px'; info.style.width = '100%'; info.style.textAlign = 'center'; info.innerHTML = 'Drag to spin the cube'; container.appendChild( info ); scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 ); camera.position.y = 150; camera.position.z = 500; scene.add( camera ); // Cube var materials = []; for ( var i = 0; i < 6; i ++ ) { materials.push( new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff } ) ); } cube = new THREE.Mesh( new THREE.CubeGeometry( 200, 200, 200, 1, 1, 1, materials ), new THREE.MeshFaceMaterial() ); cube.position.y = 150; scene.add( cube ); // Plane plane = new THREE.Mesh( new THREE.PlaneGeometry( 400, 400 ), new THREE.MeshBasicMaterial( { color: 0xe0e0e0 } ) ); //plane.rotation.x = - 90 * ( Math.PI / 180 ); scene.add( plane ); renderer = new THREE.ASCIIRenderer(); //THREE.CanvasRenderer renderer.setSize( window.innerWidth, window.innerHeight ); container.appendChild( renderer.domElement ); stats = new Stats(); stats.domElement.style.position = 'absolute'; stats.domElement.style.top = '0px'; container.appendChild( stats.domElement ); document.addEventListener( 'mousedown', onDocumentMouseDown, false ); document.addEventListener( 'touchstart', onDocumentTouchStart, false ); document.addEventListener( 'touchmove', onDocumentTouchMove, false ); } // function onDocumentMouseDown( event ) { event.preventDefault(); document.addEventListener( 'mousemove', onDocumentMouseMove, false ); document.addEventListener( 'mouseup', onDocumentMouseUp, false ); document.addEventListener( 'mouseout', onDocumentMouseOut, false ); mouseXOnMouseDown = event.clientX - windowHalfX; mouseYOnMouseDown = event.clientY - windowHalfY; targetYRotationOnMouseDown = targetYRotation; targetXRotationOnMouseDown = targetXRotation; } function onDocumentMouseMove( event ) { mouseX = event.clientX - windowHalfX; targetYRotation = targetYRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.02; targetXRotation = targetXRotationOnMouseDown + ( mouseY - mouseYOnMouseDown ) * 0.02; } function onDocumentMouseUp( event ) { document.removeEventListener( 'mousemove', onDocumentMouseMove, false ); document.removeEventListener( 'mouseup', onDocumentMouseUp, false ); document.removeEventListener( 'mouseout', onDocumentMouseOut, false ); } function onDocumentMouseOut( event ) { document.removeEventListener( 'mousemove', onDocumentMouseMove, false ); document.removeEventListener( 'mouseup', onDocumentMouseUp, false ); document.removeEventListener( 'mouseout', onDocumentMouseOut, false ); } function onDocumentTouchStart( event ) { if ( event.touches.length == 1 ) { event.preventDefault(); mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX; targetRotationOnMouseDown = targetRotation; } } function onDocumentTouchMove( event ) { if ( event.touches.length == 1 ) { event.preventDefault(); mouseX = event.touches[ 0 ].pageX - windowHalfX; targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.05;; } } // function animate() { requestAnimationFrame( animate ); render(); stats.update(); } function render() { cube.rotation.x += ( targetXRotation - cube.rotation.x ) * 0.05; plane.rotation.y = cube.rotation.y += ( targetYRotation - cube.rotation.y ) * 0.05; renderer.render( scene, camera ); } <!doctype html> <html lang="en"> <head> <title>three.js ASCII - geometry - cube</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> </head> <body> <script src="http://mrdoob.github.com/three.js/build/Three.js"></script> <script src="http://mrdoob.github.com/three.js/examples/js/Stats.js"></script> </body> </html> ASCII 3D Cube body { font-family: Monospace; background-color: #f0f0f0; margin: 0px; overflow: hidden; /**/ } An ASCII renderer for the Three.js library! Based on nihilogic's jsascii library. (still requires canvas support). Another treat after google's 8bit maps :D added this to github too. https://github.com/zz85/ThreeLabs maybe it could into the main library [update: This tool is now in three.js r49 renamed to AsciiEffect] /* * Yeah, I had another crazy idea I had while in the bath just now - * the ability to render THREE.js scenes in ASCII - * with a THREE.AsciiRenderer. Okay, maybe this isn't original (https://github.com/trevlovett/AsciiTracer) * and ASCII has been quite a "popular" thing I think * like http://256.io/escapes.js/ but I thought I could do a quick meshup in 15 minutes. * okay, at least with some help from some ASCII converters. I looked quickly at * https://github.com/saw/Canvas-ASCII-Art#readme, https://github.com/horndude77/ascii-canvas * but finally decided to go with http://www.nihilogic.dk/labs/jsascii/ * 'cause it looked the most hackable :) * okay, ended up i took more than 15 minutes, and something more like 2 hours but most of the time turned into * and squashing some bugs. - just realized this demo look quite boring too, but feel free to add more * rotation to the cube or whatever by forking the code and editing a few lines at the bottom... * * 16 April 2012 - @blurspline */ // Some settings var bResolution = 0.15; var iScale = 1; var bColor = false; // nice but slows down rendering! var bAlpha = false; var bBlock = false; var bInvert = false; var strResolution = 'low'; THREE.ASCIIRenderer = function() { var canvasRenderer = new THREE.CanvasRenderer(); var width, height; var domElement = document.createElement('div'); var ascii = document.createElement("table"); domElement.appendChild(ascii); this.setSize = function(w, h) { canvasRenderer.setSize( w, h ); } this.render = function() { canvasRenderer.render.apply(canvasRenderer, arguments); asciifyImage(canvasRenderer.domElement, canvasRenderer, ascii); } this.domElement = domElement; }; // Throw in ascii library /* * jsAscii 0.1 * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/ * MIT License [http://www.nihilogic.dk/licenses/mit-license.txt] */ var aDefaultCharList = (" .,:;i1tfLCG08@").split(""); var aDefaultColorCharList = (" CGO08@").split(""); var strFont = "courier new"; // convert img element to ascii function asciifyImage(oImg, canvasRenderer, oAscii) { var fakeWidth = window.innerWidth; var fakeHeight = window.innerHeight; var oCanvasImg = canvasRenderer.domElement; var oCanvas = document.createElement("canvas"); if (!oCanvas.getContext) { return; } var oCtx = oCanvas.getContext("2d"); if (!oCtx.getImageData) { return; } var aCharList = (bColor ? aDefaultColorCharList : aDefaultCharList); var fResolution = 0.5; switch (strResolution) { case "low" : fResolution = 0.25; break; case "medium" : fResolution = 0.5; break; case "high" : fResolution = 1; break; } if (bResolution) fResolution = bResolution; var iWidth = Math.round(fakeWidth * fResolution); var iHeight = Math.round(fakeHeight * fResolution); oCanvas.width = iWidth; oCanvas.height = iHeight; oCanvas.style.display = "none"; oCanvas.style.width = iWidth; oCanvas.style.height = iHeight; oCtx.drawImage(oCanvasImg, 0, 0, iWidth, iHeight); var oImgData = oCtx.getImageData(0, 0, iWidth, iHeight).data; var strChars = ""; for (var y=0;y<iHeight;y+=2) { for (var x=0;x<iWidth;x++) { var iOffset = (y*iWidth + x) * 4; var iRed = oImgData[iOffset]; var iGreen = oImgData[iOffset + 1]; var iBlue = oImgData[iOffset + 2]; var iAlpha = oImgData[iOffset + 3]; var iCharIdx; var fBrightness; fBrightness = (0.3*iRed + 0.59*iGreen + 0.11*iBlue) / 255; if (iAlpha == 0) { // should calculate alpha instead, but quick hack :) //fBrightness *= (iAlpha / 255); fBrightness = 1; } iCharIdx = Math.floor((1-fBrightness) * (aCharList.length-1)); if (bInvert) { iCharIdx = aCharList.length - iCharIdx - 1; } // good for debugging //fBrightness = Math.floor(fBrightness * 10); //strThisChar = fBrightness; var strThisChar = aCharList[iCharIdx]; if (strThisChar===undefined || strThisChar == " ") strThisChar = " "; if (bColor) { strChars += "<span style='" + "color:rgb("+iRed+","+iGreen+","+iBlue+");" + (bBlock ? "background-color:rgb("+iRed+","+iGreen+","+iBlue+");" : "") + (bAlpha ? "opacity:" + (iAlpha/255) + ";" : "") + "'>" + strThisChar + "</span>"; } else { strChars += strThisChar; } } strChars += "<br/>"; } var fFontSize = (2/fResolution)*iScale; var fLineHeight = (2/fResolution)*iScale; // adjust letter-spacing for all combinations of scale and resolution to get it to fit the image width. var fLetterSpacing = 0; if (strResolution == "low") { switch (iScale) { case 1 : fLetterSpacing = -1; break; case 2 : case 3 : fLetterSpacing = -2.1; break; case 4 : fLetterSpacing = -3.1; break; case 5 : fLetterSpacing = -4.15; break; } } if (strResolution == "medium") { switch (iScale) { case 1 : fLetterSpacing = 0; break; case 2 : fLetterSpacing = -1; break; case 3 : fLetterSpacing = -1.04; break; case 4 : case 5 : fLetterSpacing = -2.1; break; } } if (strResolution == "high") { switch (iScale) { case 1 : case 2 : fLetterSpacing = 0; break; case 3 : case 4 : case 5 : fLetterSpacing = -1; break; } } // can't get a span or div to flow like an img element, but a table works? oAscii.innerHTML = "<tr><td>" + strChars + "</td></tr>"; if (oImg.style.backgroundColor) { oAscii.rows[0].cells[0].style.backgroundColor = oImg.style.backgroundColor; oAscii.rows[0].cells[0].style.color = oImg.style.color; } oAscii.cellSpacing = 0; oAscii.cellPadding = 0; var oStyle = oAscii.style; oStyle.display = "inline"; oStyle.width = Math.round(iWidth/fResolution*iScale) + "px"; oStyle.height = Math.round(iHeight/fResolution*iScale) + "px"; oStyle.whiteSpace = "pre"; oStyle.margin = "0px"; oStyle.padding = "0px"; oStyle.letterSpacing = fLetterSpacing + "px"; oStyle.fontFamily = strFont; oStyle.fontSize = fFontSize + "px"; oStyle.lineHeight = fLineHeight + "px"; oStyle.textAlign = "left"; oStyle.textDecoration = "none"; // replaces old image with ascii table //oImg.parentNode.replaceChild(oAscii, oImg); return oAscii; } function asciifyImageLoad(oImg) { var oCanvasImg = new Image(); oCanvasImg.src = oImg.src; if (oCanvasImg.complete) { return asciifyImage(oImg, oCanvasImg); } else { oCanvasImg.onload = function() { return asciifyImage(oImg, oCanvasImg) } } } /* return function() { var aImg = document.getElementsByTagName("img"); var aImages = []; for (var i=0;i<aImg.length;i++) { aImages[i] = aImg[i]; } for (var i=0;i<aImages.length;i++) { if (aImages[i].getAttribute("asciify") == "true") { asciifyImageLoad(aImages[i]); } } } */ // end modified http://www.nihilogic.dk/labs/jsascii/jsascii.js // Let's start with the class spinning cube example from three.js // Just swap out the default CanvasRenderer -> AsciiRenderer and things should work // Let's start with the class spinning cube example from three.js var container, stats; var camera, scene, renderer; var cube, plane; var targetYRotation = targetXRotation = 0; var targetYRotationOnMouseDown = targetXRotationOnMouseDown = 0; var mouseX = 0, mouseY = 0; var mouseYOnMouseDown = mouseXOnMouseDown = 0; var windowHalfX = window.innerWidth / 2; var windowHalfY = window.innerHeight / 2; init(); animate(); function init() { container = document.createElement( 'div' ); document.body.appendChild( container ); var info = document.createElement( 'div' ); info.style.position = 'absolute'; info.style.top = '10px'; info.style.width = '100%'; info.style.textAlign = 'center'; info.innerHTML = 'Drag to spin the cube'; container.appendChild( info ); scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 ); camera.position.y = 150; camera.position.z = 500; scene.add( camera ); // Cube var materials = []; for ( var i = 0; i < 6; i ++ ) { materials.push( new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff } ) ); } cube = new THREE.Mesh( new THREE.CubeGeometry( 200, 200, 200, 1, 1, 1, materials ), new THREE.MeshFaceMaterial() ); cube.position.y = 150; scene.add( cube ); // Plane plane = new THREE.Mesh( new THREE.PlaneGeometry( 400, 400 ), new THREE.MeshBasicMaterial( { color: 0xe0e0e0 } ) ); //plane.rotation.x = - 90 * ( Math.PI / 180 ); scene.add( plane ); renderer = new THREE.ASCIIRenderer(); //THREE.CanvasRenderer renderer.setSize( window.innerWidth, window.innerHeight ); container.appendChild( renderer.domElement ); stats = new Stats(); stats.domElement.style.position = 'absolute'; stats.domElement.style.top = '0px'; container.appendChild( stats.domElement ); document.addEventListener( 'mousedown', onDocumentMouseDown, false ); document.addEventListener( 'touchstart', onDocumentTouchStart, false ); document.addEventListener( 'touchmove', onDocumentTouchMove, false ); } // function onDocumentMouseDown( event ) { event.preventDefault(); document.addEventListener( 'mousemove', onDocumentMouseMove, false ); document.addEventListener( 'mouseup', onDocumentMouseUp, false ); document.addEventListener( 'mouseout', onDocumentMouseOut, false ); mouseXOnMouseDown = event.clientX - windowHalfX; mouseYOnMouseDown = event.clientY - windowHalfY; targetYRotationOnMouseDown = targetYRotation; targetXRotationOnMouseDown = targetXRotation; } function onDocumentMouseMove( event ) { mouseX = event.clientX - windowHalfX; targetYRotation = targetYRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.02; targetXRotation = targetXRotationOnMouseDown + ( mouseY - mouseYOnMouseDown ) * 0.02; } function onDocumentMouseUp( event ) { document.removeEventListener( 'mousemove', onDocumentMouseMove, false ); document.removeEventListener( 'mouseup', onDocumentMouseUp, false ); document.removeEventListener( 'mouseout', onDocumentMouseOut, false ); } function onDocumentMouseOut( event ) { document.removeEventListener( 'mousemove', onDocumentMouseMove, false ); document.removeEventListener( 'mouseup', onDocumentMouseUp, false ); document.removeEventListener( 'mouseout', onDocumentMouseOut, false ); } function onDocumentTouchStart( event ) { if ( event.touches.length == 1 ) { event.preventDefault(); mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX; targetRotationOnMouseDown = targetRotation; } } function onDocumentTouchMove( event ) { if ( event.touches.length == 1 ) { event.preventDefault(); mouseX = event.touches[ 0 ].pageX - windowHalfX; targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.05;; } } // function animate() { requestAnimationFrame( animate ); render(); stats.update(); } function render() { cube.rotation.x += ( targetXRotation - cube.rotation.x ) * 0.05; plane.rotation.y = cube.rotation.y += ( targetYRotation - cube.rotation.y ) * 0.05; renderer.render( scene, camera ); } <!doctype html> <html lang="en"> <head> <title>three.js ASCII - geometry - cube</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> </head> <body> <script src="http://mrdoob.github.com/three.js/build/Three.js"></script> <script src="http://mrdoob.github.com/three.js/examples/js/Stats.js"></script> </body> </html> body { font-family: Monospace; background-color: #f0f0f0; margin: 0px; overflow: hidden; /**/ } use an iframe compat browser, deer Play on jsdo.it games Author Share ブログに埋め込む QR Tag Download Complete! Description What kind of game? An ASCII renderer for the Three.js library! Based on nihilogic's jsascii library. (still requires canvas support). Another treat after google's 8bit maps :D added this to github too. https://github.com/zz85/ThreeLabs maybe it could into the main library [update: This tool is now in three.js r49 renamed to AsciiEffect] Control Device Smartphone Controllerjsdo.it WebSocket Controller» Mouse Keyboard Touch Device Fullscreen Activated Inactivated jsdo.it games から削除する Submit Author zz85 URLhttp://www.lab4games.net/zz85/blog learning and playing with visual effects with javascript! twitter: http://twitter.com/blurspline github: https://github.com/zz85 Tweet Default Panel Auto play Screenshot Readme JavaScript HTML CSS Size Width: px Height: px code <script type="text/javascript" src="http://jsdo.it/blogparts/8gb9/js"></script> 3d, 3d, 8bit, 8bit, art&design ascii, ascii, cube, cube, library&test terminal terminal Discussion Questions on this code? Tags 3d 3d, 8bit, art&design ascii, cube, library&test terminal Favorite by tmake akm2: 3dart&design Forked sort by latest page views favorite forked forked: ASCII 3D Cube jt5d 00 1780 422/16/7 3d, 8bit, art&design ascii, cube, library&test terminal forked: ASCII 3D Cube alvarobyrne 00 2094 424/17/10 3d, 8bit, art&design ascii, cube, library&test terminal forked: ASCII 3D Cube baduncadunca 00 1892 422/16/7 3d, 8bit, art&design ascii, cube, library&test terminal forked: ASCII 3D Cube legacycrono 00 2040 422/16/7 3d, 8bit, art&design ascii, cube, library&test terminal 1 2NEXT>>