Skip to content

Commit

Permalink
feat: model interaction
Browse files Browse the repository at this point in the history
  • Loading branch information
Cdm2883 committed Jan 22, 2025
1 parent db1f76a commit ee6db61
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 44 deletions.
67 changes: 24 additions & 43 deletions website/src/assets/javascripts/main.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";

const image = document.querySelector<HTMLElement>('#index-page .logo img');
const canvas = document.querySelector<HTMLElement>('#index-page .logo canvas');
const logoBox = document.querySelector<HTMLElement>('#index-page .logo-box');
const titleBox = document.querySelector<HTMLElement>('#index-page .title');

const animationStart = Date.now();
let animationDone = false;
logoBox.addEventListener('animationend', _ =>
setTimeout(() => animationDone = true, (Date.now() - animationStart) * 1.3));

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(60, 1, 0.1, 80);
const camera = new THREE.PerspectiveCamera(60, 1, 0.01, 100);
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, canvas });
const deg = THREE.MathUtils.degToRad(1)

Expand All @@ -22,10 +22,14 @@ renderer.setClearAlpha(0);
const ambientLight = new THREE.AmbientLight(0xFFFFFF, 10);
scene.add(ambientLight);

const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;

const loader = new GLTFLoader();
let logo: THREE.Object3D<THREE.Object3DEventMap>;
loader.load("./assets/models/logo.glb", data => {
logo = data.scene;
logo.remove(logo.getObjectByName('node_3'));
logo.rotation.y = -90 * deg;
scene.add(logo);

Expand All @@ -36,10 +40,27 @@ loader.load("./assets/models/logo.glb", data => {
let currentRotationY = 0;
function animate() {
if (logo) logo.rotation.y = (-90 + currentRotationY) * deg;
controls.update();
renderer.render(scene, camera);
requestAnimationFrame(animate);
}

let canvasActiveTimer = null;
const canvasActive = () => {
canvas.classList.add('active-animation');
canvas.classList.add('active');
if (canvasActiveTimer) clearTimeout(canvasActiveTimer);
canvasActiveTimer = setTimeout(() => canvas.classList.remove("active"), 3000);
};
canvas.addEventListener('touchstart', canvasActive);
canvas.addEventListener('touchmove', canvasActive);
let mouseDown = false;
// @ts-ignore
canvas.addEventListener('mousedown', () => mouseDown = canvasActive() || true);
canvas.addEventListener('mouseup', () => mouseDown = false);
canvas.addEventListener('mousemove', () => mouseDown && canvasActive());
canvas.addEventListener('wheel', canvasActive);

function postShowCanvas() {
if (animationDone) showCanvas();
else setTimeout(postShowCanvas, 100);
Expand All @@ -48,46 +69,6 @@ function showCanvas() {
image.classList.toggle("hide");
canvas.classList.toggle("hide");
const { clientWidth, clientHeight } = renderer.domElement;
const [ width, height ] = [clientWidth * devicePixelRatio, clientHeight * devicePixelRatio];
const [ width, height ] = [ clientWidth * devicePixelRatio, clientHeight * devicePixelRatio ];
renderer.setSize(width, height, false);
}



const bezier = cubicBezier(1, -0.54, 0, 1.54);
const autoRotation = setInterval(() => {
if (!animationDone) return;
const endN = 300;
let n = 0;
const timer = setInterval(() =>
// @ts-ignore
currentRotationY = ++n >= endN ? clearInterval(timer) || 0 : 360 * bezier(n / endN), 1);
}, 5000);

function cubicBezier(x1: number, y1: number, x2: number, y2: number): (t: number) => number {
const bezier = (t: number, p0: number, p1: number, p2: number, p3: number) => {
const u = 1 - t;
return u * u * u * p0 + 3 * u * u * t * p1 + 3 * u * t * t * p2 + t * t * t * p3;
}
const solveX = (t: number) => bezier(t, 0, x1, x2, 1);
const solveY = (t: number) => bezier(t, 0, y1, y2, 1);
return function(t: number) {
let left = 0;
let right = 1;
const epsilon = 0.0001;
let x = solveX(t);

while (right - left > epsilon) {
let mid = (left + right) / 2;
let xMid = solveX(mid);
if (xMid < x) {
left = mid;
} else {
right = mid;
}
}

let resultT = (left + right) / 2;
return solveY(resultT);
};
}
11 changes: 10 additions & 1 deletion website/src/assets/stylesheets/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
}

$text-color: #ececec;
$accent-red: #cc0000;
html {
color: $text-color;
background-color: #1e1f22;
Expand Down Expand Up @@ -128,6 +129,14 @@ $logo-box-end: min(80vmin, 500px);
.hide {
opacity: 0;
}
canvas.active-animation {
background-color: transparent;
transition: background-color ease .2s;
}
canvas.active {
//background-color: $accent-red;
background-color: black;
}
}

.decoration {
Expand Down Expand Up @@ -254,7 +263,7 @@ $logo-box-end: min(80vmin, 500px);
$size: relative-size(30);
width: $size;
height: $size;
background: #cc0000;
background: $accent-red;
}
}
.sub {
Expand Down

0 comments on commit ee6db61

Please sign in to comment.