Learn about the projects I've built by diving into the Toy Chest
Travel through the futuristic Laptop to discover the technologies I can use
Explore in search of the Magical Chest by clicking on any grassland and directing the mage to your cursor
Thanks for taking the time to get to know me and I hope you enjoy your time here!
While I was still in college, the original version of this site had a picture of me as the button that executed the drop-down of the skills menu, but my professor said that it just wasn't intuitive and that I should try putting text into the button. So I changed it from my picture to text that read, "Skill Levels". I then got more feedback that the button had too much text and to try shortening it. I changed it to just read "Skills" and from that point on I hated the way the button looked.
When it came time to remake my website, it was the first thing on the docket. So I had to figure out a visual cue that would suggest the button leads to an area of the page which lists my skills. I ended up deciding to just make a pixel-version of my laptop, with the screen literally showing what the button did when clicked. I loved the process of making pixel art so much that after finding an 8-bit font on Google fonts, I decided to make it the central theme of my new site.
When I started building this site I had already animated objects using CSS before, so I wanted to experiment with the HTML Canvas and with creating animated Gifs that might be able to be used as dynamic animations using timers in JavaScript. I decided to use different techniques for different areas to highlight the risks and rewards of each.
For the Skills menu I used pure JavaScript and I injected the content using PHP. Through JavaScript I was able to adjust the scroll position based upon the height of the text area, allow users to close a menu by clicking anywhere I chose, and it also allowed me to tailor animations through the use of various triggers.
For the Mage and Sparkle animations I used the HTML Canvas and sprite sheets. With those tools I can select specific 'frames' to display, then time them appropriately to give the illusion of character movement without loading multiple images. I can also utilize the same various triggers available in pure JavaScript.
Finally, for the Laptop and Chest animations I made animated Gifs that I switched out using JavaScript timers and triggers. This forced me to load more images, but it was far more gentle on the processor, as compared to the HTML Canvas which ran numerous complex functions dozens of times each second.
I've shared links to my previous projects before, but I wanted to organize them in a more efficient way. So what better way to adhere to the 8-bit theme than to make a treasure chest! I named it 'Toy Chest' to incentivize myself to make more short, playful apps. This way I would have fun learning new tools by building small 'games', but I would also be giving visitors to the site some fun ways to sample what I can build.
To make navigation easier I also decided to include a tooltip at the bottom that would list the technologies used to build the 'toy'. This way a prospective employer could more easily find the type of example project they are looking for.
The Skill bars were one of the first pieces I made for the original version of this site. I had just started exploring CSS and JavaScript animations and I wanted to use the opportunity to practice the techniques while I created a presentational that would communicate the technologies I could use and my confidence levels for each one.
In the 8-bit revision of the site, I liked the difference of the font choices, since this area took you through a laptop and into a more futuristic zone with sharp edges and smooth gradients. For this reason, I decided not to revise this section with the 8-bit theme.
I also noticed that some areas, when clicked, expanded below the screen which led me to explore altering the scroll position based upon the current position and the hieght of the element to be revealed.
While I could have used a game development library like Construct 2, ImpactJS, or Phaser, I wanted to build in Canvas using only vanilla JavaScript and some jQuery (only for selection), this way I could get a better perception on how each task might be actually executed logically inside one of these game development engines. However, by not using an engine I was forced to reinvent the wheel for some tasks.
The only places the parallax issue may be noticed is when the mage walks 'in front' of the chests or the signpost legs. The issue stems from the fact that I've blended techniques on this page to highlight my diversity, but that style means that the z-index that I set in my CSS isn't going to carry over to the Canvas. With Canvas being a single element I can't push or pull the z-index of images drawn inside of it.
I had the idea of making a trigger that changes the z-index of the entire canvas when the image is in the appropriate locations, but during the initial remodel of the site I scrapped the idea due to how minimal the effect would be and how much work would be required to implement it. Perhaps I'll set aside an hour to nail down the effect on another day.
As you might notice, the sparkle in the lower right corner continues to pulse, even after the mage arrives at his destination and stops animating, even though they are both on the same canvas that is being redrawn every X milliseconds. To achieve this, I had to swap which actions were executed every X milliseconds to allow the mage to stand still, and the sparkle to continue.
To tell the canvas which set of actions it should execute, I had to send it triggers that could track which actions are currently happening, and which should stop. If I had to handle any more than 2 pieces I probably would have made a more complex and general handler for the process. But for something this simple, doing things this way works without having to reinvent the wheel too much.
The collision triggers were performed the same way any other collision is detected, by listening for positions and comparing them. The issue came about on screen resize, since I had to re-associate the trigger points. I ended up using the same tracker that I utilized to stop certain animations while continuing others. But if I had to do this multiple times, I would have just made a handler for it.
This was the largest issue when using the HTML Canvas. The main problem stemmed from the fact that the size of the images inside the canvas are determined upon their initialization (before you begin repetatively drawing them so they animate). Because of this, in order to keep their size to the ratio of the window after a window resize, you have to track the size before the resizing event, and after, then adjust accordingly. However, the resizing event happens multiple times, should a user drag a window box to scale the viewer size.
To combat this, I used functions that would track the window size before and after a resize, then reinitialize the canvas. An improvement might be to allow the function to wait, to ensure that the resizing is complete, this way I'm not reinitializing the canvas numerous times in a short period, but for my purposes here the implementation I used works well.
The video that I embedded in the Skills area under the After Effects skill was frequently causing slow page loading when a user would first land on the site. To combat this, I had the idea of replacing the video with an clickable image which would request the video to load when clicked.
Shortly after building testing this functionality I decided that I wanted to capture the thumbnail of the video to serve as the image, this way it would be intuitive what the image would do when clicked. Luckily, I found a dependency that performed all of this for me called LazyYT, built by Tyler Pearson
I designed the Skills area so that you could see a progress bar showing my confidence in a specific skill that when clicked, would expand to show additional information. However, when the information would be shown, it would frequently appear below the page, forcing users to scroll down.
I remedied this issue by implementing an auto-scroll feature that would sense the height of the element to be revealed, then scroll the user up an equivalent height, thus allowing the user to read the newly shown material without having to scroll.
I wanted to test out a few styles of animation, with one of them being the usage of a GIF and timer to emulate what would normally be a bit more complex to execute. The main issue here, is in the flash that is sometimes seen as the GIF animations are swapped out. You may be able to see this when you click on one of the chests.
A second issue was in how the browser ignores the cached content on a page refresh where you hold down a specific key. This technique is often used in development to see changes that have been made. The issue is that the browser only ignores the initially loaded content, and the secondary GIF that is loaded upon clicking the chest is still retrieved from the cache, requiring me to clear the cache manually every time I change something on that second image.
I spent about 3 days on this specific issue, trying to 'trick' the browser into acting like a landscape site while being in portrait mode. I had rotated the body of the page, and adjusted all my measurments so that the site would be an effective duplicate of what is normally seen in landscape mode.
The issue was that the scrolling feature of any section was now 90 degrees off, forcing users to scroll-left in order to scroll up and down. I tried numerous tricks, such as creating a false scrolling area, rotating it back and replacing regular scroll events with scroll-left events... so on and so on.
I was able to get 90% of the site looking and performing the way it was supposed to, but the Canvas area ran into too many problems from the rotation and counter-rotation throwing off it's calculations, so I ended up deciding to prompt the user to use landscape mode should they land on the page in portrait mode.
The main issue here is that many mobile browsers include the navigation bar height when calculating the viewer size, forcing the page to be taller than it should be. However, when setting an absolutely positioned element, the 'bottom' of the page is still only the bottom of the viewable area, and not the actual bottom of the page.
This causes the page to be improperly lined up, should a user scroll down on the main page. This issue only really affects pages that are not supposed to scroll, but take up the entire viewable area, so solutions were limited to little 'hacks' for each mobile platform.
I tried numerous solutions to work around the issue, but many of the tricks have become broken due to updates in the browsers, and the tricks that worked then caused additional issues in other browsers. So I decided to just accept the bug and take it as a reasoning to develop on native platforms when designing a mobile interface, which is why I began learning React-Native.
Hi, I'm Joey Hicklin the web developer! (Unless it's a Saturday, then I'm Joey Hicklin, the board gaming host.) I live in Vancouver, Washington with my wife and our 4 cats.
Years ago I was asked to pick a single object that could accurately describe me and I replied, "An Excel sheet... but a really cool Excel sheet that can render images by using each cell to represent a single pixel." Of course an Excel sheet isn't a physical object, so I had to change my answer on the fly and the best I could come up with was, "A raquetball, because I have a lot of energy and I like the color blue." I still picture the other people that answered that question as their objects, so one person is an intricate stained glass scene and another is an antique pocketwatch. I'm really hoping that they remember me as a raquetball containing an IoT device with Excel installed.
I'm a minimalist by heart and I try to tailor my development tactics to reflect that. There's just something so very satisfying about being able to complete a task with as few lines as possible. However, this desire is constantly kept in check with the only other thing that's even more satisfying, expediting a process. If I can complete the task quicker without sacrificing performace or accuracy, elegance gets saved for later.
When I'm not working on a coding project, I'm probably hanging out with my wife, Kelly. Right now we mostly play Star Realms, Robinson Crusoe, and Dungeon Defenders 2. The most common show we watch would probably be Star Trek (we're mid-way through Voyager). We like to go backpacking and primitive camping, and we're also building a tiny home. If we aren't right next to each other, I'm probably working on my next batch of cider, tweaking the recipe, and she's probably painting rocks.