With a desire to update my "about" page, I set out to kill two birds with one stone, a fresh new about page and learning 3d graphics in the browser. https://www.re-tug.com/about/ is built with three.js, a package built within Javascript to make 3d graphics.
About threejs
I followed a tutorial on youtube to create the threejs scene in the background. My code to make the pulsating mesh can be found here. The about page turned out really cool, click and drag on the background and you should be able to rotate the pulsating mesh.
Learning both C# and javascript recently has lead to a lot of mistakes and lost time, but it has been a enjoyable process. Learning how to debug with console.log has become natural at this point.
Trying to tweak the code in the youtube link to my liking lead to some interesting errors, below was my attempt to manually recreate the wireframe pulsating:
Deployment Hell
Through building this website, I have learned that merely getting your code up and running on a development server is usually about 1/4 of the battle. After getting through the tutorial I set out to push this code up to the internet for everyone to see. (I am mostly writing this part so I have something to reference in the future when I am going through deployment pains)
Attempt #1 - Using Script Tags to Load ThreeJS
After some research, it seemed like the easiest and quickest way to get threejs, orbit controls and gsap (the packages used to make the graphics) was through script tags in htlm.
I had something that looked like the following:
<script type="importmap">
{
"imports": {
"three" : "https://unpkg.com/three@0.126.1/build/three.module.js",
"orbitcontrols" : "https://unpkg.com/three@0.126.1/examples/jsm/controls/OrbitControls.js",
"datgui" : "https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.9/dat.gui.min.js"
"gsap" : "https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"
}
}
</script>
<script type="module" src="{% static 'blog/threeBackground.js' %}"></script>
This method relies on cdns (content delivery networks) to deliver the code that is used for threejs, orbit controls etc. I was successfully able to deploy my code with this method, but the code did not work on firefox nor any of the iOS web browsers.
With my whole family and friends using apple products, I had to find a better to make this happen. Apparently script tags are going to be outdated in the future and I think this is why it did not work on firefox and iOS web browsers.
I would get console errors like the following:
At this point I had maybe sunk 20 hours of work into getting this eye candy into the website.
Attempt #2 - Using node.js and NPM
I'll be honest, I still have no idea what node.js and NPM (node package manager) are, but they seemed like the solution to my iOS problems.
My best understanding of these, node.js is a way to write javascript outside of the web browser and NPM is similar to pythons pip command, a way to install packages.
Using node.js and npm, I could see threejs and other modules being downloaded into a folder called node_modules in my file directory. Naively, I thought this was the ticket, I could just reference these files on my production machiene on heroku. This did not work and I spent way too long going down this route.
Attempt #3 - Using Webpack, A Bundler
Webpack is another javascript package that converts the javascript file I linked on my github into a singular javascript file that embeds all of the threejs code and other javascript libraries referenced and places it into one singular file. A sample of the file created by using webpack is shown below:
if(t.applyMatrix3(this.matrix),t.x<0||t.x>1)switch(this.wrapS){case r:t.x=t.x-Math.floor(t.x);break;case a:t.x=t.x<0?0:1;break;case s:1===Math.abs(Math.floor(t.x)%2)?t.x=Math.ceil(t.x)-t.x:t.x=t.x-Math.floor(t.x)}if(t.y<0||t.y>1)switch(this.wrapT){case r:t.y=t.y-Math.floor(t.y);break;case a:t.y=t.y<0?0:1;break;case s:1===Math.abs(Math.floor(t.y)%2)?t.y=Math.ceil(t.y)-t.y:t.y=t.y-Math.floor(t.y)}return this.flip
Lots of gibberish to my eyes...
The command to make this all encompassing file on my development server was: npm run build
This file was the ticket to making the "about" page work on all devices, it no longer requires the html code to have script tags and nor the use of CDNs for the packages like three.js
I had to upload this static file to heroku and serve it up and the rest is history. All total, I think I spent about 10 hours on the actual three.js tutorial part and 40 hours on the deployment aspect of the "about" page. I would like to thank and apologize to my wife for her having to listen me scream, laugh and cry during deployment of this page.
DEPLOYMENT IS TERRIBLE!
Notes on heroku deployment:
- Disable collectstatic by default, have to run:
-
heroku run python manage.py collectstatic
-
- Can ignore double static file reference on deployment
-
heroku defaults to ....\my_website\blog\static
-
- added in gitignore file node_modules
- Within procfile added:
-
web: gunicorn my_website.wsgi npm start
-