mirror of
				https://github.com/RGBCube/rgbcube.github.io
				synced 2025-10-31 06:52:45 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			278 lines
		
	
	
		
			No EOL
		
	
	
		
			5.9 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			278 lines
		
	
	
		
			No EOL
		
	
	
		
			5.9 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE html>
 | |
| <html>
 | |
| 
 | |
| <head>
 | |
|   <meta charset="UTF-8" />
 | |
|   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 | |
|   <meta property="og:type" content="website">
 | |
| 
 | |
|   <title>RGBCube</title>
 | |
|   <meta name="author" content="RGBCube" />
 | |
| 
 | |
|   <meta property="og:site_name" content="RGBCube" />
 | |
|   <meta property="og:title" content="RGBCube" />
 | |
| 
 | |
|   <meta name="description" content="The official website and link portal of RGBCube and his work." />
 | |
|   <meta property="og:description" content="The official website and link portal of RGBCube and his work." />
 | |
| 
 | |
|   <meta property="og:image" content="/thumbnail.png" />
 | |
|   <meta property="og:image:type" content="image/png" />
 | |
|   <meta property="og:image:height" content="" />
 | |
|   <meta property="og:image:width" content="" />
 | |
| 
 | |
|   <meta property="og:url" content="https://rgbcube.github.io/" />
 | |
|   <link rel="canonical" href="https://rgbcube.github.io/">
 | |
| </head>
 | |
| 
 | |
| <body>
 | |
|   <style>
 | |
|     /* STYLING */
 | |
| 
 | |
|     @font-face {
 | |
|       font-family: "Bai Jamjuree";
 | |
|       font-weight: 700;
 | |
|       src: url(BaiJamjuree700.woff2) format(woff2);
 | |
|     }
 | |
| 
 | |
|     html {
 | |
|       background-color: #000000;
 | |
|       font-family: "Bai Jamjuree", sans;
 | |
|       font-size: 300%;
 | |
|     }
 | |
| 
 | |
|     a {
 | |
|       color: #000000;
 | |
|       text-decoration-line: none;
 | |
|     }
 | |
| 
 | |
|     .frame {
 | |
|       background-color: #FFFFFF;
 | |
| 
 | |
|       width: min-content;
 | |
| 
 | |
|       padding: 0 .3em;
 | |
|       border-radius: 1em;
 | |
| 
 | |
|       user-select: none;
 | |
|     }
 | |
| 
 | |
|     .frame:hover {
 | |
|       background-color: #FFFF00;
 | |
|     }
 | |
| 
 | |
|     /* POSITIONING */
 | |
| 
 | |
|     body,
 | |
|     html {
 | |
|       height: 100%;
 | |
|       margin: 0;
 | |
|     }
 | |
| 
 | |
|     .scene {
 | |
|       height: 100%;
 | |
|       width: 100%;
 | |
|       perspective: 15em;
 | |
| 
 | |
|       display: flex;
 | |
| 
 | |
|       align-items: center;
 | |
|       justify-content: center;
 | |
|     }
 | |
| 
 | |
|     .cube {
 | |
|       height: 5em;
 | |
|       width: 5em;
 | |
| 
 | |
|       position: relative;
 | |
| 
 | |
|       transform: translateZ(-2.5em);
 | |
|       transform-style: preserve-3d;
 | |
|     }
 | |
| 
 | |
|     .face {
 | |
|       background-size: cover;
 | |
|       background-position: center;
 | |
| 
 | |
|       width: 5em;
 | |
|       height: 5em;
 | |
| 
 | |
|       display: flex;
 | |
| 
 | |
|       align-items: center;
 | |
|       justify-content: center;
 | |
| 
 | |
|       position: absolute;
 | |
|     }
 | |
| 
 | |
|     .front {
 | |
|       transform: rotateY(0deg) translateZ(2.5em);
 | |
|       background-image: url(front.png);
 | |
|     }
 | |
| 
 | |
|     .top {
 | |
|       transform: rotateX(90deg) translateZ(2.5em);
 | |
|       background-image: url(top.png);
 | |
|     }
 | |
| 
 | |
|     .back {
 | |
|       transform: rotateY(180deg) translateZ(2.5em);
 | |
|       background-image: url(back.png);
 | |
|     }
 | |
| 
 | |
|     .bottom {
 | |
|       transform: rotateX(-90deg) translateZ(2.5em);
 | |
|       background-image: url(bottom.png);
 | |
|     }
 | |
| 
 | |
|     .right {
 | |
|       transform: rotateY(90deg) translateZ(2.5em);
 | |
|       background-image: url(right.png);
 | |
|     }
 | |
| 
 | |
|     .left {
 | |
|       transform: rotateY(-90deg) translateZ(2.5em);
 | |
|       background-image: url(left.png);
 | |
|     }
 | |
|   </style>
 | |
| 
 | |
|   <div class="scene">
 | |
|     <div class="cube">
 | |
|       <div class="face front">
 | |
|         <a href="/contact">
 | |
|           <div class="frame">
 | |
|             <p>contact</p>
 | |
|           </div>
 | |
|         </a>
 | |
|       </div>
 | |
| 
 | |
|       <div class="face top">
 | |
|         <a href="https://github.com/RGBCube">
 | |
|           <div class="frame">
 | |
|             <p>github</p>
 | |
|           </div>
 | |
|         </a>
 | |
|       </div>
 | |
| 
 | |
|       <div class="face back">
 | |
|         <a href="/">
 | |
|           <div class="frame">
 | |
|             <p></p>
 | |
|           </div>
 | |
|         </a>
 | |
|       </div>
 | |
| 
 | |
|       <div class="face bottom">
 | |
|         <a href="/">
 | |
|           <div class="frame">
 | |
|             <p></p>
 | |
|           </div>
 | |
|         </a>
 | |
|       </div>
 | |
| 
 | |
|       <div class="face right">
 | |
|         <a href="/">
 | |
|           <div class="frame">
 | |
|             <p></p>
 | |
|           </div>
 | |
|         </a>
 | |
|       </div>
 | |
| 
 | |
|       <div class="face left">
 | |
|         <a href="/">
 | |
|           <div class="frame">
 | |
|             <p></p>
 | |
|           </div>
 | |
|         </a>
 | |
|       </div>
 | |
|     </div>
 | |
|   </div>
 | |
| 
 | |
|   <script>
 | |
|     class Quaternion {
 | |
|       constructor(x, y, z, w) {
 | |
|         this.x = x;
 | |
|         this.y = y;
 | |
|         this.z = z;
 | |
|         this.w = w;
 | |
|       }
 | |
| 
 | |
|       static multiply(q1, q2) {
 | |
|         return new Quaternion(
 | |
|           q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y,
 | |
|           q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x,
 | |
|           q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w,
 | |
|           q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z,
 | |
|         )
 | |
|       }
 | |
| 
 | |
|       static fromAxisAngle(axis, angle) {
 | |
|         const halfAngle = angle / 2;
 | |
|         const sinHalfAngle = Math.sin(halfAngle);
 | |
|         const cosHalfAngle = Math.cos(halfAngle);
 | |
|         return new Quaternion(
 | |
|           axis.x * sinHalfAngle,
 | |
|           axis.y * sinHalfAngle,
 | |
|           axis.z * sinHalfAngle,
 | |
|           cosHalfAngle
 | |
|         );
 | |
|       }
 | |
| 
 | |
|       normalize() {
 | |
|         const length = Math.sqrt(
 | |
|           this.x ** 2 + this.y ** 2 + this.z ** 2 + this.w ** 2
 | |
|         );
 | |
| 
 | |
|         this.x /= length;
 | |
|         this.y /= length;
 | |
|         this.z /= length;
 | |
|         this.w /= length;
 | |
| 
 | |
|         return this;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     const cube = document.querySelector(".cube");
 | |
| 
 | |
|     let isMouseDown = false;
 | |
| 
 | |
|     let lastX = 0;
 | |
|     let lastY = 0;
 | |
| 
 | |
|     let rotationVelocity = new Quaternion(0, 0, 0, 1);
 | |
| 
 | |
|     document.addEventListener("mousemove", (e) => {
 | |
|       if (isMouseDown) {
 | |
|         const deltaX = e.clientX - lastX;
 | |
|         const deltaY = e.clientY - lastY;
 | |
| 
 | |
|         const axis = new Quaternion(deltaY, deltaX, 0, 0).normalize();
 | |
|         const angle = Math.sqrt(deltaX * deltaX + deltaY * deltaY) * 0.01;
 | |
| 
 | |
|         const deltaRotation = Quaternion.fromAxisAngle(axis, angle);
 | |
|         rotationVelocity = Quaternion.multiply(deltaRotation, rotationVelocity);
 | |
| 
 | |
|         cube.style.transform = `rotate3d(${rotationVelocity.x}, ${rotationVelocity.y}, ${rotationVelocity.z}, ${rotationVelocity.w}rad)`;
 | |
| 
 | |
|         lastX = e.clientX;
 | |
|         lastY = e.clientY;
 | |
|       }
 | |
|     });
 | |
| 
 | |
|     document.addEventListener("mousedown", (e) => {
 | |
|       isMouseDown = true;
 | |
| 
 | |
|       lastX = e.clientX;
 | |
|       lastY = e.clientY;
 | |
|     });
 | |
| 
 | |
|     document.addEventListener("mouseup", () => {
 | |
|       isMouseDown = false;
 | |
|     });
 | |
| 
 | |
|     document.addEventListener("mouseleave", () => {
 | |
|       isMouseDown = false;
 | |
|     });
 | |
|   </script>
 | |
| </body>
 | |
| 
 | |
| </html> | 
