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
 Subscribe Follow us on Twitter
 Follow us on Twitter
