{"id":12626,"date":"2026-02-24T19:19:09","date_gmt":"2026-02-24T19:19:09","guid":{"rendered":"https:\/\/withcode.tech\/media\/?p=12626"},"modified":"2026-07-01T15:29:07","modified_gmt":"2026-07-01T15:29:07","slug":"threejs-scroll-animation","status":"publish","type":"post","link":"https:\/\/withcode.tech\/media\/threejs-scroll-animation\/","title":{"rendered":"\u3010\u5b9f\u88c5\u30ac\u30a4\u30c9\u3011Three.js\u30b9\u30af\u30ed\u30fc\u30eb\u9023\u52d5\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u306e\u4f5c\u308a\u65b9\uff01\u57fa\u790e\u304b\u3089\u5fdc\u7528\u307e\u3067\u8a73\u3057\u304f\u89e3\u8aac"},"content":{"rendered":"\n<div class=\"wp-block-group swl-box\"><div class=\"wp-block-group__inner-container\">\n\n<h3 class=\"wp-block-heading\">\u3053\u306e\u8a18\u4e8b\u3067\u308f\u304b\u308b\u3053\u3068<\/h3>\n\n\n<ul class=\"wp-block-list\">\n<li>Three.js \u306e\u57fa\u672c\u69cb\u6210\u8981\u7d20\uff08Scene\u30fbCamera\u30fbRenderer\u30fbMesh\uff09\u306e\u5f79\u5272<\/li>\n<li>\u30b9\u30af\u30ed\u30fc\u30eb\u91cf\u3092 3D \u5ea7\u6a19\u306b\u5909\u63db\u3057\u3066\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u3055\u305b\u308b\u4ed5\u7d44\u307f<\/li>\n<li>\u7dda\u5f62\u88dc\u9593\uff08Lerp\uff09\u3092\u4f7f\u3063\u305f\u6163\u6027\u52b9\u679c\u306e\u5b9f\u88c5\u65b9\u6cd5<\/li>\n<li>\u30d1\u30e9\u30e9\u30c3\u30af\u30b9\u52b9\u679c\u30fb\u30bb\u30af\u30b7\u30e7\u30f3\u5225\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u306e\u5fdc\u7528\u5b9f\u88c5<\/li>\n<li>GSAP\u30fbLenis \u3068\u306e\u9023\u643a\u3068\u3001\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u306e\u30c6\u30af\u30cb\u30c3\u30af<\/li>\n<\/ul>\n\n<\/div><\/div>\n\n\n<div class=\"swell-block-balloon\"><div class=\"c-balloon -bln-left\" data-col=\"gray\"><div class=\"c-balloon__icon -square\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/withcode.tech\/media\/wp-content\/uploads\/2025\/06\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2025-06-15-14.48.08.jpg\" alt=\"\" class=\"c-balloon__iconImg\" width=\"80px\" height=\"80px\"><span class=\"c-balloon__iconName\">\u751f\u5f92<\/span><\/div><div class=\"c-balloon__body -speaking -border-none\"><div class=\"c-balloon__text\">\n<p><strong>Three.js\u3067\u30b9\u30af\u30ed\u30fc\u30eb\u306b\u9023\u52d5\u3059\u308b3D\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u3092\u4f5c\u308a\u305f\u3044\u3093\u3067\u3059\u304c\u3001\u3069\u3046\u3059\u308c\u3070\u826f\u3044\u3067\u3057\u3087\u3046\u304b\uff1f<\/strong><\/p>\n<span class=\"c-balloon__shapes\"><span class=\"c-balloon__before\"><\/span><span class=\"c-balloon__after\"><\/span><\/span><\/div><\/div><\/div><\/div>\n\n<div class=\"swell-block-balloon\"><div class=\"c-balloon -bln-right\" data-col=\"gray\"><div class=\"c-balloon__icon -square\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/withcode.tech\/media\/wp-content\/uploads\/2025\/06\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2025-06-15-15.11.23.jpg\" alt=\"\" class=\"c-balloon__iconImg\" width=\"80px\" height=\"80px\"><span class=\"c-balloon__iconName\">\u30da\u30f3\u535a\u58eb<\/span><\/div><div class=\"c-balloon__body -speaking -border-none\"><div class=\"c-balloon__text\">\n<p><strong>\u3088\u30fc\u304f\u805e\u304f\u3093\u3060\u305e\uff01Three.js\u3068\u30b9\u30af\u30ed\u30fc\u30eb\u30a4\u30d9\u30f3\u30c8\u3092\u7d44\u307f\u5408\u308f\u305b\u308c\u3070\u3001\u6ca1\u5165\u611f\u306e\u3042\u308b3D\u4f53\u9a13\u304c\u4f5c\u308c\u308b\u3093\u3058\u3083\u3002\u4eca\u65e5\u306f\u57fa\u672c\u304b\u3089\u5fdc\u7528\u307e\u3067\u8a73\u3057\u304f\u89e3\u8aac\u3059\u308b\u305e\u3044\uff01<\/strong><\/p>\n<span class=\"c-balloon__shapes\"><span class=\"c-balloon__before\"><\/span><span class=\"c-balloon__after\"><\/span><\/span><\/div><\/div><\/div><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>\u7d50\u8ad6\u304b\u3089\u8a00\u3046\u3068\u3001Three.js \u306e\u30b9\u30af\u30ed\u30fc\u30eb\u9023\u52d5\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u306f\u300c\u30b9\u30af\u30ed\u30fc\u30eb\u91cf\u306e\u53d6\u5f97 \u2192 3D \u5ea7\u6a19\u3078\u306e\u5909\u63db \u2192 requestAnimationFrame \u3067\u306e\u518d\u63cf\u753b\u300d\u3068\u3044\u30463\u30b9\u30c6\u30c3\u30d7\u3067\u5b9f\u73fe\u3057\u307e\u3059\u3002<\/strong>\u7dda\u5f62\u88dc\u9593\uff08Lerp\uff09\u3092\u4f7f\u3048\u3070\u6163\u6027\u52b9\u679c\u3082\u7c21\u5358\u306b\u8ffd\u52a0\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u672c\u8a18\u4e8b\u3067\u306f\u3001<strong><span class=\"swl-marker mark_yellow\">Three.js \u3092\u4f7f\u3063\u3066\u30b9\u30af\u30ed\u30fc\u30eb\u9023\u52d5\u306e 3D \u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u88c5\u3059\u308b\u65b9\u6cd5\u3092\u3001\u57fa\u790e\u304b\u3089\u5fdc\u7528\u307e\u3067<\/span><\/strong>\u3001\u5b9f\u88c5\u4f8b\u3092\u4ea4\u3048\u3066\u5fb9\u5e95\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Three.js \u3068\u306f\uff1f<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">\u57fa\u672c\u6982\u5ff5\u3068\u4e3b\u8981\u69cb\u6210\u8981\u7d20<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Three.js \u306f\u3001<strong>WebGL \u3092\u3088\u308a\u7c21\u5358\u306b\u6271\u3048\u308b\u3088\u3046\u306b\u3057\u305f JavaScript \u30e9\u30a4\u30d6\u30e9\u30ea<\/strong>\u3067\u3059\u3002WebGL \u306e\u8907\u96d1\u306a\u4f4e\u30ec\u30d9\u30eb API \u3092\u62bd\u8c61\u5316\u3057\u3001\u6570\u884c\u306e\u30b3\u30fc\u30c9\u3067 3D \u30b7\u30fc\u30f3\u3092\u4f5c\u6210\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>\u69cb\u6210\u8981\u7d20<\/th><th>\u5f79\u5272<\/th><\/tr><\/thead><tbody><tr><td>Scene\uff08\u30b7\u30fc\u30f3\uff09<\/td><td>3D \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092\u914d\u7f6e\u3059\u308b\u7a7a\u9593<\/td><\/tr><tr><td>Camera\uff08\u30ab\u30e1\u30e9\uff09<\/td><td>\u30b7\u30fc\u30f3\u3092\u898b\u308b\u8996\u70b9<\/td><\/tr><tr><td>Renderer\uff08\u30ec\u30f3\u30c0\u30e9\u30fc\uff09<\/td><td>\u30b7\u30fc\u30f3\u3068\u30ab\u30e1\u30e9\u3092\u4f7f\u3063\u3066\u753b\u50cf\u3092\u751f\u6210<\/td><\/tr><tr><td>Mesh\uff08\u30e1\u30c3\u30b7\u30e5\uff09<\/td><td>\u30b8\u30aa\u30e1\u30c8\u30ea\uff08\u5f62\u72b6\uff09\u3068\u30de\u30c6\u30ea\u30a2\u30eb\uff08\u8cea\u611f\uff09\u306e\u7d44\u307f\u5408\u308f\u305b<\/td><\/tr><tr><td>Light\uff08\u30e9\u30a4\u30c8\uff09<\/td><td>\u30b7\u30fc\u30f3\u3092\u7167\u3089\u3059\u5149\u6e90<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">\u30b9\u30af\u30ed\u30fc\u30eb\u9023\u52d5\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u306e\u4ed5\u7d44\u307f<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30b9\u30af\u30ed\u30fc\u30eb\u91cf\u3092\u53d6\u5f97<\/strong>\uff1aJavaScript \u3067\u30da\u30fc\u30b8\u306e\u30b9\u30af\u30ed\u30fc\u30eb\u4f4d\u7f6e\u3092\u76e3\u8996<\/li>\n<li><strong>\u30b9\u30af\u30ed\u30fc\u30eb\u91cf\u3092 3D \u5ea7\u6a19\u306b\u5909\u63db<\/strong>\uff1a\u30b9\u30af\u30ed\u30fc\u30eb\u5024\u3092 3D \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u4f4d\u7f6e\u3084\u56de\u8ee2\u306b\u9069\u7528<\/li>\n<li><strong>\u30b7\u30fc\u30f3\u3092\u518d\u63cf\u753b<\/strong>\uff1arequestAnimationFrame \u3067\u6ed1\u3089\u304b\u306b\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u74b0\u5883\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7<\/h2>\n\n\n<div class=\"swell-block-balloon\"><div class=\"c-balloon -bln-left\" data-col=\"gray\"><div class=\"c-balloon__icon -square\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/withcode.tech\/media\/wp-content\/uploads\/2025\/06\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2025-06-15-14.48.08.jpg\" alt=\"\" class=\"c-balloon__iconImg\" width=\"80px\" height=\"80px\"><span class=\"c-balloon__iconName\">\u751f\u5f92<\/span><\/div><div class=\"c-balloon__body -speaking -border-none\"><div class=\"c-balloon__text\">\n<p><strong>\u307e\u305a\u306f\u4f55\u304b\u3089\u59cb\u3081\u308c\u3070\u826f\u3044\u3067\u3059\u304b\uff1f<\/strong><\/p>\n<span class=\"c-balloon__shapes\"><span class=\"c-balloon__before\"><\/span><span class=\"c-balloon__after\"><\/span><\/span><\/div><\/div><\/div><\/div>\n\n<div class=\"swell-block-balloon\"><div class=\"c-balloon -bln-right\" data-col=\"gray\"><div class=\"c-balloon__icon -square\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/withcode.tech\/media\/wp-content\/uploads\/2025\/06\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2025-06-15-15.11.23.jpg\" alt=\"\" class=\"c-balloon__iconImg\" width=\"80px\" height=\"80px\"><span class=\"c-balloon__iconName\">\u30da\u30f3\u535a\u58eb<\/span><\/div><div class=\"c-balloon__body -speaking -border-none\"><div class=\"c-balloon__text\">\n<p><strong>\u307e\u305a\u306fThree.js\u3092\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u5c0e\u5165\u3059\u308b\u3093\u3058\u3083\u3002CDN\u3092\u4f7f\u3048\u3070\u7c21\u5358\u306b\u59cb\u3081\u3089\u308c\u308b\u305e<\/strong><\/p>\n<span class=\"c-balloon__shapes\"><span class=\"c-balloon__before\"><\/span><span class=\"c-balloon__after\"><\/span><\/span><\/div><\/div><\/div><\/div>\n\n\n<h3 class=\"wp-block-heading\">\u65b9\u6cd51\uff1aCDN \u7d4c\u7531\u3067\u8aad\u307f\u8fbc\u307f\uff08\u7c21\u5358\uff09<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;!DOCTYPE html&gt;\n&lt;html lang=\"ja\"&gt;\n&lt;head&gt;\n  &lt;meta charset=\"UTF-8\"&gt;\n  &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"&gt;\n  &lt;title&gt;Three.js \u30b9\u30af\u30ed\u30fc\u30eb\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3&lt;\/title&gt;\n  &lt;style&gt;\n    body {\n      margin: 0;\n      overflow-x: hidden;\n    }\n\n    #canvas-container {\n      position: fixed;\n      top: 0;\n      left: 0;\n      width: 100%;\n      height: 100vh;\n      z-index: -1;\n    }\n\n    .content {\n      position: relative;\n      height: 300vh; \/* \u30b9\u30af\u30ed\u30fc\u30eb\u53ef\u80fd\u306b\u3059\u308b *\/\n      padding: 50px;\n    }\n  &lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n  &lt;div id=\"canvas-container\"&gt;&lt;\/div&gt;\n  &lt;div class=\"content\"&gt;\n    &lt;h1&gt;\u30b9\u30af\u30ed\u30fc\u30eb\u3057\u3066\u307f\u3066\u304f\u3060\u3055\u3044&lt;\/h1&gt;\n  &lt;\/div&gt;\n\n  &lt;!-- Three.js\u672c\u4f53 --&gt;\n  &lt;script type=\"importmap\"&gt;\n    {\n      \"imports\": {\n        \"three\": \"https:\/\/cdn.jsdelivr.net\/npm\/three@0.160.0\/build\/three.module.js\"\n      }\n    }\n  &lt;\/script&gt;\n\n  &lt;script type=\"module\" src=\"main.js\"&gt;&lt;\/script&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\u65b9\u6cd52\uff1anpm \u7d4c\u7531\u3067\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\uff08\u63a8\u5968\uff09<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code># \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u521d\u671f\u5316\nnpm init -y\n\n# Three.js\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\nnpm install three\n\n# Vite\u3092\u4f7f\u3063\u305f\u958b\u767a\u74b0\u5883\uff08\u30aa\u30d7\u30b7\u30e7\u30f3\uff09\nnpm install -D vite<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u57fa\u672c\u5b9f\u88c5\uff1a\u30b7\u30f3\u30d7\u30eb\u306a\u30b9\u30af\u30ed\u30fc\u30eb\u9023\u52d5<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">\u30b9\u30c6\u30c3\u30d71\uff1a\u57fa\u672c\u30b7\u30fc\u30f3\u306e\u4f5c\u6210<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ main.js\nimport * as THREE from 'three';\n\n\/\/ \u30b7\u30fc\u30f3\u3001\u30ab\u30e1\u30e9\u3001\u30ec\u30f3\u30c0\u30e9\u30fc\u306e\u4f5c\u6210\nconst scene = new THREE.Scene();\n\n\/\/ \u30ab\u30e1\u30e9\u306e\u8a2d\u5b9a\nconst camera = new THREE.PerspectiveCamera(\n  75, \/\/ \u8996\u91ce\u89d2\uff08FOV\uff09\n  window.innerWidth \/ window.innerHeight, \/\/ \u30a2\u30b9\u30da\u30af\u30c8\u6bd4\n  0.1, \/\/ Near\uff08\u3053\u308c\u3088\u308a\u8fd1\u3044\u3082\u306e\u306f\u63cf\u753b\u3055\u308c\u306a\u3044\uff09\n  1000 \/\/ Far\uff08\u3053\u308c\u3088\u308a\u9060\u3044\u3082\u306e\u306f\u63cf\u753b\u3055\u308c\u306a\u3044\uff09\n);\ncamera.position.z = 5;\n\n\/\/ \u30ec\u30f3\u30c0\u30e9\u30fc\u306e\u8a2d\u5b9a\nconst renderer = new THREE.WebGLRenderer({\n  alpha: true, \/\/ \u80cc\u666f\u3092\u900f\u660e\u306b\n  antialias: true \/\/ \u30a2\u30f3\u30c1\u30a8\u30a4\u30ea\u30a2\u30b9\u6709\u52b9\u5316\n});\nrenderer.setSize(window.innerWidth, window.innerHeight);\nrenderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); \/\/ Retina\u30c7\u30a3\u30b9\u30d7\u30ec\u30a4\u5bfe\u5fdc\n\n\/\/ canvas\u3092DOM\u306b\u8ffd\u52a0\nconst container = document.getElementById('canvas-container');\ncontainer.appendChild(renderer.domElement);\n\n\/\/ \u30b8\u30aa\u30e1\u30c8\u30ea\u3068\u30de\u30c6\u30ea\u30a2\u30eb\u3067\u30e1\u30c3\u30b7\u30e5\u3092\u4f5c\u6210\nconst geometry = new THREE.BoxGeometry(1, 1, 1);\nconst material = new THREE.MeshStandardMaterial({\n  color: 0x00ff00,\n  metalness: 0.5,\n  roughness: 0.5\n});\nconst cube = new THREE.Mesh(geometry, material);\nscene.add(cube);\n\n\/\/ \u30e9\u30a4\u30c8\u306e\u8ffd\u52a0\nconst ambientLight = new THREE.AmbientLight(0xffffff, 0.5);\nscene.add(ambientLight);\n\nconst directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);\ndirectionalLight.position.set(5, 5, 5);\nscene.add(directionalLight);\n\n\/\/ \u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u30eb\u30fc\u30d7\nfunction animate() {\n  requestAnimationFrame(animate);\n\n  \/\/ \u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\n  renderer.render(scene, camera);\n}\n\nanimate();<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\u30b9\u30c6\u30c3\u30d72\uff1a\u30b9\u30af\u30ed\u30fc\u30eb\u9023\u52d5\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \u30b9\u30af\u30ed\u30fc\u30eb\u30a4\u30d9\u30f3\u30c8\u306e\u76e3\u8996\nlet scrollY = window.pageYOffset;\n\nwindow.addEventListener('scroll', () => {\n  scrollY = window.pageYOffset;\n});\n\n\/\/ \u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u30eb\u30fc\u30d7\u306b\u8ffd\u52a0\nfunction animate() {\n  requestAnimationFrame(animate);\n\n  \/\/ \u30b9\u30af\u30ed\u30fc\u30eb\u91cf\u306b\u5fdc\u3058\u3066\u30ad\u30e5\u30fc\u30d6\u3092\u56de\u8ee2\n  cube.rotation.y = scrollY * 0.001;\n  cube.rotation.x = scrollY * 0.0005;\n\n  \/\/ \u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\n  renderer.render(scene, camera);\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\u30b9\u30c6\u30c3\u30d73\uff1a\u30ec\u30b9\u30dd\u30f3\u30b7\u30d6\u5bfe\u5fdc<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \u30a6\u30a3\u30f3\u30c9\u30a6\u30ea\u30b5\u30a4\u30ba\u5bfe\u5fdc\nwindow.addEventListener('resize', () => {\n  \/\/ \u30ab\u30e1\u30e9\u306e\u30a2\u30b9\u30da\u30af\u30c8\u6bd4\u3092\u66f4\u65b0\n  camera.aspect = window.innerWidth \/ window.innerHeight;\n  camera.updateProjectionMatrix();\n\n  \/\/ \u30ec\u30f3\u30c0\u30e9\u30fc\u306e\u30b5\u30a4\u30ba\u3092\u66f4\u65b0\n  renderer.setSize(window.innerWidth, window.innerHeight);\n  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));\n});<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u5fdc\u7528\u5b9f\u88c5\uff1a\u30ab\u30e1\u30e9\u8ddd\u96e2\u306e\u6700\u9069\u5316<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Three.js \u306e\u5ea7\u6a19\u7cfb\u3092\u30d4\u30af\u30bb\u30eb\u5ea7\u6a19\u306b\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u76f4\u611f\u7684\u306a\u914d\u7f6e\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u30ab\u30e1\u30e9\u8ddd\u96e2\u306e\u8a08\u7b97<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \u30ab\u30e1\u30e9\u306e\u8996\u91ce\u89d2\uff08FOV\uff09\nconst fov = 45;\n\n\/\/ \u30ab\u30e1\u30e9\u8ddd\u96e2\u3092\u8a08\u7b97\n\/\/ \u3053\u306e\u8ddd\u96e2\u306b\u914d\u7f6e\u3059\u308b\u3068\u3001Three.js\u306e\u5ea7\u6a191\u5358\u4f4d = 1\u30d4\u30af\u30bb\u30eb\u306b\u306a\u308b\nfunction getCameraDistance() {\n  const fovRad = (fov * Math.PI) \/ 180; \/\/ \u5ea6\u3092\u30e9\u30b8\u30a2\u30f3\u306b\u5909\u63db\n  const distance = window.innerHeight \/ (2 * Math.tan(fovRad \/ 2));\n  return distance;\n}\n\n\/\/ \u30ab\u30e1\u30e9\u306e\u8a2d\u5b9a\nconst camera = new THREE.PerspectiveCamera(\n  fov,\n  window.innerWidth \/ window.innerHeight,\n  0.1,\n  10000\n);\n\n\/\/ \u30ab\u30e1\u30e9\u3092Z\u8ef8\u4e0a\u3067\u6700\u9069\u306a\u8ddd\u96e2\u306b\u914d\u7f6e\ncamera.position.z = getCameraDistance();\n\n\/\/ \u30ea\u30b5\u30a4\u30ba\u6642\u306b\u30ab\u30e1\u30e9\u8ddd\u96e2\u3092\u518d\u8a08\u7b97\nwindow.addEventListener('resize', () => {\n  camera.aspect = window.innerWidth \/ window.innerHeight;\n  camera.position.z = getCameraDistance();\n  camera.updateProjectionMatrix();\n\n  renderer.setSize(window.innerWidth, window.innerHeight);\n  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));\n});<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\u30d4\u30af\u30bb\u30eb\u5358\u4f4d\u3067\u306e\u914d\u7f6e<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \u3053\u308c\u3067\u5ea7\u6a191\u5358\u4f4d = 1\u30d4\u30af\u30bb\u30eb\u306b\u306a\u308b\n\/\/ \u4f8b\uff1a\u753b\u9762\u4e2d\u592e\u306b200x200px\u306e\u30ad\u30e5\u30fc\u30d6\u3092\u914d\u7f6e\nconst cubeSize = 200;\nconst geometry = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize);\nconst material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });\nconst cube = new THREE.Mesh(geometry, material);\n\n\/\/ \u753b\u9762\u4e2d\u592e\u306b\u914d\u7f6e\uff08Three.js\u306e\u539f\u70b9\u306f\u753b\u9762\u4e2d\u592e\uff09\ncube.position.x = 0;\ncube.position.y = 0;\ncube.position.z = 0;\n\nscene.add(cube);\n\n\/\/ \u30b9\u30af\u30ed\u30fc\u30eb\u9023\u52d5\u3067Y\u5ea7\u6a19\u3092\u5909\u66f4\nwindow.addEventListener('scroll', () => {\n  \/\/ \u30b9\u30af\u30ed\u30fc\u30eb\u91cf\u3092\u305d\u306e\u307e\u307eY\u5ea7\u6a19\u306b\u9069\u7528\n  \/\/ \u8ca0\u306e\u5024\u306b\u3059\u308b\u3053\u3068\u3067\u3001\u4e0b\u306b\u30b9\u30af\u30ed\u30fc\u30eb\u3059\u308b\u3068\u4e0b\u306b\u79fb\u52d5\n  cube.position.y = -window.pageYOffset;\n});<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u9ad8\u5ea6\u306a\u5b9f\u88c5\uff1a\u6163\u6027\u52b9\u679c\u3068\u30b9\u30e0\u30fc\u30ba\u306a\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u30b9\u30af\u30ed\u30fc\u30eb\u306b\u9045\u5ef6\u3092\u6301\u305f\u305b\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u6ed1\u3089\u304b\u3067\u5fc3\u5730\u3088\u3044\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u7dda\u5f62\u88dc\u9593\uff08Lerp\uff09\u3092\u4f7f\u3063\u305f\u6163\u6027\u52b9\u679c<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \u73fe\u5728\u306e\u30b9\u30af\u30ed\u30fc\u30eb\u4f4d\u7f6e\u3068\u30bf\u30fc\u30b2\u30c3\u30c8\u4f4d\u7f6e\nlet scrollY = 0;\nlet currentScrollY = 0;\n\nwindow.addEventListener('scroll', () => {\n  scrollY = window.pageYOffset;\n});\n\n\/\/ \u7dda\u5f62\u88dc\u9593\u95a2\u6570\nfunction lerp(start, end, factor) {\n  return start + (end - start) * factor;\n}\n\nfunction animate() {\n  requestAnimationFrame(animate);\n\n  \/\/ \u6163\u6027\u52b9\u679c\uff1a\u73fe\u5728\u4f4d\u7f6e\u3092\u30bf\u30fc\u30b2\u30c3\u30c8\u306b\u5411\u3051\u3066\u5f90\u3005\u306b\u79fb\u52d5\n  \/\/ factor\u304c\u5c0f\u3055\u3044\u307b\u3069\u9045\u5ef6\u304c\u5927\u304d\u304f\u306a\u308b\uff080.05 = \u304b\u306a\u308a\u9045\u3044\u30010.1 = \u6a19\u6e96\uff09\n  currentScrollY = lerp(currentScrollY, scrollY, 0.08);\n\n  \/\/ \u30b9\u30af\u30ed\u30fc\u30eb\u91cf\u306b\u5fdc\u3058\u3066\u56de\u8ee2\uff08\u4fc2\u6570\u3067\u52d5\u304d\u3092\u8abf\u6574\uff09\n  cube.rotation.y = currentScrollY * 0.001;\n  cube.rotation.x = currentScrollY * 0.0005;\n\n  \/\/ Y\u5ea7\u6a19\u306e\u79fb\u52d5\uff08\u30d1\u30e9\u30e9\u30c3\u30af\u30b9\u52b9\u679c\uff09\n  cube.position.y = -currentScrollY * 0.5; \/\/ 0.5\u500d\u306e\u901f\u5ea6\u3067\u79fb\u52d5\n\n  renderer.render(scene, camera);\n}\n\nanimate();<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\u8907\u6570\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3067\u7570\u306a\u308b\u901f\u5ea6\uff08\u30d1\u30e9\u30e9\u30c3\u30af\u30b9\u52b9\u679c\uff09<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \u8907\u6570\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092\u4f5c\u6210\nconst objects = [];\n\n\/\/ \u80cc\u666f\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\uff08\u9045\u304f\u52d5\u304f\uff09\nconst bgGeometry = new THREE.SphereGeometry(100, 32, 32);\nconst bgMaterial = new THREE.MeshStandardMaterial({\n  color: 0x3366ff,\n  metalness: 0.3,\n  roughness: 0.7\n});\nconst bgSphere = new THREE.Mesh(bgGeometry, bgMaterial);\nbgSphere.position.z = -300;\nscene.add(bgSphere);\nobjects.push({ mesh: bgSphere, speed: 0.2 }); \/\/ 0.2\u500d\u306e\u901f\u5ea6\n\n\/\/ \u4e2d\u666f\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\uff08\u6a19\u6e96\u306e\u901f\u5ea6\uff09\nconst midGeometry = new THREE.TorusGeometry(80, 30, 16, 100);\nconst midMaterial = new THREE.MeshStandardMaterial({\n  color: 0xff6600,\n  metalness: 0.5,\n  roughness: 0.5\n});\nconst midTorus = new THREE.Mesh(midGeometry, midMaterial);\nmidTorus.position.z = -100;\nscene.add(midTorus);\nobjects.push({ mesh: midTorus, speed: 0.5 }); \/\/ 0.5\u500d\u306e\u901f\u5ea6\n\n\/\/ \u524d\u666f\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\uff08\u901f\u304f\u52d5\u304f\uff09\nconst fgGeometry = new THREE.ConeGeometry(50, 100, 4);\nconst fgMaterial = new THREE.MeshStandardMaterial({\n  color: 0xff0066,\n  metalness: 0.7,\n  roughness: 0.3\n});\nconst fgCone = new THREE.Mesh(fgGeometry, fgMaterial);\nfgCone.position.z = 50;\nscene.add(fgCone);\nobjects.push({ mesh: fgCone, speed: 1.2 }); \/\/ 1.2\u500d\u306e\u901f\u5ea6\n\n\/\/ \u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u30eb\u30fc\u30d7\nlet scrollY = 0;\nlet currentScrollY = 0;\n\nwindow.addEventListener('scroll', () => {\n  scrollY = window.pageYOffset;\n});\n\nfunction animate() {\n  requestAnimationFrame(animate);\n\n  currentScrollY = lerp(currentScrollY, scrollY, 0.08);\n\n  \/\/ \u5404\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092\u7570\u306a\u308b\u901f\u5ea6\u3067\u52d5\u304b\u3059\n  objects.forEach(({ mesh, speed }) => {\n    mesh.position.y = -currentScrollY * speed;\n    mesh.rotation.y = currentScrollY * 0.001 * speed;\n  });\n\n  renderer.render(scene, camera);\n}\n\nanimate();<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u5b9f\u8df5\u7684\u306a\u5fdc\u7528\uff1a\u30bb\u30af\u30b7\u30e7\u30f3\u3054\u3068\u306e\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><span class=\"swl-marker mark_yellow\">\u30b9\u30af\u30ed\u30fc\u30eb\u4f4d\u7f6e\u306b\u5fdc\u3058\u3066\u7570\u306a\u308b\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u884c\u3059\u308b\u5b9f\u88c5\u4f8b<\/span><\/strong>\u3067\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u30bb\u30af\u30b7\u30e7\u30f3\u691c\u77e5\u3068\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u5207\u308a\u66ff\u3048<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \u30bb\u30af\u30b7\u30e7\u30f3\u306e\u5b9a\u7fa9\nconst sections = [\n  {\n    element: document.querySelector('#section1'),\n    animation: (progress) => {\n      \/\/ \u30bb\u30af\u30b7\u30e7\u30f31: \u56de\u8ee2\n      cube.rotation.y = progress * Math.PI * 2;\n      cube.scale.set(1 + progress * 0.5, 1 + progress * 0.5, 1 + progress * 0.5);\n    }\n  },\n  {\n    element: document.querySelector('#section2'),\n    animation: (progress) => {\n      \/\/ \u30bb\u30af\u30b7\u30e7\u30f32: \u8272\u5909\u5316\n      const color = new THREE.Color();\n      color.setHSL(progress, 0.7, 0.5);\n      cube.material.color = color;\n    }\n  },\n  {\n    element: document.querySelector('#section3'),\n    animation: (progress) => {\n      \/\/ \u30bb\u30af\u30b7\u30e7\u30f33: \u4f4d\u7f6e\u79fb\u52d5\n      cube.position.x = (progress - 0.5) * 400;\n      cube.rotation.z = progress * Math.PI;\n    }\n  }\n];\n\nfunction getCurrentSection() {\n  const scrollY = window.pageYOffset;\n  const windowHeight = window.innerHeight;\n\n  for (let i = 0; i < sections.length; i++) {\n    const section = sections[i];\n    const rect = section.element.getBoundingClientRect();\n    const sectionTop = scrollY + rect.top;\n    const sectionBottom = sectionTop + rect.height;\n\n    \/\/ \u73fe\u5728\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3092\u5224\u5b9a\n    if (scrollY >= sectionTop - windowHeight && scrollY <= sectionBottom) {\n      \/\/ \u30bb\u30af\u30b7\u30e7\u30f3\u5185\u306e\u9032\u884c\u5ea6\u3092\u8a08\u7b97\uff080\u301c1\uff09\n      const progress = Math.max(0, Math.min(1,\n        (scrollY - sectionTop + windowHeight) \/ (rect.height + windowHeight)\n      ));\n\n      return { section, progress, index: i };\n    }\n  }\n\n  return null;\n}\n\nfunction animate() {\n  requestAnimationFrame(animate);\n\n  const current = getCurrentSection();\n\n  if (current) {\n    \/\/ \u73fe\u5728\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u306e\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u884c\n    current.section.animation(current.progress);\n  }\n\n  renderer.render(scene, camera);\n}\n\nanimate();<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Intersection Observer API \u3092\u4f7f\u3063\u305f\u6700\u9069\u5316<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Intersection Observer\u3067\u8868\u793a\u9818\u57df\u3092\u76e3\u8996\nlet isVisible = false;\n\nconst observer = new IntersectionObserver((entries) => {\n  entries.forEach(entry => {\n    isVisible = entry.isIntersecting;\n  });\n}, {\n  threshold: 0 \/\/ 1px\u3067\u3082\u8868\u793a\u3055\u308c\u305f\u3089\u691c\u77e5\n});\n\n\/\/ canvas\u8981\u7d20\u3092\u76e3\u8996\nobserver.observe(container);\n\n\/\/ \u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u30eb\u30fc\u30d7\nfunction animate() {\n  requestAnimationFrame(animate);\n\n  \/\/ \u8868\u793a\u3055\u308c\u3066\u3044\u308b\u6642\u306e\u307f\u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\n  if (isVisible) {\n    currentScrollY = lerp(currentScrollY, scrollY, 0.08);\n\n    cube.rotation.y = currentScrollY * 0.001;\n    cube.position.y = -currentScrollY * 0.5;\n\n    renderer.render(scene, camera);\n  }\n}\n\nanimate();<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. \u30dd\u30ea\u30b4\u30f3\u6570\u306e\u524a\u6e1b<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \u274c \u60aa\u3044\u4f8b\uff1a\u9ad8\u30dd\u30ea\u30b4\u30f3\nconst highPolyGeometry = new THREE.SphereGeometry(100, 128, 128); \/\/ 16,384\u9762\n\n\/\/ \u2705 \u826f\u3044\u4f8b\uff1a\u4f4e\u30dd\u30ea\u30b4\u30f3\nconst lowPolyGeometry = new THREE.SphereGeometry(100, 32, 32); \/\/ 2,048\u9762\n\n\/\/ \u898b\u305f\u76ee\u306e\u5dee\u306f\u307b\u3068\u3093\u3069\u306a\u3044\u304c\u3001\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u306f8\u500d\u5411\u4e0a<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2. \u63cf\u753b\u8ca0\u8377\u306e\u8efd\u6e1b<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Frustum Culling\uff08\u8996\u754c\u5916\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306f\u63cf\u753b\u3057\u306a\u3044\uff09\n\/\/ Three.js\u306f\u81ea\u52d5\u3067\u884c\u3046\u304c\u3001\u624b\u52d5\u3067\u5236\u5fa1\u3082\u53ef\u80fd\nmesh.frustumCulled = true; \/\/ \u30c7\u30d5\u30a9\u30eb\u30c8\u306ftrue\n\n\/\/ Level of Detail\uff08LOD\uff09\u306e\u6d3b\u7528\nconst lod = new THREE.LOD();\n\n\/\/ \u8fd1\u8ddd\u96e2\u7528\uff08\u9ad8\u30dd\u30ea\u30b4\u30f3\uff09\nconst highDetail = new THREE.Mesh(\n  new THREE.SphereGeometry(100, 64, 64),\n  material\n);\nlod.addLevel(highDetail, 0);\n\n\/\/ \u4e2d\u8ddd\u96e2\u7528\uff08\u4e2d\u30dd\u30ea\u30b4\u30f3\uff09\nconst mediumDetail = new THREE.Mesh(\n  new THREE.SphereGeometry(100, 32, 32),\n  material\n);\nlod.addLevel(mediumDetail, 300);\n\n\/\/ \u9060\u8ddd\u96e2\u7528\uff08\u4f4e\u30dd\u30ea\u30b4\u30f3\uff09\nconst lowDetail = new THREE.Mesh(\n  new THREE.SphereGeometry(100, 16, 16),\n  material\n);\nlod.addLevel(lowDetail, 600);\n\nscene.add(lod);<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">3. \u30c6\u30af\u30b9\u30c1\u30e3\u306e\u6700\u9069\u5316<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \u30c6\u30af\u30b9\u30c1\u30e3\u306e\u30b5\u30a4\u30ba\u306f2\u306e\u3079\u304d\u4e57\uff08256, 512, 1024, 2048...\uff09\nconst textureLoader = new THREE.TextureLoader();\nconst texture = textureLoader.load('texture.jpg');\n\n\/\/ \u30df\u30c3\u30d7\u30de\u30c3\u30d7\u3092\u6709\u52b9\u5316\uff08\u30c7\u30d5\u30a9\u30eb\u30c8\u3067\u6709\u52b9\uff09\ntexture.generateMipmaps = true;\n\n\/\/ \u7570\u65b9\u6027\u30d5\u30a3\u30eb\u30bf\u30ea\u30f3\u30b0\uff08\u54c1\u8cea\u5411\u4e0a\uff09\ntexture.anisotropy = renderer.capabilities.getMaxAnisotropy();\n\n\/\/ \u30e2\u30d0\u30a4\u30eb\u7528\u306b\u306f\u4f4e\u89e3\u50cf\u5ea6\u30c6\u30af\u30b9\u30c1\u30e3\u3092\u4f7f\u7528\nconst isMobile = \/iPhone|iPad|iPod|Android\/i.test(navigator.userAgent);\nconst texturePath = isMobile ? 'texture-512.jpg' : 'texture-2048.jpg';<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">4. \u30e1\u30e2\u30ea\u30ea\u30fc\u30af\u306e\u9632\u6b62<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \u30da\u30fc\u30b8\u96e2\u8131\u6642\u3084\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u30a2\u30f3\u30de\u30a6\u30f3\u30c8\u6642\u306b\u30af\u30ea\u30fc\u30f3\u30a2\u30c3\u30d7\nfunction cleanup() {\n  \/\/ \u30b8\u30aa\u30e1\u30c8\u30ea\u306e\u7834\u68c4\n  geometry.dispose();\n\n  \/\/ \u30de\u30c6\u30ea\u30a2\u30eb\u306e\u7834\u68c4\n  material.dispose();\n\n  \/\/ \u30c6\u30af\u30b9\u30c1\u30e3\u306e\u7834\u68c4\n  if (material.map) material.map.dispose();\n\n  \/\/ \u30ec\u30f3\u30c0\u30e9\u30fc\u306e\u7834\u68c4\n  renderer.dispose();\n\n  \/\/ \u30a4\u30d9\u30f3\u30c8\u30ea\u30b9\u30ca\u30fc\u306e\u524a\u9664\n  window.removeEventListener('scroll', handleScroll);\n  window.removeEventListener('resize', handleResize);\n}\n\n\/\/ React\u306e\u5834\u5408\nuseEffect(() => {\n  \/\/ \u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u51e6\u7406...\n\n  return () => {\n    cleanup();\n  };\n}, []);<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u5916\u90e8\u30e9\u30a4\u30d6\u30e9\u30ea\u3068\u306e\u9023\u643a<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">GSAP \u3068\u306e\u7d44\u307f\u5408\u308f\u305b<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ GSAP\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\n\/\/ npm install gsap\n\nimport gsap from 'gsap';\nimport { ScrollTrigger } from 'gsap\/ScrollTrigger';\n\ngsap.registerPlugin(ScrollTrigger);\n\n\/\/ \u30b9\u30af\u30ed\u30fc\u30eb\u30c8\u30ea\u30ac\u30fc\u3067\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\ngsap.to(cube.rotation, {\n  y: Math.PI * 2,\n  x: Math.PI,\n  scrollTrigger: {\n    trigger: '#section1',\n    start: 'top top',\n    end: 'bottom top',\n    scrub: true, \/\/ \u30b9\u30af\u30ed\u30fc\u30eb\u306b\u540c\u671f\n    markers: true \/\/ \u30c7\u30d0\u30c3\u30b0\u7528\u30de\u30fc\u30ab\u30fc\uff08\u672c\u756a\u3067\u306f\u524a\u9664\uff09\n  }\n});\n\n\/\/ \u8907\u6570\u306e\u30d7\u30ed\u30d1\u30c6\u30a3\u3092\u540c\u6642\u306b\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\ngsap.to(cube.position, {\n  x: 200,\n  y: -500,\n  scrollTrigger: {\n    trigger: '#section2',\n    start: 'top center',\n    end: 'bottom center',\n    scrub: 1 \/\/ \u30b9\u30af\u30ed\u30fc\u30eb\u306b1\u79d2\u306e\u9045\u5ef6\n  }\n});\n\n\/\/ \u8272\u306e\u5909\u5316\ngsap.to(cube.material.color, {\n  r: 1,\n  g: 0,\n  b: 0,\n  scrollTrigger: {\n    trigger: '#section3',\n    start: 'top bottom',\n    end: 'center center',\n    scrub: true\n  }\n});<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Lenis\uff08\u30b9\u30e0\u30fc\u30b9\u30b9\u30af\u30ed\u30fc\u30eb\uff09\u3068\u306e\u7d44\u307f\u5408\u308f\u305b<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Lenis\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\n\/\/ npm install @studio-freight\/lenis\n\nimport Lenis from '@studio-freight\/lenis';\n\n\/\/ Lenis\u306e\u521d\u671f\u5316\nconst lenis = new Lenis({\n  duration: 1.2,\n  easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),\n  smooth: true\n});\n\n\/\/ \u30b9\u30af\u30ed\u30fc\u30eb\u30a4\u30d9\u30f3\u30c8\u3092\u76e3\u8996\nlenis.on('scroll', (e) => {\n  scrollY = e.scroll;\n});\n\n\/\/ \u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u30eb\u30fc\u30d7\u306b\u7d71\u5408\nfunction animate(time) {\n  requestAnimationFrame(animate);\n\n  lenis.raf(time);\n\n  currentScrollY = lerp(currentScrollY, scrollY, 0.08);\n\n  cube.rotation.y = currentScrollY * 0.001;\n  cube.position.y = -currentScrollY * 0.5;\n\n  renderer.render(scene, camera);\n}\n\nanimate();<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u5b9f\u8df5\u4f8b\uff1a\u5b8c\u5168\u306a\u30d7\u30ed\u30b8\u30a7\u30af\u30c8<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u3053\u308c\u307e\u3067\u306e\u77e5\u8b58\u3092\u7d71\u5408\u3057\u305f\u5b8c\u5168\u306a\u5b9f\u88c5\u4f8b\u3067\u3059\u3002\u30af\u30e9\u30b9\u30d9\u30fc\u30b9\u3067\u6574\u7406\u3059\u308b\u3053\u3068\u3067\u3001\u4fdd\u5b88\u6027\u304c\u9ad8\u307e\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ main.js - \u5b8c\u5168\u7248\nimport * as THREE from 'three';\n\nclass ScrollAnimation {\n  constructor() {\n    this.scrollY = 0;\n    this.currentScrollY = 0;\n    this.isVisible = true;\n\n    this.init();\n    this.createObjects();\n    this.setupEventListeners();\n    this.animate();\n  }\n\n  init() {\n    \/\/ \u30b7\u30fc\u30f3\n    this.scene = new THREE.Scene();\n    this.scene.background = new THREE.Color(0x000000);\n\n    \/\/ \u30ab\u30e1\u30e9\n    this.fov = 45;\n    this.camera = new THREE.PerspectiveCamera(\n      this.fov,\n      window.innerWidth \/ window.innerHeight,\n      0.1,\n      10000\n    );\n    this.updateCameraPosition();\n\n    \/\/ \u30ec\u30f3\u30c0\u30e9\u30fc\n    this.renderer = new THREE.WebGLRenderer({\n      antialias: true,\n      alpha: true\n    });\n    this.renderer.setSize(window.innerWidth, window.innerHeight);\n    this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));\n\n    const container = document.getElementById('canvas-container');\n    container.appendChild(this.renderer.domElement);\n\n    \/\/ \u30e9\u30a4\u30c8\n    const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);\n    this.scene.add(ambientLight);\n\n    const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);\n    directionalLight.position.set(5, 5, 5);\n    this.scene.add(directionalLight);\n  }\n\n  updateCameraPosition() {\n    const fovRad = (this.fov * Math.PI) \/ 180;\n    const distance = window.innerHeight \/ (2 * Math.tan(fovRad \/ 2));\n    this.camera.position.z = distance;\n  }\n\n  createObjects() {\n    this.objects = [];\n\n    \/\/ \u80cc\u666f\u306e\u7403\u4f53\n    const bgGeometry = new THREE.SphereGeometry(150, 32, 32);\n    const bgMaterial = new THREE.MeshStandardMaterial({\n      color: 0x3366ff,\n      metalness: 0.3,\n      roughness: 0.7\n    });\n    const bgSphere = new THREE.Mesh(bgGeometry, bgMaterial);\n    bgSphere.position.z = -400;\n    this.scene.add(bgSphere);\n    this.objects.push({ mesh: bgSphere, speed: 0.2, rotationSpeed: 0.0002 });\n\n    \/\/ \u30e1\u30a4\u30f3\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\n    const mainGeometry = new THREE.TorusKnotGeometry(80, 25, 128, 16);\n    const mainMaterial = new THREE.MeshStandardMaterial({\n      color: 0xff6600,\n      metalness: 0.5,\n      roughness: 0.5\n    });\n    const mainMesh = new THREE.Mesh(mainGeometry, mainMaterial);\n    this.scene.add(mainMesh);\n    this.objects.push({ mesh: mainMesh, speed: 0.6, rotationSpeed: 0.0008 });\n\n    \/\/ \u524d\u666f\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\n    const fgGeometry = new THREE.OctahedronGeometry(60);\n    const fgMaterial = new THREE.MeshStandardMaterial({\n      color: 0xff0066,\n      metalness: 0.7,\n      roughness: 0.3,\n      wireframe: true\n    });\n    const fgMesh = new THREE.Mesh(fgGeometry, fgMaterial);\n    fgMesh.position.z = 100;\n    this.scene.add(fgMesh);\n    this.objects.push({ mesh: fgMesh, speed: 1.0, rotationSpeed: 0.0012 });\n  }\n\n  setupEventListeners() {\n    \/\/ \u30b9\u30af\u30ed\u30fc\u30eb\u30a4\u30d9\u30f3\u30c8\n    window.addEventListener('scroll', () => {\n      this.scrollY = window.pageYOffset;\n    });\n\n    \/\/ \u30ea\u30b5\u30a4\u30ba\u30a4\u30d9\u30f3\u30c8\n    window.addEventListener('resize', () => {\n      this.camera.aspect = window.innerWidth \/ window.innerHeight;\n      this.updateCameraPosition();\n      this.camera.updateProjectionMatrix();\n\n      this.renderer.setSize(window.innerWidth, window.innerHeight);\n      this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));\n    });\n\n    \/\/ Intersection Observer\n    const observer = new IntersectionObserver((entries) => {\n      entries.forEach(entry => {\n        this.isVisible = entry.isIntersecting;\n      });\n    }, { threshold: 0 });\n\n    observer.observe(this.renderer.domElement);\n  }\n\n  lerp(start, end, factor) {\n    return start + (end - start) * factor;\n  }\n\n  animate() {\n    requestAnimationFrame(() => this.animate());\n\n    if (!this.isVisible) return;\n\n    \/\/ \u30b9\u30af\u30ed\u30fc\u30eb\u306e\u6163\u6027\u52b9\u679c\n    this.currentScrollY = this.lerp(this.currentScrollY, this.scrollY, 0.08);\n\n    \/\/ \u5404\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u66f4\u65b0\n    this.objects.forEach(({ mesh, speed, rotationSpeed }) => {\n      mesh.position.y = -this.currentScrollY * speed;\n      mesh.rotation.y += rotationSpeed * 60; \/\/ 60fps\u60f3\u5b9a\n      mesh.rotation.x = this.currentScrollY * 0.0003 * speed;\n    });\n\n    this.renderer.render(this.scene, this.camera);\n  }\n\n  \/\/ \u30af\u30ea\u30fc\u30f3\u30a2\u30c3\u30d7\u30e1\u30bd\u30c3\u30c9\n  dispose() {\n    window.removeEventListener('scroll', this.handleScroll);\n    window.removeEventListener('resize', this.handleResize);\n\n    this.objects.forEach(({ mesh }) => {\n      mesh.geometry.dispose();\n      mesh.material.dispose();\n    });\n\n    this.renderer.dispose();\n  }\n}\n\n\/\/ \u521d\u671f\u5316\nconst scrollAnimation = new ScrollAnimation();<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n<div class=\"swell-block-balloon\"><div class=\"c-balloon -bln-left\" data-col=\"gray\"><div class=\"c-balloon__icon -square\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/withcode.tech\/media\/wp-content\/uploads\/2025\/06\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2025-06-15-15.06.05.jpg\" alt=\"\" class=\"c-balloon__iconImg\" width=\"80px\" height=\"80px\"><span class=\"c-balloon__iconName\">\u751f\u5f92<\/span><\/div><div class=\"c-balloon__body -speaking -border-none\"><div class=\"c-balloon__text\">\n<p><strong>Three.js\u3067\u30b9\u30af\u30ed\u30fc\u30eb\u9023\u52d5\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u3001\u3060\u3044\u3076\u308f\u304b\u3063\u3066\u304d\u307e\u3057\u305f\uff01<\/strong><\/p>\n<span class=\"c-balloon__shapes\"><span class=\"c-balloon__before\"><\/span><span class=\"c-balloon__after\"><\/span><\/span><\/div><\/div><\/div><\/div>\n\n<div class=\"swell-block-balloon\"><div class=\"c-balloon -bln-right\" data-col=\"gray\"><div class=\"c-balloon__icon -square\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/withcode.tech\/media\/wp-content\/uploads\/2025\/06\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2025-06-15-15.12.07.jpg\" alt=\"\" class=\"c-balloon__iconImg\" width=\"80px\" height=\"80px\"><span class=\"c-balloon__iconName\">\u30da\u30f3\u535a\u58eb<\/span><\/div><div class=\"c-balloon__body -speaking -border-none\"><div class=\"c-balloon__text\">\n<p><strong>\u305d\u306e\u8abf\u5b50\u3058\u3083\uff01\u307e\u305a\u306f\u30b7\u30f3\u30d7\u30eb\u306a\u5b9f\u88c5\u304b\u3089\u59cb\u3081\u3066\u3001\u5f90\u3005\u306b\u6163\u6027\u52b9\u679c\u3084\u30d1\u30e9\u30e9\u30c3\u30af\u30b9\u3092\u8ffd\u52a0\u3057\u3066\u3044\u304f\u3068\u826f\u3044\u305e\u3002\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u306b\u3082\u6c17\u3092\u914d\u308b\u3053\u3068\u3092\u5fd8\u308c\u305a\u306b\u306a\uff01<\/strong><\/p>\n<span class=\"c-balloon__shapes\"><span class=\"c-balloon__before\"><\/span><span class=\"c-balloon__after\"><\/span><\/span><\/div><\/div><\/div><\/div>\n\n<div class=\"swell-block-balloon\"><div class=\"c-balloon -bln-left\" data-col=\"gray\"><div class=\"c-balloon__icon -square\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/withcode.tech\/media\/wp-content\/uploads\/2025\/06\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2025-06-15-14.48.08.jpg\" alt=\"\" class=\"c-balloon__iconImg\" width=\"80px\" height=\"80px\"><span class=\"c-balloon__iconName\">\u751f\u5f92<\/span><\/div><div class=\"c-balloon__body -speaking -border-none\"><div class=\"c-balloon__text\">\n<p><strong>\u308f\u304b\u308a\u307e\u3057\u305f\uff01\u65e9\u901f\u81ea\u5206\u306e\u30dd\u30fc\u30c8\u30d5\u30a9\u30ea\u30aa\u30b5\u30a4\u30c8\u306b\u5b9f\u88c5\u3057\u3066\u307f\u307e\u3059\uff01<\/strong><\/p>\n<span class=\"c-balloon__shapes\"><span class=\"c-balloon__before\"><\/span><span class=\"c-balloon__after\"><\/span><\/span><\/div><\/div><\/div><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u3088\u304f\u3042\u308b\u8cea\u554f<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Three.js \u306f\u30e2\u30d0\u30a4\u30eb\u3067\u3082\u52d5\u4f5c\u3057\u307e\u3059\u304b\uff1f<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u52d5\u4f5c\u3057\u307e\u3059\u304c\u3001\u30e2\u30d0\u30a4\u30eb\u306f GPU \u30d1\u30ef\u30fc\u304c\u9650\u3089\u308c\u308b\u305f\u3081\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u304c\u5fc5\u9808\u3067\u3059\u3002\u30dd\u30ea\u30b4\u30f3\u6570\u3092\u4f4e\u304f\u6291\u3048\u3001\u30c6\u30af\u30b9\u30c1\u30e3\u3092\u4f4e\u89e3\u50cf\u5ea6\uff08512px \u4ee5\u4e0b\uff09\u306b\u3057\u3001<code>renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))<\/code> \u3067 Retina \u5bfe\u5fdc\u3057\u3064\u3064\u8ca0\u8377\u3092\u5236\u9650\u3057\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Three.js \u3068 GSAP \u306f\u3069\u3061\u3089\u3092\u30b9\u30af\u30ed\u30fc\u30eb\u5236\u5fa1\u306b\u4f7f\u3048\u3070\u3044\u3044\u3067\u3059\u304b\uff1f<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u30b7\u30f3\u30d7\u30eb\u306a\u30b9\u30af\u30ed\u30fc\u30eb\u9023\u52d5\u306a\u3089\u751f\u306e scroll \u30a4\u30d9\u30f3\u30c8\uff0bLerp \u3067\u5341\u5206\u3067\u3059\u3002\u30bb\u30af\u30b7\u30e7\u30f3\u3054\u3068\u306b\u8907\u96d1\u306a\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u3092\u7d44\u307f\u305f\u3044\u5834\u5408\u306f GSAP ScrollTrigger \u304c\u9069\u3057\u3066\u3044\u307e\u3059\u3002Lenis \u306f\u30b9\u30e0\u30fc\u30b9\u30b9\u30af\u30ed\u30fc\u30eb\u81ea\u4f53\u3092\u5236\u5fa1\u3059\u308b\u30e9\u30a4\u30d6\u30e9\u30ea\u306a\u306e\u3067\u3001Three.js \u3084 GSAP \u3068\u7d44\u307f\u5408\u308f\u305b\u3066\u4f7f\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">React\u30fbNext.js \u3067\u3082\u4f7f\u3048\u307e\u3059\u304b\uff1f<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u4f7f\u3048\u307e\u3059\u3002\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306e\u30de\u30a6\u30f3\u30c8\u6642\u306b Three.js \u306e\u521d\u671f\u5316\u3092\u884c\u3044\u3001\u30a2\u30f3\u30de\u30a6\u30f3\u30c8\u6642\u306b <code>dispose()<\/code> \u3067\u30af\u30ea\u30fc\u30f3\u30a2\u30c3\u30d7\u3059\u308b\u306e\u304c\u57fa\u672c\u30d1\u30bf\u30fc\u30f3\u3067\u3059\u3002React Three Fiber\uff08@react-three\/fiber\uff09\u3092\u4f7f\u3046\u3068\u3001Three.js \u3092 React \u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3068\u3057\u3066\u5ba3\u8a00\u7684\u306b\u8a18\u8ff0\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lerp \u306e factor \u5024\u306f\u3069\u3046\u6c7a\u3081\u308c\u3070\u3044\u3044\u3067\u3059\u304b\uff1f<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">0.05\u301c0.15 \u306e\u7bc4\u56f2\u304c\u4e00\u822c\u7684\u3067\u3059\u30020.05 \u306f\u304b\u306a\u308a\u3086\u3063\u304f\u308a\u3057\u305f\u8ffd\u5f93\u30010.15 \u306f\u307b\u307c\u5373\u6642\u306b\u8fd1\u3044\u52d5\u304d\u306b\u306a\u308a\u307e\u3059\u3002\u30e6\u30fc\u30b6\u30fc\u304c\u5feb\u9069\u306b\u611f\u3058\u308b\u9045\u5ef6\u306f 0.07\u301c0.10 \u7a0b\u5ea6\u304c\u591a\u3044\u3067\u3059\u304c\u3001\u6f14\u51fa\u610f\u56f3\u306b\u3088\u3063\u3066\u8abf\u6574\u3057\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u30d5\u30ec\u30fc\u30e0\u30ec\u30fc\u30c8\u3092 60fps \u306b\u56fa\u5b9a\u3057\u305f\u3044\u5834\u5408\u306f\u3069\u3046\u3057\u307e\u3059\u304b\uff1f<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">requestAnimationFrame \u306f\u74b0\u5883\u306b\u3088\u3063\u3066 120fps \u4ee5\u4e0a\u3067\u52d5\u4f5c\u3059\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002<code>clock.getDelta()<\/code> \u3067\u7d4c\u904e\u6642\u9593\u3092\u53d6\u5f97\u3057\u3001\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u91cf\u3092\u6642\u9593\u30d9\u30fc\u30b9\u3067\u8a08\u7b97\u3059\u308b\u304b\u3001<code>renderer.setAnimationLoop()<\/code> \u3092\u5229\u7528\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u30d5\u30ec\u30fc\u30e0\u30ec\u30fc\u30c8\u306b\u4f9d\u5b58\u3057\u306a\u3044\u5b9f\u88c5\u306b\u3059\u308b\u3053\u3068\u3067\u3001\u9ad8\u30ea\u30d5\u30ec\u30c3\u30b7\u30e5\u30ec\u30fc\u30c8\u7aef\u672b\u3067\u3082\u610f\u56f3\u3057\u305f\u901f\u5ea6\u3067\u52d5\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u307e\u3068\u3081<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u672c\u8a18\u4e8b\u3067\u306f\u3001Three.js \u3092\u4f7f\u3063\u305f\u30b9\u30af\u30ed\u30fc\u30eb\u9023\u52d5\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u306e\u5b9f\u88c5\u65b9\u6cd5\u3092\u57fa\u790e\u304b\u3089\u5fdc\u7528\u307e\u3067\u89e3\u8aac\u3057\u307e\u3057\u305f\u3002<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u57fa\u672c\u69cb\u6210<\/strong>\uff1aScene\u30fbCamera\u30fbRenderer\u30fbMesh \u306e4\u8981\u7d20\u304c\u57fa\u672c<\/li>\n<li><strong>\u30b9\u30af\u30ed\u30fc\u30eb\u9023\u52d5<\/strong>\uff1a\u30b9\u30af\u30ed\u30fc\u30eb\u91cf\u3092 3D \u5ea7\u6a19\u3084\u56de\u8ee2\u306b\u9069\u7528\u3059\u308b<\/li>\n<li><strong>\u30ab\u30e1\u30e9\u6700\u9069\u5316<\/strong>\uff1a\u8996\u91ce\u89d2\u304b\u3089\u6700\u9069\u306a\u30ab\u30e1\u30e9\u8ddd\u96e2\u3092\u8a08\u7b97\u3057\u3066\u5ea7\u6a191\u5358\u4f4d = 1px \u3092\u5b9f\u73fe<\/li>\n<li><strong>\u6163\u6027\u52b9\u679c<\/strong>\uff1a\u7dda\u5f62\u88dc\u9593\uff08Lerp\uff09\u3067\u6ed1\u3089\u304b\u306a\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u73fe<\/li>\n<li><strong>\u30d1\u30e9\u30e9\u30c3\u30af\u30b9<\/strong>\uff1a\u8907\u6570\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092\u7570\u306a\u308b\u901f\u5ea6\u3067\u52d5\u304b\u3057\u3066\u5965\u884c\u304d\u611f\u3092\u6f14\u51fa<\/li>\n<li><strong>\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9<\/strong>\uff1a\u30dd\u30ea\u30b4\u30f3\u6570\u524a\u6e1b\u30fbLOD\u30fbIntersection Observer \u3067\u30b9\u30e0\u30fc\u30ba\u306b\u52d5\u4f5c\u3055\u305b\u308b<\/li>\n<li><strong>\u5916\u90e8\u30e9\u30a4\u30d6\u30e9\u30ea<\/strong>\uff1aGSAP \u3084 Lenis \u3068\u306e\u9023\u643a\u3067\u3088\u308a\u9ad8\u5ea6\u306a\u8868\u73fe\u304c\u53ef\u80fd<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><span class=\"swl-marker mark_yellow\">WithCode \u3067\u5b66\u3093\u3060 Web \u5236\u4f5c\u306e\u57fa\u790e\u77e5\u8b58\u306b Three.js \u306e 3D \u6280\u8853\u3092\u7d44\u307f\u5408\u308f\u305b\u308c\u3070\u3001\u5370\u8c61\u7684\u3067\u30a4\u30f3\u30bf\u30e9\u30af\u30c6\u30a3\u30d6\u306a Web \u30b5\u30a4\u30c8\u3092\u69cb\u7bc9\u3067\u304d\u307e\u3059\u3002<\/span><\/strong>\u307e\u305a\u306f\u30b7\u30f3\u30d7\u30eb\u306a\u5b9f\u88c5\u304b\u3089\u59cb\u3081\u3066\u3001\u5f90\u3005\u306b\u9ad8\u5ea6\u306a\u30c6\u30af\u30cb\u30c3\u30af\u3092\u53d6\u308a\u5165\u308c\u3066\u3044\u304d\u307e\u3057\u3087\u3046\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">WithCode\u3092\u4f53\u9a13\u3067\u304d\u308b\u521d\u7d1a\u30b3\u30fc\u30b9\u516c\u958b\u4e2d\uff01<\/h2>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"alignleft size-full\"><img decoding=\"async\" src=\"https:\/\/withcode.tech\/media\/wp-content\/uploads\/2024\/01\/withcode-beginner-course.jpg\" alt=\"WithCode\u521d\u7d1a\u30b3\u30fc\u30b9\" class=\"wp-image-12345\"\/><\/figure>\n<\/div>\n\n\n<h3 class=\"wp-block-heading\">\u521d\u7d1a\u30b3\u30fc\u30b9\uff08\u00a549,800\uff09\u304c\u5b8c\u5168\u7121\u6599\u306b\uff01<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u671f\u9593\uff1a<\/strong>1\u9031\u9593<\/li>\n<li><strong>\u5b66\u7fd2\u5185\u5bb9\uff1a<\/strong>\u30ed\u30fc\u30c9\u30de\u30c3\u30d7\/\u57fa\u790e\u77e5\u8b58\/\u74b0\u5883\u69cb\u7bc9\/HTML\/CSS\/LP\u30fb\u30dd\u30fc\u30c8\u30d5\u30a9\u30ea\u30aa\u4f5c\u6210<br><strong><span class=\"swl-marker mark_yellow\">\u2192 \u6b63\u3057\u3044\u5b66\u7fd2\u65b9\u6cd5\u3067\u300c\u78ba\u304b\u306a\u6210\u9577\u300d\u3092\u5b9f\u611f\u3067\u304d\u308b\u30ab\u30ea\u30ad\u30e5\u30e9\u30e0<\/span><\/strong><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u526f\u696d\u30fb\u30d5\u30ea\u30fc\u30e9\u30f3\u30b9\u304c\u4e3b\u6d41\u306b\u306a\u3063\u3066\u3044\u308b\u4eca\u3053\u305d\u3001\u81ea\u3089\u306e\u30b9\u30ad\u30eb\u3067\u7a3c\u3052\u308b\u4eba\u6750\u3092\u76ee\u6307\u3057\u3066\u307f\u307e\u305b\u3093\u304b\uff1f<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u672a\u7d4c\u9a13\u3067\u3082\u5fc3\u914d\u3059\u308b\u3053\u3068\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u521d\u7d1a\u30b3\u30fc\u30b9\u3092\u53d7\u8b1b\u3055\u308c\u308b\u65b9\u306e\u5927\u591a\u6570\u306f\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u672a\u7d4c\u9a13\u3067\u3059\u3002\u307e\u305a\u306f\u7121\u6599\u30ab\u30a6\u30f3\u30bb\u30ea\u30f3\u30b0\u3067\u3001\u60a9\u307f\u3084\u4e0d\u5b89\u3092\u304a\u805e\u304b\u305b\u304f\u3060\u3055\u3044\uff01<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link has-white-color has-text-color has-background has-link-color wp-element-button\" href=\"https:\/\/withcode.tech\/reservation\/\" style=\"background-color:#ffbf00\"><strong>\u516c\u5f0f\u30b5\u30a4\u30c8\u304b\u3089\u7121\u6599\u30ab\u30a6\u30f3\u30bb\u30ea\u30f3\u30b0\u306b\u7533\u3057\u8fbc\u3080 \u2192<\/strong><\/a><\/div>\n<\/div>\n\n","protected":false},"excerpt":{"rendered":"<p>Three.js\u3067\u30b9\u30af\u30ed\u30fc\u30eb\u9023\u52d53D\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u88c5\u3059\u308b\u65b9\u6cd5\u3092\u57fa\u790e\u304b\u3089\u89e3\u8aac\u3002Lerp\u6163\u6027\u52b9\u679c\u30fb\u30d1\u30e9\u30e9\u30c3\u30af\u30b9\u30fb\u30bb\u30af\u30b7\u30e7\u30f3\u5225\u30a2\u30cb\u30e1\u30fc\u30b7\u30e7\u30f3\u30fbGSAP\u9023\u643a\u307e\u3067\u3001\u30b3\u30fc\u30c9\u4f8b\u4ed8\u304d\u3067\u5fb9\u5e95\u30ac\u30a4\u30c9\u3057\u307e\u3059\u3002<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"swell_btn_cv_data":"","footnotes":"","vk-ltc-link":"","vk-ltc-target":"0"},"categories":[34,359],"tags":[],"class_list":["post-12626","post","type-post","status-publish","format-standard","hentry","category-programming","category-javascript-programming"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/posts\/12626","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/comments?post=12626"}],"version-history":[{"count":2,"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/posts\/12626\/revisions"}],"predecessor-version":[{"id":13992,"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/posts\/12626\/revisions\/13992"}],"wp:attachment":[{"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/media?parent=12626"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/categories?post=12626"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/tags?post=12626"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}