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
.mov
for colours by creating apalette.png
pallet file
ffmpeg -y -t 10 -i palette-fast.mov \
-vf fps=5,scale=740:-1:flags=lanczos,palettegen \
palette.png
- convert the
.mov
to a.gif
using 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.gif
And 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.