diff --git a/app/page.tsx b/app/page.tsx
index 72d67c4..dd42757 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -18,23 +18,24 @@ export default function Page() {
-
-
+
- Hello World!
-
-
-
-
+ Hello World
+
+
+ TECH OTAKUS SAVE THE WORLD
+
);
diff --git a/components/models/home/computer-desk.tsx b/components/models/home/computer-desk.tsx
index f0b6430..d73d9f3 100644
--- a/components/models/home/computer-desk.tsx
+++ b/components/models/home/computer-desk.tsx
@@ -1,60 +1,24 @@
'use client';
import { Canvas } from '@react-three/fiber';
-import { lazy, Suspense } from 'react';
+import { lazy, Suspense, useMemo } from 'react';
import Loading from './loading';
import { PerspectiveCamera } from '@react-three/drei/core/PerspectiveCamera';
-import { Leva, useControls } from 'leva';
+import { useMediaQuery } from 'react-responsive';
const ComputerModel = lazy(
() => import('components/models/home/computer-model'),
);
+const Target = lazy(() => import('components/models/home/target'));
const ComputerDesk = () => {
- const c = useControls('RUARoom', {
- positionX: {
- value: 0,
- min: -10,
- max: 10,
- step: 0.1,
- },
- positionY: {
- value: 0,
- min: -10,
- max: 10,
- step: 0.1,
- },
- positionZ: {
- value: 0,
- min: -10,
- max: 10,
- step: 0.01,
- },
- rotationX: {
- value: 0,
- min: -Math.PI,
- max: Math.PI,
- step: 0.01,
- },
- rotationY: {
- value: 0,
- min: -Math.PI,
- max: Math.PI,
- step: 0.01,
- },
- rotationZ: {
- value: 0,
- min: -Math.PI,
- max: Math.PI,
- step: 0.001,
- },
- scale: {
- value: 1,
- min: 0.1,
- max: 10,
- step: 0.01,
- },
- });
+ const isMobile = useMediaQuery({ query: '(max-width: 768px)' });
+ const scale = useMemo(() => {
+ if (isMobile) {
+ return 0.08;
+ }
+ return 0.1;
+ }, [isMobile]);
return (
<>
@@ -63,14 +27,15 @@ const ComputerDesk = () => {
+
-
+ {/* */}
>
);
};
diff --git a/components/models/home/target.tsx b/components/models/home/target.tsx
new file mode 100644
index 0000000..69089e6
--- /dev/null
+++ b/components/models/home/target.tsx
@@ -0,0 +1,89 @@
+/**
+ * Samll target item in home page
+ */
+import * as THREE from 'three';
+import React, { JSX, useMemo, useRef } from 'react';
+import { useGLTF } from '@react-three/drei';
+import { DRACOLoader, GLTF, GLTFLoader } from 'three-stdlib';
+import { useLoader } from '@react-three/fiber';
+import gsap from 'gsap';
+import { useGSAP } from '@gsap/react';
+import { useMediaQuery } from 'react-responsive';
+
+type GLTFResult = GLTF & {
+ nodes: {
+ Cylinder016: THREE.Mesh;
+ Cylinder016_1: THREE.Mesh;
+ Cylinder016_2: THREE.Mesh;
+ };
+ materials: {
+ ['Red.025']: THREE.MeshStandardMaterial;
+ ['White.025']: THREE.MeshStandardMaterial;
+ ['BrownDark.018']: THREE.MeshStandardMaterial;
+ };
+};
+
+export function Target(props: JSX.IntrinsicElements['group']) {
+ const { nodes, materials } = useLoader(
+ GLTFLoader,
+ '/models/target-processed.gltf',
+ (loader) => {
+ const dracoLoader = new DRACOLoader();
+ dracoLoader.setDecoderPath('/libs/draco/');
+ loader.setDRACOLoader(dracoLoader);
+ },
+ ) as unknown as GLTFResult;
+
+ // animation
+ const targetRef = useRef(null);
+ useGSAP(() => {
+ if (!targetRef.current) return;
+ gsap.to(targetRef.current.position, {
+ y: targetRef.current.position.y + 0.5,
+ duration: 1.5,
+ repeat: -1,
+ yoyo: true,
+ });
+ });
+
+ const isMobile = useMediaQuery({ query: '(max-width: 768px)' });
+ const position = useMemo<[number, number, number]>(() => {
+ if (isMobile) {
+ return [-5, -5, 3] as const;
+ }
+ return [-14, -8, 0] as const;
+ }, [isMobile]);
+
+ return (
+
+
+
+
+
+
+
+ );
+}
+
+useGLTF.preload('/models/target-processed.gltf');
+
+export default Target;
diff --git a/package.json b/package.json
index 7a3bbc6..7605f23 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,7 @@
"@docsearch/css": "^3.9.0",
"@docsearch/react": "^3.9.0",
"@giscus/react": "^3.1.0",
+ "@gsap/react": "^2.1.2",
"@octokit/core": "^6.1.5",
"@octokit/plugin-rest-endpoint-methods": "^14.0.0",
"@react-spring/three": "^10.0.0",
@@ -30,12 +31,14 @@
"@tailwindcss/postcss": "^4.1.7",
"algoliasearch": "^5.25.0",
"dayjs": "^1.11.13",
+ "gsap": "^3.13.0",
"next": "15.3.2",
"next-mdx-remote": "^5.0.0",
"next-themes": "^0.4.6",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-icons": "^5.5.0",
+ "react-responsive": "^10.0.1",
"rehype-highlight": "^7.0.0",
"rehype-react": "^8.0.0",
"rehype-slug": "^6.0.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index a05c020..dea5bcb 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -29,6 +29,9 @@ importers:
'@giscus/react':
specifier: ^3.1.0
version: 3.1.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
+ '@gsap/react':
+ specifier: ^2.1.2
+ version: 2.1.2(gsap@3.13.0)(react@19.1.0)
'@octokit/core':
specifier: ^6.1.5
version: 6.1.5
@@ -53,6 +56,9 @@ importers:
dayjs:
specifier: ^1.11.13
version: 1.11.13
+ gsap:
+ specifier: ^3.13.0
+ version: 3.13.0
next:
specifier: 15.3.2
version: 15.3.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.89.0)
@@ -71,6 +77,9 @@ importers:
react-icons:
specifier: ^5.5.0
version: 5.5.0(react@19.1.0)
+ react-responsive:
+ specifier: ^10.0.1
+ version: 10.0.1(react@19.1.0)
rehype-highlight:
specifier: ^7.0.0
version: 7.0.1
@@ -449,6 +458,12 @@ packages:
react: ^16 || ^17 || ^18 || ^19
react-dom: ^16 || ^17 || ^18 || ^19
+ '@gsap/react@2.1.2':
+ resolution: {integrity: sha512-JqliybO1837UcgH2hVOM4VO+38APk3ECNrsuSM4MuXp+rbf+/2IG2K1YJiqfTcXQHH7XlA0m3ykniFYstfq0Iw==}
+ peerDependencies:
+ gsap: ^3.12.5
+ react: '>=17'
+
'@humanwhocodes/config-array@0.13.0':
resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==}
engines: {node: '>=10.10.0'}
@@ -1608,6 +1623,9 @@ packages:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
+ css-mediaquery@0.1.2:
+ resolution: {integrity: sha512-COtn4EROW5dBGlE/4PiKnh6rZpAPxDeFLaEEwt4i10jpDMFt2EhQGS79QmmrO+iKCHv0PU/HrOWEhijFd1x99Q==}
+
csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
@@ -2133,6 +2151,9 @@ packages:
resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==}
engines: {node: '>=6.0'}
+ gsap@3.13.0:
+ resolution: {integrity: sha512-QL7MJ2WMjm1PHWsoFrAQH/J8wUeqZvMtHO58qdekHpCfhvhSL4gSiz6vJf5EeMP0LOn3ZCprL2ki/gjED8ghVw==}
+
gzip-size@6.0.0:
resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==}
engines: {node: '>=10'}
@@ -2198,6 +2219,9 @@ packages:
html-escaper@2.0.2:
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
+ hyphenate-style-name@1.1.0:
+ resolution: {integrity: sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==}
+
iconv-lite@0.6.3:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
engines: {node: '>=0.10.0'}
@@ -2608,6 +2632,9 @@ packages:
markdown-table@3.0.4:
resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
+ matchmediaquery@0.4.2:
+ resolution: {integrity: sha512-wrZpoT50ehYOudhDjt/YvUJc6eUzcdFPdmbizfgvswCKNHD1/OBOHYJpHie+HXpu6bSkEGieFMYk6VuutaiRfA==}
+
mdast-util-find-and-replace@3.0.1:
resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==}
@@ -3072,6 +3099,12 @@ packages:
peerDependencies:
react: ^19.0.0
+ react-responsive@10.0.1:
+ resolution: {integrity: sha512-OM5/cRvbtUWEX8le8RCT8scA8y2OPtb0Q/IViEyCEM5FBN8lRrkUOZnu87I88A6njxDldvxG+rLBxWiA7/UM9g==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ react: '>=16.8.0'
+
react-use-measure@2.1.7:
resolution: {integrity: sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==}
peerDependencies:
@@ -3238,6 +3271,9 @@ packages:
resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==}
engines: {node: '>=0.10.0'}
+ shallow-equal@3.1.0:
+ resolution: {integrity: sha512-pfVOw8QZIXpMbhBWvzBISicvToTiM5WBF1EeAUZDDSb5Dt29yl4AYbyywbJFSEsRUMr7gJaxqCdr4L3tQf9wVg==}
+
sharp@0.34.1:
resolution: {integrity: sha512-1j0w61+eVxu7DawFJtnfYcvSv6qPFvfTaqzTQ2BLknVhHTwGS8sc63ZBF4rzkWMBVKybo4S5OBtDdZahh2A1xg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
@@ -4116,6 +4152,11 @@ snapshots:
react: 19.1.0
react-dom: 19.1.0(react@19.1.0)
+ '@gsap/react@2.1.2(gsap@3.13.0)(react@19.1.0)':
+ dependencies:
+ gsap: 3.13.0
+ react: 19.1.0
+
'@humanwhocodes/config-array@0.13.0':
dependencies:
'@humanwhocodes/object-schema': 2.0.3
@@ -5323,6 +5364,8 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
+ css-mediaquery@0.1.2: {}
+
csstype@3.1.3: {}
d@1.0.2:
@@ -6021,6 +6064,8 @@ snapshots:
section-matter: 1.0.0
strip-bom-string: 1.0.0
+ gsap@3.13.0: {}
+
gzip-size@6.0.0:
dependencies:
duplexer: 0.1.2
@@ -6117,6 +6162,8 @@ snapshots:
html-escaper@2.0.2: {}
+ hyphenate-style-name@1.1.0: {}
+
iconv-lite@0.6.3:
dependencies:
safer-buffer: 2.1.2
@@ -6492,6 +6539,10 @@ snapshots:
markdown-table@3.0.4: {}
+ matchmediaquery@0.4.2:
+ dependencies:
+ css-mediaquery: 0.1.2
+
mdast-util-find-and-replace@3.0.1:
dependencies:
'@types/mdast': 4.0.4
@@ -7237,6 +7288,14 @@ snapshots:
react: 19.1.0
scheduler: 0.25.0
+ react-responsive@10.0.1(react@19.1.0):
+ dependencies:
+ hyphenate-style-name: 1.1.0
+ matchmediaquery: 0.4.2
+ prop-types: 15.8.1
+ react: 19.1.0
+ shallow-equal: 3.1.0
+
react-use-measure@2.1.7(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
dependencies:
react: 19.1.0
@@ -7481,6 +7540,8 @@ snapshots:
is-plain-object: 2.0.4
split-string: 3.1.0
+ shallow-equal@3.1.0: {}
+
sharp@0.34.1:
dependencies:
color: 4.2.3
diff --git a/public/models/lowpoly-desk/lowpoly_desk-processed.glb b/public/models/lowpoly-desk/lowpoly_desk-processed.glb
deleted file mode 100644
index ac178c8..0000000
Binary files a/public/models/lowpoly-desk/lowpoly_desk-processed.glb and /dev/null differ
diff --git a/public/models/target-processed.gltf b/public/models/target-processed.gltf
new file mode 100644
index 0000000..12f635d
--- /dev/null
+++ b/public/models/target-processed.gltf
@@ -0,0 +1,288 @@
+{
+ "asset": {
+ "generator": "Khronos glTF Blender I/O v1.5.17",
+ "version": "2.0"
+ },
+ "scene": 0,
+ "scenes": [
+ {
+ "name": "Scene",
+ "nodes": [
+ 0
+ ]
+ }
+ ],
+ "nodes": [
+ {
+ "mesh": 0,
+ "name": "targetStand",
+ "rotation": [
+ 0.7071068286895752,
+ 0,
+ 0,
+ 0.7071067094802856
+ ],
+ "translation": [
+ 0,
+ 0,
+ 0
+ ],
+ "scale": [
+ 1,
+ 1,
+ 1
+ ]
+ }
+ ],
+ "materials": [
+ {
+ "doubleSided": true,
+ "name": "Red.025",
+ "pbrMetallicRoughness": {
+ "baseColorFactor": [
+ 1,
+ 0.02505292184650898,
+ 0.11802464723587036,
+ 1
+ ],
+ "metallicFactor": 0,
+ "roughnessFactor": 0.20000000298023224
+ },
+ "emissiveFactor": [
+ 0,
+ 0,
+ 0
+ ],
+ "alphaMode": "OPAQUE"
+ },
+ {
+ "doubleSided": true,
+ "name": "White.025",
+ "pbrMetallicRoughness": {
+ "baseColorFactor": [
+ 0.799102783203125,
+ 0.799102783203125,
+ 0.799102783203125,
+ 1
+ ],
+ "metallicFactor": 0,
+ "roughnessFactor": 0.5
+ },
+ "emissiveFactor": [
+ 0,
+ 0,
+ 0
+ ],
+ "alphaMode": "OPAQUE"
+ },
+ {
+ "doubleSided": true,
+ "name": "BrownDark.018",
+ "pbrMetallicRoughness": {
+ "baseColorFactor": [
+ 0.32694560289382935,
+ 0.10152623057365417,
+ 0.05927089974284172,
+ 1
+ ],
+ "metallicFactor": 0,
+ "roughnessFactor": 0.4000000059604645
+ },
+ "emissiveFactor": [
+ 0,
+ 0,
+ 0
+ ],
+ "alphaMode": "OPAQUE"
+ }
+ ],
+ "meshes": [
+ {
+ "name": "Cylinder.016",
+ "primitives": [
+ {
+ "attributes": {
+ "POSITION": 1,
+ "NORMAL": 2,
+ "TEXCOORD_0": 3
+ },
+ "indices": 0,
+ "material": 0,
+ "mode": 4,
+ "extensions": {
+ "KHR_draco_mesh_compression": {
+ "bufferView": 0,
+ "attributes": {
+ "POSITION": 0,
+ "NORMAL": 1,
+ "TEXCOORD_0": 2
+ }
+ }
+ }
+ },
+ {
+ "attributes": {
+ "POSITION": 5,
+ "NORMAL": 6,
+ "TEXCOORD_0": 7
+ },
+ "indices": 4,
+ "material": 1,
+ "mode": 4,
+ "extensions": {
+ "KHR_draco_mesh_compression": {
+ "bufferView": 1,
+ "attributes": {
+ "POSITION": 0,
+ "NORMAL": 1,
+ "TEXCOORD_0": 2
+ }
+ }
+ }
+ },
+ {
+ "attributes": {
+ "POSITION": 9,
+ "NORMAL": 10,
+ "TEXCOORD_0": 11
+ },
+ "indices": 8,
+ "material": 2,
+ "mode": 4,
+ "extensions": {
+ "KHR_draco_mesh_compression": {
+ "bufferView": 2,
+ "attributes": {
+ "POSITION": 0,
+ "NORMAL": 1,
+ "TEXCOORD_0": 2
+ }
+ }
+ }
+ }
+ ]
+ }
+ ],
+ "accessors": [
+ {
+ "componentType": 5123,
+ "count": 282,
+ "type": "SCALAR"
+ },
+ {
+ "componentType": 5126,
+ "count": 96,
+ "max": [
+ 0.5114296778097465,
+ 0.8281944695337842,
+ -0.7671326534539592
+ ],
+ "min": [
+ -0.5114295586004569,
+ 0.43332787314507226,
+ -1.7111184104338004
+ ],
+ "type": "VEC3"
+ },
+ {
+ "componentType": 5126,
+ "count": 96,
+ "type": "VEC3"
+ },
+ {
+ "componentType": 5126,
+ "count": 96,
+ "type": "VEC2"
+ },
+ {
+ "componentType": 5123,
+ "count": 1818,
+ "type": "SCALAR"
+ },
+ {
+ "componentType": 5126,
+ "count": 734,
+ "max": [
+ 0.684837244316375,
+ 0.8791963504067735,
+ -0.4541223597165487
+ ],
+ "min": [
+ -0.6851508665445902,
+ -0.0215896416071513,
+ -1.85557300332819
+ ],
+ "type": "VEC3"
+ },
+ {
+ "componentType": 5126,
+ "count": 734,
+ "type": "VEC3"
+ },
+ {
+ "componentType": 5126,
+ "count": 734,
+ "type": "VEC2"
+ },
+ {
+ "componentType": 5123,
+ "count": 252,
+ "type": "SCALAR"
+ },
+ {
+ "componentType": 5126,
+ "count": 120,
+ "max": [
+ 0.6735454190924626,
+ 0.6617427920794337,
+ 0.0007889245740948514
+ ],
+ "min": [
+ -0.6735453594878178,
+ -0.6570781458571415,
+ -1.3108001936629277
+ ],
+ "type": "VEC3"
+ },
+ {
+ "componentType": 5126,
+ "count": 120,
+ "type": "VEC3"
+ },
+ {
+ "componentType": 5126,
+ "count": 120,
+ "type": "VEC2"
+ }
+ ],
+ "bufferViews": [
+ {
+ "buffer": 0,
+ "byteOffset": 0,
+ "byteLength": 729
+ },
+ {
+ "buffer": 0,
+ "byteOffset": 736,
+ "byteLength": 2912
+ },
+ {
+ "buffer": 0,
+ "byteOffset": 3648,
+ "byteLength": 758
+ }
+ ],
+ "buffers": [
+ {
+ "name": "target-processed",
+ "byteLength": 4408,
+ "uri": "data:application/octet-stream;base64,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"
+ }
+ ],
+ "extensionsRequired": [
+ "KHR_draco_mesh_compression"
+ ],
+ "extensionsUsed": [
+ "KHR_draco_mesh_compression"
+ ]
+}