Personal Portfolio: Dev
Tags: dohackathon, webdev, vue, gsap
Published: 2021-01-06 20:43:54

Let's talk some tech, finally. 

The last two posts revolved around the inspiration and design for the website, and I'll get deeper into some of the development challenges I met (and conquered!), and more importantly some pitfalls I fell into. 

## Stack: What framework did I use?
Answer: *Vue*

True story: I created a Vue project, deleted it thinking it's overkill for this single page application. Create a new frame-less project. Realized my mistake. Re-created a new Vue project again. And I'm so glad I went back to Vue.

What I initially thought could just be a single large `index.html` file, Vue ensured me that I build modular components and give a proper structure to my codebase, which essentially became significant to manage the different layers and animations I'd decided to add to the portfolio. 

## Animations
The vision that I had with this project involved a lot of animations. And I wanted to work with a library that is proven to be fast, efficient, and small enough. But first, I tried to use the basic CSS animations. It started well, was happy for some time before I accidentally tested the webpage on a Macbook (was originally working on my Windows machine).

![balloons-animated](https://i.imgur.com/aOKfOAw.gif)
<figcaption>Example of the initial animations [Low FPS gif]</figcaption>

While the basic CSS transitions were working fine on my PC, they were slightly lagging on the Mac Chrome browser. Considering, these were just a couple of the animations, I decided to try out a library called [GSAP](https://greensock.com/docs/v3/GSAP) that I had read about previously. I integrated it with my Vue project and replicated the animations with it. 

It worked *flawlessly*. 

## Image Mapping
As you might have seen in my previous [post](https://dev.to/abhinavchawla13/personal-portfolio-design-e18), I had designed a floating island. The island had two distinct features:
1. Floatation: The island had an inherent pulse-animation moving a few pixels up and down. Also, I added a subtle sideways animation on cursor movements over the x-axis.
2. Clickable events: There were multiple objects clickable on the island, that can be seen with a yellow glow. This is where things get tricky.

![floating](https://i.imgur.com/NGstLZ3.gif)
<figcaption>Exemplifying effects discussed in (1) [Low FPS gif]</figcaption>

Let's discuss the second point in more detail. My initial idea was to superimpose individual images for all the events on top of the island image, so it's easier to add an animated glow (unlike the current static glow) and add clickable events. While this sounded reasonable, it ended up being a headache as the island size isn't constant; it's responsive to the size of the screen. Hence, *sizing and positioning* the individual smaller images relative to the main island were too much of a hassle. 

Looking for an alternate, I came across [HTML Image Maps](https://www.w3schools.com/html/html_images_imagemap.asp); to be honest, I had no idea this feature existed, and it was going to make my life a lot easier. Fortunately, I found a great [onlne tool](https://www.image-map.net/) to help me draw down the area boundaries for my map.

![image-map](https://i.imgur.com/2AOp4N0.png)
<figcaption>image-map.net tool</figcaption>


So, all good, I guessed? Well, not really. Image maps work well with absolute fixed-size images but don't resize relatively when the original image's size changes as in my case. After digging around Stackoverflow and trying multiple solutions, hope seemed grim. Until, I found this *magical* package [image-map](https://github.com/clarketm/image-map) which somehow integrated with Vue and automatically readjusted all the area boundaries as the screen size changed. Seriously, this package saved me. 🙏

## Loading
Since this website loads a lot of different assets, I wanted to add a loader (and no, lazy-loading wasn't the solution for this case). So, I need a loader to incrementally progress based on all the assets commutatively. Adding an individual event on each asset seemed like overworking. Another sweet package to the rescue - [vue-images-loaded](https://www.npmjs.com/package/vue-images-loaded); it ran a listener for all the images being downloaded and I could figure out the progress for the loader, and therefore when to close it and show the main content without worrying about assets not being loaded properly.

![loading](https://i.imgur.com/Q9DoghK.gif)
<figcaption>Loading animation [Low FPS gif]</figcaption>

---

That's all for now, I'll be showcasing the final project in the next post. So, stay tuned for it! Feel free to ask any questions you may have about the development process 🤓