-
-
Save ThimoDEV/48e02f9f8fa0723b34ad902ec3be5200 to your computer and use it in GitHub Desktop.
Revisions
-
OrionReed revised this gist
Mar 31, 2024 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -120,6 +120,7 @@ transform: `translateZ(${THICKNESS}px)`, overflow: "visible", backfaceVisibility: "hidden", isolation: "auto", transformStyle: "preserve-3d", backgroundColor: COLOR_SURFACE ? color : getComputedStyle(childNode).backgroundColor, willChange: 'transform', -
OrionReed renamed this gist
Mar 30, 2024 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
OrionReed revised this gist
Mar 27, 2024 . 1 changed file with 4 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -32,14 +32,14 @@ traverseDOM(body, 0, 0, 0); document.addEventListener("mousemove", (event) => { const rotationY = (MAX_ROTATION * (1 - event.clientY / window.innerHeight) - (MAX_ROTATION / 2)); const rotationX = (MAX_ROTATION * event.clientX / window.innerWidth - (MAX_ROTATION / 2)); body.style.transform = `rotateX(${rotationY}deg) rotateY(${rotationX}deg)`; }); // Create side faces for an element to give it a 3D appearance function createSideFaces(element, color) { if (!SHOW_SIDES) { return } const width = element.offsetWidth; const height = element.offsetHeight; const fragment = document.createDocumentFragment(); @@ -115,7 +115,7 @@ for (let children = parentNode.childNodes, childrenCount = children.length, i = 0; i < childrenCount; i++) { const childNode = children[i]; if (!(1 === childNode.nodeType && !childNode.classList.contains('dom-3d-side-face'))) continue; const color = COLOR_RANDOM ? getRandomColor() : getColorByDepth(depthLevel, COLOR_HUE, -5); Object.assign(childNode.style, { transform: `translateZ(${THICKNESS}px)`, overflow: "visible", -
OrionReed revised this gist
Mar 27, 2024 . 1 changed file with 8 additions and 9 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -5,28 +5,27 @@ const COLOR_SURFACE = true; // color tops of DOM nodes? const COLOR_RANDOM = false; // randomise color? const COLOR_HUE = 190; // hue in HSL (https://hslpicker.com) const MAX_ROTATION = 180; // set to 360 to rotate all the way round const THICKNESS = 20; // thickness of layers const DISTANCE = 10000; // ¯\\_(ツ)_/¯ function getRandomColor() { const hue = Math.floor(Math.random() * 360); const saturation = 50 + Math.floor(Math.random() * 30); const lightness = 40 + Math.floor(Math.random() * 30); return `hsl(${hue}, ${saturation}%, ${lightness}%)`; } const getDOMDepth = element => [...element.children].reduce((max, child) => Math.max(max, getDOMDepth(child)), 0) + 1; const domDepthCache = getDOMDepth(document.body); const getColorByDepth = (depth, hue = 0, lighten = 0) => `hsl(${hue}, 75%, ${Math.min(10 + depth * (1 + 60 / domDepthCache), 90) + lighten}%)`; // Apply initial styles to the body to enable 3D perspective const body = document.body; body.style.overflow = "visible"; body.style.transformStyle = "preserve-3d"; body.style.perspective = DISTANCE; const perspectiveOriginX = (window.innerWidth / 2); const perspectiveOriginY = (window.innerHeight / 2); body.style.perspectiveOrigin = body.style.transformOrigin = `${perspectiveOriginX}px ${perspectiveOriginY}px`; @@ -116,7 +115,7 @@ for (let children = parentNode.childNodes, childrenCount = children.length, i = 0; i < childrenCount; i++) { const childNode = children[i]; if (!(1 === childNode.nodeType && !childNode.classList.contains('dom-3d-side-face'))) continue; const color = COLOR_RANDOM ? getRandomColor() : getColorByDepth(depthLevel, 190, -5); Object.assign(childNode.style, { transform: `translateZ(${THICKNESS}px)`, overflow: "visible", -
OrionReed revised this gist
Mar 27, 2024 . 1 changed file with 31 additions and 24 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,19 +1,26 @@ // 3D Dom viewer, copy-paste this into your console to visualise the DOM as a stack of solid blocks. // You can also minify and save it as a bookmarklet (https://www.freecodecamp.org/news/what-are-bookmarklets/) (() => { const SHOW_SIDES = false; // color sides of DOM nodes? const COLOR_SURFACE = true; // color tops of DOM nodes? const COLOR_RANDOM = false; // randomise color? const COLOR_HUE = 190; // hue in HSL (https://hslpicker.com) const COLOR_OPACITY = 1; const MAX_ROTATION = 180; // set to 360 to rotate all the way round const THICKNESS = 30; // thickness of layers const PERSPECTIVE = 1000; // ¯\\_(ツ)_/¯ function getRandomColor() { const hue = Math.floor(Math.random() * 360); const saturation = 50 + Math.floor(Math.random() * 30); const lightness = 40 + Math.floor(Math.random() * 30); return `hsl(${hue}, ${saturation}%, ${lightness}%)`; } const getDOMDepth = element => [...element.children].reduce((max, child) => Math.max(max, getDOMDepth(child)), 0) + 1; const domDepthCache = getDOMDepth(document.body); const getColorByDepth = (depth, hue = 0, lighten = 0, opacity = 1) => `hsla(${hue}, 75%, ${Math.min(10 + depth * (1 + 60 / domDepthCache), 90) + lighten}%,${opacity})`; // Apply initial styles to the body to enable 3D perspective const body = document.body; @@ -32,17 +39,16 @@ }); // Create side faces for an element to give it a 3D appearance function createSideFaces(element, color) { if (!SHOW_SIDES) return const width = element.offsetWidth; const height = element.offsetHeight; const fragment = document.createDocumentFragment(); // Helper function to create and style a face const createFace = ({ width, height, transform, transformOrigin, top, left, right, bottom }) => { const face = document.createElement('div'); face.className = 'dom-3d-side-face'; Object.assign(face.style, { transformStyle: "preserve-3d", backfaceVisibility: 'hidden', @@ -65,16 +71,16 @@ // Top face createFace({ width, height: THICKNESS, transform: `rotateX(-270deg) translateY(${-THICKNESS}px)`, transformOrigin: 'top', top: '0px', left: '0px', }); // Right face createFace({ width: THICKNESS, height, transform: 'rotateY(90deg)', transformOrigin: 'left', @@ -85,18 +91,18 @@ // Bottom face createFace({ width, height: THICKNESS, transform: `rotateX(-90deg) translateY(${THICKNESS}px)`, transformOrigin: 'bottom', bottom: '0px', left: '0px' }); // Left face createFace({ width: THICKNESS, height, transform: `translateX(${-THICKNESS}px) rotateY(-90deg)`, transformOrigin: 'right', top: '0px', left: '0px' @@ -109,13 +115,14 @@ function traverseDOM(parentNode, depthLevel, offsetX, offsetY) { for (let children = parentNode.childNodes, childrenCount = children.length, i = 0; i < childrenCount; i++) { const childNode = children[i]; if (!(1 === childNode.nodeType && !childNode.classList.contains('dom-3d-side-face'))) continue; const color = COLOR_RANDOM ? getRandomColor() : getColorByDepth(depthLevel, 190, -5, COLOR_OPACITY); Object.assign(childNode.style, { transform: `translateZ(${THICKNESS}px)`, overflow: "visible", backfaceVisibility: "hidden", transformStyle: "preserve-3d", backgroundColor: COLOR_SURFACE ? color : getComputedStyle(childNode).backgroundColor, willChange: 'transform', }); @@ -125,7 +132,7 @@ updatedOffsetX += parentNode.offsetLeft; updatedOffsetY += parentNode.offsetTop; } createSideFaces(childNode, color); traverseDOM(childNode, depthLevel + 1, updatedOffsetX, updatedOffsetY); } } -
OrionReed revised this gist
Mar 27, 2024 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -9,10 +9,10 @@ const SHOW_SIDES = true; // color sides of DOM elements? const COLOR_TOP_SURFACE = true; // color tops of towers? const COLOR_HUE = 190; // hue in HSL (https://hslpicker.com) const COLOR_OPACITY = 1; const MAX_ROTATION = 180; // set to 360 to rotate all the way round const DEPTH_INCREMENT = 30; // height/depth of layers const PERSPECTIVE = 1000; // ¯\\_(ツ)_/¯ const SIDE_FACE_CLASS = 'side-face'; // we use this to avoid traversing infinitely // Apply initial styles to the body to enable 3D perspective -
OrionReed revised this gist
Mar 27, 2024 . 1 changed file with 5 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -6,10 +6,10 @@ const getColorByDepth = (depth, hue = 0, lighten = 0, opacity = 1) => `hsla(${hue}, 75%, ${Math.min(10 + depth * (1 + 60 / domDepthCache), 90) + lighten}%,${opacity})`; // Config const SHOW_SIDES = true; // color sides of DOM elements? const COLOR_TOP_SURFACE = true; // color tops of towers? const COLOR_HUE = 190; // hue in HSL (https://hslpicker.com) const COLOR_OPACITY = 1; // ¯\\_(ツ)_/¯ const MAX_ROTATION = 180; // set to 360 to rotate all the way round const DEPTH_INCREMENT = 30; // height/depth of layers const PERSPECTIVE = 1000; @@ -25,7 +25,6 @@ body.style.perspectiveOrigin = body.style.transformOrigin = `${perspectiveOriginX}px ${perspectiveOriginY}px`; traverseDOM(body, 0, 0, 0); document.addEventListener("mousemove", (event) => { const rotationY = (MAX_ROTATION * (1 - event.screenY / screen.height) - (MAX_ROTATION / 2)); const rotationX = (MAX_ROTATION * event.screenX / screen.width - (MAX_ROTATION / 2)); @@ -34,6 +33,7 @@ // Create side faces for an element to give it a 3D appearance function createSideFaces(element, depthLevel) { if (!SHOW_SIDES) return const width = element.offsetWidth; const height = element.offsetHeight; const color = getColorByDepth(depthLevel, 190, -5, COLOR_OPACITY); @@ -115,7 +115,7 @@ overflow: "visible", backfaceVisibility: "hidden", transformStyle: "preserve-3d", backgroundColor: COLOR_TOP_SURFACE ? getColorByDepth(depthLevel, COLOR_HUE, 0, COLOR_OPACITY) : 'transparent', willChange: 'transform', }); -
OrionReed revised this gist
Mar 27, 2024 . 1 changed file with 6 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -12,7 +12,7 @@ const COLOR_OPACITY = 1; const MAX_ROTATION = 180; // set to 360 to rotate all the way round const DEPTH_INCREMENT = 30; // height/depth of layers const PERSPECTIVE = 1000; const SIDE_FACE_CLASS = 'side-face'; // we use this to avoid traversing infinitely // Apply initial styles to the body to enable 3D perspective @@ -45,6 +45,7 @@ face.className = SIDE_FACE_CLASS; Object.assign(face.style, { transformStyle: "preserve-3d", backfaceVisibility: 'hidden', position: 'absolute', width: `${width}px`, height: `${height}px`, @@ -65,10 +66,10 @@ createFace({ width, height: DEPTH_INCREMENT, transform: `rotateX(-270deg) translateY(${-DEPTH_INCREMENT}px)`, transformOrigin: 'top', top: '0px', left: '0px', }); // Right face @@ -85,7 +86,7 @@ createFace({ width, height: DEPTH_INCREMENT, transform: `rotateX(-90deg) translateY(${DEPTH_INCREMENT}px)`, transformOrigin: 'bottom', bottom: '0px', left: '0px' @@ -112,6 +113,7 @@ Object.assign(childNode.style, { transform: `translateZ(${DEPTH_INCREMENT}px)`, overflow: "visible", backfaceVisibility: "hidden", transformStyle: "preserve-3d", backgroundColor: COLOR_SURFACES ? getColorByDepth(depthLevel, COLOR_HUE, 0, COLOR_OPACITY) : 'transparent', willChange: 'transform', -
OrionReed revised this gist
Mar 27, 2024 . 1 changed file with 5 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -6,24 +6,23 @@ const getColorByDepth = (depth, hue = 0, lighten = 0, opacity = 1) => `hsla(${hue}, 75%, ${Math.min(10 + depth * (1 + 60 / domDepthCache), 90) + lighten}%,${opacity})`; // Config const COLOR_SURFACES = true; // color tops of towers? const COLOR_SIDES = true; // color sides of DOM elements? const COLOR_HUE = 190; // hue in HSL (https://hslpicker.com) const COLOR_OPACITY = 1; const MAX_ROTATION = 180; // set to 360 to rotate all the way round const DEPTH_INCREMENT = 30; // height/depth of layers const PERSPECTIVE = 1000; const SIDE_FACE_CLASS = 'side-face'; // we use this to avoid traversing infinitely // Apply initial styles to the body to enable 3D perspective const body = document.body; body.style.overflow = "visible"; body.style.transformStyle = "preserve-3d"; body.style.perspective = PERSPECTIVE; const perspectiveOriginX = (window.innerWidth / 2); const perspectiveOriginY = (window.innerHeight / 2); body.style.perspectiveOrigin = body.style.transformOrigin = `${perspectiveOriginX}px ${perspectiveOriginY}px`; traverseDOM(body, 0, 0, 0); // Event listener to rotate the DOM based on mouse movement -
OrionReed revised this gist
Mar 27, 2024 . 1 changed file with 103 additions and 83 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,54 +1,47 @@ // 3D Dom viewer, copy-paste this into your console to visualise the DOM as a stack of solid blocks. // You can also minify and save it as a bookmarklet (https://www.freecodecamp.org/news/what-are-bookmarklets/) (() => { const getDOMDepth = element => [...element.children].reduce((max, child) => Math.max(max, getDOMDepth(child)), 0) + 1; const domDepthCache = getDOMDepth(document.body); const getColorByDepth = (depth, hue = 0, lighten = 0, opacity = 1) => `hsla(${hue}, 75%, ${Math.min(10 + depth * (1 + 60 / domDepthCache), 90) + lighten}%,${opacity})`; // Config const MAX_ROTATION = 180; // set to 360 to rotate all the way round const DEPTH_INCREMENT = 30; // height/depth of layers const PERSPECTIVE = 1000; // ¯\_(ツ)_/¯ const SIDE_FACE_CLASS = 'side-face'; // we use this to avoid traversing infinitely const COLOR_SURFACES = true; // color tops of towers? const COLOR_SIDES = true; // color sides of DOM elements? const COLOR_HUE = 190; // hue in HSL (https://hslpicker.com) const COLOR_OPACITY = 1; // Setup body for 3D perspective const body = document.body; body.style.overflow = "visible"; body.style.transformStyle = "preserve-3d"; body.style.perspective = PERSPECTIVE; const perspectiveOriginX = (window.innerWidth / 2); const perspectiveOriginY = (window.innerHeight / 2); body.style.perspectiveOrigin = body.style.transformOrigin = `${perspectiveOriginX}px ${perspectiveOriginY}px`; traverseDOM(body, 0, 0, 0); // Event listener to rotate the DOM based on mouse movement document.addEventListener("mousemove", (event) => { const rotationY = (MAX_ROTATION * (1 - event.screenY / screen.height) - (MAX_ROTATION / 2)); const rotationX = (MAX_ROTATION * event.screenX / screen.width - (MAX_ROTATION / 2)); body.style.transform = `rotateX(${rotationY}deg) rotateY(${rotationX}deg)`; }); // Create side faces for an element to give it a 3D appearance function createSideFaces(element, depthLevel) { const width = element.offsetWidth; const height = element.offsetHeight; const color = getColorByDepth(depthLevel, 190, -5, COLOR_OPACITY); const fragment = document.createDocumentFragment(); // Helper function to create and style a face const createFace = ({ width, height, transform, transformOrigin, top, left, right, bottom }) => { const face = document.createElement('div'); face.className = SIDE_FACE_CLASS; Object.assign(face.style, { @@ -57,55 +50,82 @@ width: `${width}px`, height: `${height}px`, background: color, transform, transformOrigin, overflow: 'hidden', willChange: 'transform', top, left, right, bottom }); fragment.appendChild(face); } // Top face createFace({ width, height: DEPTH_INCREMENT, transform: 'rotateX(-90deg)', transformOrigin: 'top', top: '0px', left: '0px' }); // Right face createFace({ width: DEPTH_INCREMENT, height, transform: 'rotateY(90deg)', transformOrigin: 'left', top: '0px', left: `${width}px` }); // Bottom face createFace({ width, height: DEPTH_INCREMENT, transform: 'rotateX(90deg)', transformOrigin: 'bottom', bottom: '0px', left: '0px' }); // Left face createFace({ width: DEPTH_INCREMENT, height, transform: `translateX(${-DEPTH_INCREMENT}px) rotateY(-90deg)`, transformOrigin: 'right', top: '0px', left: '0px' }); element.appendChild(fragment); } // Recursive function to traverse child nodes, apply 3D styles, and create side faces function traverseDOM(parentNode, depthLevel, offsetX, offsetY) { for (let children = parentNode.childNodes, childrenCount = children.length, i = 0; i < childrenCount; i++) { const childNode = children[i]; if (!(1 === childNode.nodeType && !childNode.classList.contains(SIDE_FACE_CLASS))) continue; Object.assign(childNode.style, { transform: `translateZ(${DEPTH_INCREMENT}px)`, overflow: "visible", transformStyle: "preserve-3d", backgroundColor: COLOR_SURFACES ? getColorByDepth(depthLevel, COLOR_HUE, 0, COLOR_OPACITY) : 'transparent', willChange: 'transform', }); let updatedOffsetX = offsetX; let updatedOffsetY = offsetY; if (childNode.offsetParent === parentNode) { updatedOffsetX += parentNode.offsetLeft; updatedOffsetY += parentNode.offsetTop; } createSideFaces(childNode, depthLevel); traverseDOM(childNode, depthLevel + 1, updatedOffsetX, updatedOffsetY); } } })() -
OrionReed revised this gist
Mar 27, 2024 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,5 @@ // Copy-paste into your console (or minify and save as a bookmarklet) to see any DOM in an almost-sorta-working 3D stack of DOM elements. // The front faces are colored for debugging, if this gist can be fixed, they can return to their normal styling. (function () { const MAX_ROTATION = 180; const DEPTH_INCREMENT = 25; -
OrionReed created this gist
Mar 27, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,109 @@ (function () { const MAX_ROTATION = 180; const DEPTH_INCREMENT = 25; const PERSPECTIVE = 1000; const SIDE_FACE_CLASS = 'side-face'; const MAX_DOM_DEPTH = getMaxDepth(document.body); // Calculate color based on depth, ensuring lighter colors for deeper elements function getColorByDepth(depth) { return `hsl(190, 75%, ${Math.min(10 + depth * (1 + 60 / MAX_DOM_DEPTH), 90)}%)`; } // Calculate the maximum depth of the DOM tree function getMaxDepth(element) { return Array.from(element.children).reduce((max, child) => Math.max(max, getMaxDepth(child)), 0) + 1; } // Freate side faces for an element to give it a 3D appearance function createSideFaces(element, depthLevel) { const width = element.offsetWidth; const height = element.offsetHeight; const color = getColorByDepth(depthLevel); const faces = [ { transform: `translateX(${width}px) rotateY(90deg)`, width: DEPTH_INCREMENT, height: height }, { transform: `translateX(-${DEPTH_INCREMENT}px) rotateY(-90deg)`, width: DEPTH_INCREMENT, height: height }, { transform: `translateY(-${DEPTH_INCREMENT}px) rotateX(90deg)`, width: width, height: DEPTH_INCREMENT }, { transform: `translateY(${height}px) rotateX(-90deg)`, width: width, height: DEPTH_INCREMENT } ]; // Create a face for each side of the element faces.forEach(({ transform, width, height }) => { const face = document.createElement('div'); face.className = SIDE_FACE_CLASS; Object.assign(face.style, { transformStyle: "preserve-3d", position: 'absolute', width: `${width}px`, height: `${height}px`, background: color, transform: transform, overflow: 'hidden', backfaceVisibility: 'hidden', willChange: 'transform', zIndex: `${depthLevel}` }) element.appendChild(face); }); } // Recursive function to traverse child nodes, apply 3D styles, and create side faces function traverseChildren(parentNode, depthLevel, offsetX, offsetY) { for (let children = parentNode.childNodes, childrenCount = children.length, i = 0; i < childrenCount; i++) { const childNode = children[i]; if (1 === childNode.nodeType && !childNode.classList.contains(SIDE_FACE_CLASS)) { Object.assign(childNode.style, { transform: `translateZ(${DEPTH_INCREMENT}px)`, position: 'relative', backfaceVisibility: 'hidden', overflow: "visible", transformStyle: "preserve-3d", zIndex: `${depthLevel}`, backgroundColor: `#${Math.floor(Math.random() * 16777215).toString(16)}`, // Random color face while debugging willChange: 'transform', }); childNode.offsetParent === parentNode && (offsetX += parentNode.offsetLeft, offsetY += parentNode.offsetTop); createSideFaces(childNode, depthLevel); traverseChildren(childNode, depthLevel + 1, offsetX, offsetY); } } } // Apply initial styles to the body to enable 3D perspective const body = document.body; body.style.overflow = "visible"; body.style.transformStyle = "preserve-3d"; body.style.backfaceVisibility = 'hidden'; body.style.perspective = PERSPECTIVE; const perspectiveOriginX = (window.innerWidth / 2); const perspectiveOriginY = (window.innerHeight / 2); body.style.perspectiveOrigin = body.style.transformOrigin = `${perspectiveOriginX}px ${perspectiveOriginY}px`; traverseChildren(body, 0, 0, 0); // Event listener to rotate the DOM based on mouse movement document.addEventListener("mousemove", (event) => { const rotationY = (MAX_ROTATION * (1 - event.screenY / screen.height) - (MAX_ROTATION / 2)); const rotationX = (MAX_ROTATION * event.screenX / screen.width - (MAX_ROTATION / 2)); body.style.transform = `rotateX(${rotationY}deg) rotateY(${rotationX}deg)`; }); })()