Skip to content

Instantly share code, notes, and snippets.

@duhaime
Last active February 5, 2018 00:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save duhaime/890cbdd0b95052d36450aeee0ef110db to your computer and use it in GitHub Desktop.
Save duhaime/890cbdd0b95052d36450aeee0ef110db to your computer and use it in GitHub Desktop.
Hokusai (Three.js)
<html>
<head>
<style>
html, body { width: 100%; height: 100%; }
body { margin: 0; overflow: hidden; }
canvas { width: 100%; height: 100%; }
</style>
</head>
<body>
<script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js'></script>
<script src='https://threejs.org/examples/js/controls/TrackballControls.js'></script>
<script>
/**
* Globals
**/
var xMin = Number.POSITIVE_INFINITY,
xMax = Number.NEGATIVE_INFINITY,
yMin = Number.POSITIVE_INFINITY,
yMax = Number.NEGATIVE_INFINITY,
group = new THREE.Group();
/**
* Ajax helper
**/
function get(url, handleSuccess, handleErr, handleProgress) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if (xmlhttp.status === 200) {
if (handleSuccess) handleSuccess(xmlhttp.responseText)
} else {
if (handleErr) handleErr(xmlhttp)
}
};
};
xmlhttp.onprogress = function(e) {
if (handleProgress) handleProgress(e);
};
xmlhttp.open('GET', url, true);
xmlhttp.send();
};
/**
* Generate a scene object with a background color
**/
function getScene() {
return new THREE.Scene();
}
/**
* Generate the camera to be used in the scene. Camera args:
* [0] field of view: identifies the portion of the scene
* visible at any time (in degrees)
* [1] aspect ratio: identifies the aspect ratio of the
* scene in width/height
* [2] near clipping plane: objects closer than the near
* clipping plane are culled from the scene
* [3] far clipping plane: objects farther than the far
* clipping plane are culled from the scene
**/
function getCamera() {
var aspectRatio = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(75, aspectRatio, 0.1, 1000);
camera.position.set(0, 0, -170);
return camera;
}
/**
* Generate the light to be used in the scene. Light args:
* [0]: Hexadecimal color of the light
* [1]: Numeric value of the light's strength/intensity
* [2]: The distance from the light where the intensity is 0
* @param {obj} scene: the current scene object
**/
function getLight(scene) {
var light = new THREE.PointLight(0xffffff, 1, 0);
light.position.set(1, 1, 1);
scene.add(light);
var ambientLight = new THREE.AmbientLight(0x111111);
scene.add(ambientLight);
return light;
}
/**
* Generate the renderer to be used in the scene
**/
function getRenderer() {
// Create the canvas with a renderer
var renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, });
// Add support for retina displays
renderer.setPixelRatio(window.devicePixelRatio);
// Specify the size of the canvas
renderer.setSize(window.innerWidth, window.innerHeight);
// Add the canvas to the DOM
document.body.appendChild(renderer.domElement);
return renderer;
}
/**
* Generate the controls to be used in the scene
* @param {obj} camera: the three.js camera for the scene
* @param {obj} renderer: the three.js renderer for the scene
**/
function getControls(camera, renderer) {
var controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.zoomSpeed = 0.4;
controls.panSpeed = 0.4;
return controls;
}
/**
* Load svg data
**/
function loadData() {
var i, j, k, l, x, y,
triangles = [],
triangle = [];
get('output.svg', function(data) {
var background = data.split('fill="')[1].split('"')[0]
document.body.style.backgroundColor = background;
data.split('<polygon ').forEach(function(i, idx) {
triangle = [];
if (idx >= 1) {
j = i.split('points="')[1].split(' />')[0];
j.split(' ').forEach(function(k) {
l = k.split(',');
x = parseFloat(l[0]);
y = parseFloat(l[1]);
triangle.push({
x: x,
y: y,
fill: i.split('fill="')[1].split('"')[0],
})
if (x < xMin) xMin = x;
if (x > xMax) xMax = x;
if (y < yMin) yMin = y;
if (y > yMax) yMax = y;
})
triangles.push(triangle);
}
})
drawTriangles(triangles);
})
}
function drawTriangles(triangles) {
var z = 0, v1, v2, v3, geom, geometry, material, mesh,
xOffset = (xMax + xMin) / 2,
yOffset = (yMax + yMin) / 2;
triangles.map(function(t) {
z -= 0.05;
v1 = new THREE.Vector3( t[0].x - xOffset, t[0].y - yOffset, z );
v2 = new THREE.Vector3( t[1].x - xOffset, t[1].y - yOffset, z );
v3 = new THREE.Vector3( t[2].x - xOffset, t[2].y - yOffset, z );
geometry = new THREE.Geometry();
geometry.vertices.push(v1);
geometry.vertices.push(v2);
geometry.vertices.push(v3);
geometry.faces.push( new THREE.Face3(0, 1, 2) );
geometry.computeFaceNormals();
var material = new THREE.MeshBasicMaterial({
color: t[0].fill,
opacity: 0.5,
});
material.transparent = true;
var mesh = new THREE.Mesh(geometry, material);
group.add(mesh);
})
group.rotation.z = Math.PI;
scene.add(group);
}
/**
* Render!
**/
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
controls.update();
};
var scene = getScene();
var camera = getCamera();
var light = getLight(scene);
var renderer = getRenderer();
var controls = getControls(camera, renderer);
loadData();
render();
</script>
</body>
</html>
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment