Skip to content

Instantly share code, notes, and snippets.

@hartator
Last active February 2, 2024 04:36
Show Gist options
  • Save hartator/05a6b9db067a002577af244c8ac1a3a7 to your computer and use it in GitHub Desktop.
Save hartator/05a6b9db067a002577af244c8ac1a3a7 to your computer and use it in GitHub Desktop.
dom-to-3d-view.js
function domTo3DView(b, p) {
function l(k, c, b, e, g, d, f) {
return "<div style='position:absolute;-webkit-transform-origin: 0 0 0;" + ("background:" + f + ";") + ("width:" + e + "px; height:" + g + "px;") + ("-webkit-transform:" + ("translate3d(" + k + "px," + c + "px," + b + "px)") + ("rotateX(270deg) rotateY(" + d + "deg)") + ";") + "'></div>"
}
function o(k, c, d, f) {
for (var j = k.childNodes, n = j.length, m = 0; m < n; m++) {
var a = j[m];
if (1 === a.nodeType) {
a.style.overflow = "visible";
a.style.WebkitTransformStyle = "preserve-3d";
a.style.WebkitTransform = "translateZ(" + (b + (n - m) * q).toFixed(3) + "px)";
var h = d,
i = f;
a.offsetParent === k && (h += k.offsetLeft, i += k.offsetTop);
o(a, c + 1, h, i);
e += l(h + a.offsetLeft, i + a.offsetTop, (c + 1) * b, a.offsetWidth, b, 0, g[c % (g.length - 1)]);
e += l(h + a.offsetLeft + a.offsetWidth, i + a.offsetTop, (c + 1) * b, a.offsetHeight, b, 270, g[c % (g.length - 1)]);
e += l(h + a.offsetLeft, i + a.offsetTop + a.offsetHeight, (c + 1) * b, a.offsetWidth, b, 0, g[c % (g.length - 1)]);
e += l(h + a.offsetLeft, i + a.offsetTop, (c + 1) * b, a.offsetHeight, b, 270, g[c % (g.length - 1)])
}
}
}
var g = "#C33,#ea4c88,#663399,#0066cc,#669900,#ffcc33,#ff9900,#996633".split(","),
q = 0.001,
e = "",
d = document.body;
d.style.overflow = "visible";
d.style.WebkitTransformStyle = "preserve-3d";
d.style.WebkitPerspective = p;
var r = (window.innerWidth / 2).toFixed(2),
s = (window.innerHeight / 2).toFixed(2);
d.style.WebkitPerspectiveOrigin = d.style.WebkitTransformOrigin = r + "px " + s + "px";
o(d, 0, 0, 0);
var f = document.createElement("DIV");
f.style.display = "none";
f.style.position = "absolute";
f.style.top = 0;
f.innerHTML = e;
d.appendChild(f);
var j = "NO_FACES";
document.addEventListener("mousemove", function(b) {
if ("DISABLED" !== j) {
var c = b.screenX / screen.width,
b = (360 * (1 - b.screenY / screen.height) - 180).toFixed(2),
c = (360 * c - 180).toFixed(2);
d.style.WebkitTransform = "rotateX(" + b + "deg) rotateY(" + c + "deg)"
}
}, !0);
document.addEventListener("mouseup", function() {
switch (j) {
case "NO_FACES":
j = "FACES";
f.style.display = "";
break;
case "FACES":
j = "NO_FACES", f.style.display = "none"
}
}, !0)
}(25, 5E3); domTo3DView(25, 5E3);
@mingodad
Copy link

mingodad commented Aug 6, 2022

Here is it again with variable names changed, only rotate with the mousemove+SHIFT and a bit of background color added:

function domTo3DView(dtz, perspective) {
    function mk_div(tx, ty, tz, width, height, yAngle, background) {
        return "<div style='position:absolute;-webkit-transform-origin: 0 0 0;" + ("background-color:" + background + ";") + ("width:" + width + "px; height:" + height + "px;") + ("-webkit-transform:" + ("translate3d(" + tx + "px," + ty + "px," + tz + "px)") + ("rotateX(270deg) rotateY(" + yAngle + "deg)") + ";") + "'></div>"
    }

    function dive_in(node, depth, tx, ty) {
        var currentColor = colors[depth % (colors.length - 1)];
        var currentColor2 = colors2[depth % (colors2.length - 1)];
        for (var childNodes = node.childNodes, childCount = childNodes.length, childIdx = 0; childIdx < childCount; childIdx++) {
            var child = childNodes[childIdx];
            if (1 === child.nodeType) {
                child.style.overflow = "visible";
                child.style.WebkitTransformStyle = "preserve-3d";
                child.style.WebkitTransform = "translateZ(" + (dtz + (childCount - childIdx) * step).toFixed(3) + "px)";
                child.offsetParent === node && (tx += node.offsetLeft, ty += node.offsetTop);
                child.style.backgroundColor = currentColor2;
                dive_in(child, depth + 1, tx, ty);
                html += mk_div(tx + child.offsetLeft, ty + child.offsetTop, (depth + 1) * dtz, child.offsetWidth, dtz, 0, currentColor);
                html += mk_div(tx + child.offsetLeft + child.offsetWidth, ty + child.offsetTop, (depth + 1) * dtz, child.offsetHeight, dtz, 270, currentColor);
                html += mk_div(tx + child.offsetLeft, ty + child.offsetTop + child.offsetHeight, (depth + 1) * dtz, child.offsetWidth, dtz, 0, currentColor);
                html += mk_div(tx + child.offsetLeft, ty + child.offsetTop, (depth + 1) * dtz, child.offsetHeight, dtz, 270, currentColor)
            }
        }
    }
    var colors = "#0C0303,#ea4c88,#663399,#0066cc,#669900,#ffcc33,#ff9900,#996633".split(","),
        colors2 = "rgba(12,3,3,0.05);rgba(234,76,136,0.05);rgba(102,51,153,0.05);rgba(0,102,204,0.05);rgba(102,153,0,0.05);rgba(255,153,52,0.05);rgba(255,153,0,0.05);rgba(153,102,51,0.05)".split(";"),
        step = 0.001,
        html = "",
        body = document.body;
    body.style.overflow = "visible";
    body.style.WebkitTransformStyle = "preserve-3d";
    body.style.WebkitPerspective = perspective;
    var xOfsset = (window.innerWidth / 2).toFixed(2),
        yOffset = (window.innerHeight / 2).toFixed(2);
    body.style.WebkitPerspectiveOrigin = body.style.WebkitTransformOrigin = xOfsset + "px " + yOffset + "px";
    dive_in(body, 0, 0, 0);
    var div = document.createElement("DIV");
    div.style.display = "none";
    div.style.position = "absolute";
    div.style.top = 0;
    div.innerHTML = html;
    body.appendChild(div);
    var display_type = "NO_FACES";
    document.addEventListener("mousemove", function(event) {
        if (event.shiftKey && "DISABLED" !== display_type) {
            var yAngle = event.screenX / screen.width,
                xAngle = (360 * (1 - event.screenY / screen.height) - 180).toFixed(2),
                yAngle = (360 * yAngle - 180).toFixed(2);
            body.style.WebkitTransform = "rotateX(" + xAngle + "deg) rotateY(" + yAngle + "deg)"
        }
    }, !0);
    document.addEventListener("mouseup", function() {
        switch (display_type) {
            case "NO_FACES":
                display_type = "FACES";
                div.style.display = "";
                break;
            case "FACES":
                display_type = "NO_FACES", div.style.display = "none"
        }
    }, !0)
}(25, 5E3); domTo3DView(25, 5E3);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment