Day 003 - #100DaysOfCode
Update
Started a new JavaScript project using ParcelJS based on an older project. This meant I installed parcel-bundler which is at version 1.3.1 or some such and upon doing an npm install I got a whole heap of high secuirty alerts, still it worked. Looking at the docs online I found out that there is a new version 2.7.0 and to install that I needed to npm add --saveDev parcel. That aside, I have an index.html and a src/loading-bar.js which loads and attaches some basic onclick functionality to a button on an HTML page.
https://github.com/saramic/100-days-of-code/tree/main/003_smooth_progress_bar
Adding an animated progress bar
I decided to use the first best search result for “loading bar in pure javascript” and it was a good starting point to create an interval which updated the style.width of an element until it reached 100. After some tweaking I got rid of some variables, reading the value from the bar instead and created some elements on the fly to create the actual progress-bar.
Interestingly I had a //@ts-check typescript check at the top of my file. I beieve this makes Typescript type checking run in VSCode and a few red squiggly lines showed up. Not wanting to install Typescript and allthat jazz I looked up how to add annotations with JS comments and it was pretty simple.
An example below of a method signure that takes a param and returns a HTMLDivElement and another of a querySelector that will later have .disable called on the resultent element so it needs to be an HTMLInputElement. The ... | null was interesting in that it made me deal with the chance that the result is a null and in this case I just don’t make a progress bar
//@ts-check
/**
* @param {HTMLDivElement} progressBarContainer
* @returns {HTMLDivElement}
*/
const setupProgressBar = (progressBarContainer) => {
...
/** @type {HTMLInputElement | null} */
const startJobButton = document.querySelector("button[id=start-job]");That said, as I am using ParcelJS it actually probably would just compile my file if it was a .ts file. I presume this as when I decided to add some scss this just worked (although I did not actually use any scss hmm?)
<link rel="stylesheet" href="style.scss">Progress so far
In Day 002 I got a clunky progress-bar with sidekiq-status gem that is tied to a job. Now in day 003 I have a smooth animated Javascript progress-bar that just smoothly does it’s own thing. Below the blue line is the polled/clunky reloading progress bar and the green one is the smooth Javascript one (any jitter may be due to the limited animated gif framerate to keep the gif to a reasonable size)

At some stage the idea will be to make the Javascript bar poll sidekiq-status and result in a smooth bar.
Next Up
I think tomorrow I will diverge onto something that has interested me for a while and that is using the gem ClosureTree/clsure_tree to work with hierarchical tree data structures in ActiveRecord.
we wil see ¯_(ツ)_/¯
Update 003.1
Might be worth mentioning how I generate the animated gif.
- I first do a screen recording using quickTimePlayer on a mac
- then using
ffmpeg(which I install usingbrew install ffmpeg) - speed up the original
.mov
ffmpeg -i progress.mov -filter:v "setpts=0.5*PTS" progress-fast.mov- analyze the
.movfor colours by creating apalette.pngpallet file
ffmpeg -y -t 10 -i palette-fast.mov \
-vf fps=5,scale=740:-1:flags=lanczos,palettegen \
palette.png- convert the
.movto a.gifusing the palette generated
ffmpeg -i palette-fast.mov \
-i ~/local_documents/palette.png \
-filter_complex "fps=5,scale=740:-1:flags=lanczos[x];[x][1:v]paletteuse" \
smooth-vs-clunky-progress-bar.gifAnd that’s it. I usually play around with the fps=5 the frames per seconds and scale=740 to try and get it down to ~1Mb, in particular as that seems to be the limit of an animated gif that is displayed automatically in Slack without asking users to download it first.