mirror of
https://github.com/RGBCube/rgbcube.github.io
synced 2025-07-24 15:37:41 +00:00
272 lines
No EOL
5.7 KiB
HTML
272 lines
No EOL
5.7 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;
|
|
}
|
|
|
|
.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 {
|
|
/* REMOVE */
|
|
opacity: 60%;
|
|
/* REMOVE */
|
|
background-color: red;
|
|
|
|
width: 5em;
|
|
height: 5em;
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
justify-content: center;
|
|
|
|
position: absolute;
|
|
}
|
|
|
|
.front {
|
|
transform: rotateY(0deg) translateZ(2.5em);
|
|
}
|
|
|
|
.top {
|
|
transform: rotateX(90deg) translateZ(2.5em);
|
|
}
|
|
|
|
.back {
|
|
transform: rotateY(180deg) translateZ(2.5em);
|
|
}
|
|
|
|
.bottom {
|
|
transform: rotateX(-90deg) translateZ(2.5em);
|
|
}
|
|
|
|
.right {
|
|
transform: rotateY(90deg) translateZ(2.5em);
|
|
}
|
|
|
|
.left {
|
|
transform: rotateY(-90deg) translateZ(2.5em);
|
|
}
|
|
</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> |