{"id":27040019,"url":"https://github.com/rimkomatic/threejswithgsap","last_synced_at":"2025-08-24T10:13:17.675Z","repository":{"id":213094267,"uuid":"732749241","full_name":"Rimkomatic/ThreeJsWithGsap","owner":"Rimkomatic","description":null,"archived":false,"fork":false,"pushed_at":"2023-12-18T11:15:12.000Z","size":1942,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2023-12-26T05:35:18.158Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Rimkomatic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2023-12-17T17:50:32.000Z","updated_at":"2023-12-18T10:14:04.000Z","dependencies_parsed_at":"2023-12-18T12:44:49.922Z","dependency_job_id":null,"html_url":"https://github.com/Rimkomatic/ThreeJsWithGsap","commit_stats":null,"previous_names":["w41k3r0/threejswithgsap","rimkomatic/threejswithgsap"],"tags_count":0,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rimkomatic%2FThreeJsWithGsap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rimkomatic%2FThreeJsWithGsap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rimkomatic%2FThreeJsWithGsap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rimkomatic%2FThreeJsWithGsap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Rimkomatic","download_url":"https://codeload.github.com/Rimkomatic/ThreeJsWithGsap/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247284932,"owners_count":20913690,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-04-05T03:27:35.283Z","updated_at":"2025-04-05T03:27:35.739Z","avatar_url":"https://github.com/Rimkomatic.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Links Needed For the Project\n\n1. [SketchLab](https://sketchfab.com/)\n2. [Pixotronix](https://webgi.pixotronics.com/)\n\n## Setting Up the Template\n\nFirst Run\n```shell\nnpm install\n```\nNow Use \n```shell\nnpm run dev\n```\nto run the local server made with `webpack` . The website will be visible in this  [localhost:5173](http://localhost:5173/index.html) \nfor testing the development.\n\n\n### Replacing the 3d model\n\nReplace the model in the path `/assets` \nThen add the correct path to `load` in the **`index.ts`** file.Modify the following line\n```ts\nawait viewer.load(\"./assets/scene.glb\")\n```\n\n\u003e Run the system to see if everything is working as expected or not\n\n## Resizing the webgl component\n\nAs you can see the render is not properly covering the entire webpage as we expect. So do some changes in `style.css` .\n\n- change the height and width to 100 vh and vw respectively, in the `webgi-canvas-container`\n- Remove the padding , margin , box-shadow and border radius as well.\n- Add a margin and padding of 0 to the body.\n- Remove the overflow hidden to overflow-x hidden.\n\nThe final CSS should look like this \n```css\nbody {\n  font-family: sans-serif;\n  margin: 0;\n  padding: 0;\n  overflow-x:'hidden';\n}\n\n#webgi-canvas {\n  width: 100%;\n  height: 100%;\n}\n\n#webgi-canvas-container{\n  width: 100vw;\n  height: 100vh;\n}\n```\n\n\n\n### Bonus: Want to get rid of the tooltip in the website \nJust remove the `TweakpaneUiPlugin` plugin from the `index.ts` file . And remove this or comment out this\n```ts\nconst uiPlugin = await viewer.addPlugin(TweakpaneUiPlugin)\n// Add plugins to the UI to see their settings.\nuiPlugin.setupPlugins\u003cIViewerPlugin\u003e(TonemapPlugin, CanvasSnipperPlugin)\n```\n\n\n\n\n## Add The HTML and CSS for your Website \n\n\u003eYou can use a  wireframing tool like **figma** or **Abobe Xd** for faster execution .\n\nAdd your font in the `styles.css` if you like.\n\n\n\n### Can not see any changes or any elements in my page\n\nSo this happens due to the weired behavior of webgl or threejs canvas behaviour, you can use \n```css\nposition: 'fixed';\n```\nThis works but you have to keep in mind that the webgl canvas is on top of everything , you can use a z-index, but the **absolute position is must because we want to place the canvas at the center every time** .\nSo much this and that, you can use this css property and it should work fine (in my case I will edit it out if any change is needed).\n```css\n#webgi-canvas {\n  width: 100%;\n  height: 100%;\n  position: fixed;\n  top: 0;\n}\n```\n\n\n\u003e So to make things clear we gotta place the text below the 3d element , but to do that we need the position as well as the transperency of the canvas to see the things behind it clearly.\n\n### Making the canvas transperent\n\nGo to the `index.ts` file, then modify the following code\n```ts\nconst viewer = new ViewerApp({\n\tcanvas: document.getElementById('webgi-canvas') as HTMLCanvasElement,\n    useRgbm:false // add this property\n    })\n```\n\n\n### Scrolling Problem \nAs you can see you can not scroll the website using the default scroll , you can use the up and down arrow to do this, so what we have to do is we have to **disable the pointer events in the canvas** so that the scroll does not trigger the zoom in zoom out thing.\nSo in the `styles.css` modify it like\n```css\n#webgi-canvas-container{\n  width: 100vw;\n  height: 100vh;\n  pointer-events: none; /* add this */ \n}\n```\nYeah, now you can not move the model too, but do not worry about that as we will use gsap for that.\n\n\n## Install GSAP\n\nTo install gsap, we will use this\n```shell\nnpm install gsap\n```\nnow add this line to the ts file after importing the css and other stuff\n```ts\nimport gsap from 'gsap'\n```\nand then import the `ScrollTrigger` plugin\n```ts\nimport { ScrollTrigger } from \"gsap/all\"\n```\nRegister the plugin by \n```ts\ngsap.registerPlugin(ScrollTrigger)\n```\n\n### Set Up the Function for Animation \n\nThe function you can declare **inside** the `setupViewer` function declaration. Something like `setupScrollAnimation` to keep the naming convention. \n\nFor the animation we will need a **timeline** , so we will make one using \n```ts\nconst tl = gsap.timeline()\n```\n\nAt this point we need camera and object access. To do this go under the `AssetManagerPlugin` line\n```ts\nconst manager = await viewer.addPlugin(AssetManagerPlugin)\n```\naccess the camera by\n```ts\nconst camera = viewer.scene.activeCamera\n```\nThis selects the active camera from the scene. Now to get the position of the camera\n```ts\nconst position = camera.position\n```\nWe will be using some kind of control , and to control that we need a target to control. Let us access the target by adding \n```ts\nconst target = camera.target\n```\nSo the final structure of the code after the ``AssetManagerPlugin`` will be\n```ts\nconst camera = viewer.scene.activeCamera\nconst position = camera.position\nconst target = camera.target\n```\n\nNow lets get back to our function, we will change the position of the camera using gsap. \n```ts\n    function setupScrollAnimation()\n    {\n        const tl = gsap.timeline()\n\n        // 1st part\n        tl.to(position , { x: 5 , duration:4})\n    }\n```\nJust a simple one to test , now call the function inside the ``setupViewer`` function (We were already inside that function) . \n\n\n### No animation?\n\nThis happens because we can not directly change ThreeJs property by using gsap directly, we have to use a **WEBGI update function**\nLet's do it like this \n```ts\n    let needsUpdate = true\n    function onUpdate()\n    {\n        needsUpdate = true\n        viewer.renderer.resetShadows()\n    }\n```\nWe have to rerender the entire webGI as we progress.\nNow we need to add a **Hook** in order to see if the trigger for the redender has ended or not.\nDo it like this\n```ts\n    viewer.addEventListener('preFrame' , ()=\u003e{\n        if(needsUpdate)\n        {\n            camera.positionUpdated(false)\n            camera.targetUpdated(true)\n            needsUpdate = false\n        }\n    })\n```\nNow we have to pass the WEBGI update function into the GSAP code or animation function\n```ts\n    function setupScrollAnimation()\n    {\n        const tl = gsap.timeline()\n        // 1st part\n        tl.to(position , { x: 5 , duration:4 , onUpdate}) // \u003c- here\n    }\n```\n\nNow all left is to set up the scrolltrigger part.\n\n```ts\nscrollTrigger:{\n                trigger: '#two', // your second section \n                markers:true, // to see the things better\n                scrub:2 // you can see why\n            } ,\n```\n\n\n\n\n\n\n\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frimkomatic%2Fthreejswithgsap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frimkomatic%2Fthreejswithgsap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frimkomatic%2Fthreejswithgsap/lists"}