I had a chance recently to tackle a project that required several rotating cubes that showed updated text. Initially, I was excited to work with some simple 3D in HTML5 using div elements, but that excitement was lost when I struggled to reconcile my years of 3D development with this type of web development. I’m used to a “world” with a “camera” type of situation, and so I set out to try and control the HTML elements in a similar fashion.
The requirements were that the “cubes” had to have their own camera view, so to speak. They couldn’t all use the same one since this would cause a perspective issue when you move them to the outer edges and areas of the view.
/**
* Created by NeoRiley on 5/2/16.
*/
function run(){
createBillboard({x:20, y:20, width: 350, height: 350});
createBillboard({x:400, y:20, width: 350, height: 350});
createBillboard({x:200, y:350, width: 350, height: 350});
}
function createBillboard(p_bounds){
var world = create3DWorld(p_bounds);
var billboard = document.createElement("div");
billboard.id = "billboard";
billboard.style.webkitTransformStyle = "preserve-3d";
billboard.style.width = p_bounds.width + "px";
billboard.style.height = p_bounds.height + "px";
billboard.style.position = "absolute";
billboard.style.top = "0px";
billboard.style.left = "0px";
billboard.style.overflow = "visible";
billboard.className = "rotating";
var str = "l0l";
var panel_front = $createPanel(str, p_bounds);
panel_front.style.color = "#FFFFFF";
panel_front.style.background = "rgba(0, 255, 0, 0.5";
var panel_back = $createPanel(str, p_bounds);
panel_back.style.color = "#FFFFFF";
panel_back.style.background = "rgba(0, 0, 255, 0.5";
var panel_left = $createPanel(str, p_bounds);
panel_left.style.color = "#FFFFFF";
panel_left.style.background = "rgba(255, 0, 0, 0.5";
var panel_right = $createPanel(str, p_bounds);
panel_right.style.color = "#FFFFFF";
panel_right.style.background = "rgba(255, 156, 0, 0.5";
world.appendChild(billboard);
billboard.appendChild(panel_front);
billboard.appendChild(panel_back);
billboard.appendChild(panel_left);
billboard.appendChild(panel_right);
panel_front.style.webkitTransform = "translateZ(10px)";
panel_back.style.webkitTransform = "rotateY(180deg) translateZ(10px)";
panel_left.style.webkitTransform = "rotateY(90deg) translateZ(10px)";
panel_right.style.webkitTransform = "rotateY(270deg) translateZ(10px)";
}
function create3DWorld(p_bounds){
var camera = document.createElement("div");
camera.id = "camera";
camera.style.webkitPerspective = "350px";
camera.style.webkitTransformStyle = "flat";
camera.style.width = p_bounds.width + "px";
camera.style.height = p_bounds.height + "px";
camera.style.position = "absolute";
camera.style.top = p_bounds.y + "px";
camera.style.left = p_bounds.x + "px";
camera.style.overflow = "hidden";
var world = document.createElement("div");
world.id = "world";
world.style.webkitTransformStyle = "preserve-3d";
world.style.width = p_bounds.width + "px";
world.style.height = p_bounds.height + "px";
world.style.position = "absolute";
world.style.top = "0px";
world.style.left = "0px";
world.style.overflow = "visible";
document.body.appendChild(camera);
camera.appendChild(world);
return world;
}
//////////////////////////////////////////////////////////////////////////////////
function $createPanel(p_id, p_bounds){
var panel = document.createElement("div");
panel.id = "panel_" + p_id;
panel.style.width = p_bounds.width + "px";
panel.style.height = p_bounds.height + "px";
panel.style.position = "absolute";
panel.style.top = "0px";
panel.style.left = "0px";
//panel.style.webkitBackfaceVisibility = "hidden";
panel.style.overflow = "hidden";
var text = document.createElement('span');
text.textContent = p_id;
text.style.fontSize = "200px";
var bounds = getBounds(p_id, {fontSize: "200px"});
text.style.position = "absolute";
text.style.top = ((p_bounds.width * 0.5) - (bounds.height * 0.5)) + "px";
text.style.left = ((p_bounds.width * 0.5) - (bounds.width * 0.5)) + "px";
panel.appendChild(text);
return panel;
}
//////////////////////////////////////////////////////////////////////////////////
function getBounds(p_text, p_options, p_debug) {
var element = document.createElement('div'),
bounds = {width: 0, height: 0};
element.appendChild(document.createTextNode(p_text));
p_options.fontFamily = p_options.fontFamily || "arial";
p_options.fontSize = p_options.fontSize || "12px";
p_options.fontWeight = p_options.fontWeight || "normal";
element.style.fontFamily = p_options.fontFamily;
element.style.fontWeight = p_options.fontWeight;
element.style.fontSize = p_options.fontSize;
element.style.position = 'absolute';
element.style.visibility = p_debug ? 'visible' : 'hidden';
element.style.left = p_debug ? "0px" : "-1000px";
element.style.top = p_debug ? "0px" : "-1000px";
element.style.width = 'auto';
element.style.height = 'auto';
if( p_debug ){
element.style.background = "#FFFF00";
element.style.color = "#000000";
}
document.body.appendChild(element);
bounds.width = element.offsetWidth;
bounds.height = element.offsetHeight;
if( !p_debug ) document.body.removeChild(element);
return bounds;
}
run();


Subscribe
Follow us on Twitter


