Josh W. Comeau
@joshwcomeau
Indie developer and educator. Blogging at . Previously at DigitalOcean, Khan Academy. Taught at Concordia Bootcamps. He/Him 🌈
Yeah, I mean to be fair to the tool, it will tell you if the dithered image is larger than the original, and that's often the case with more-complex images. I just did a quick experiment with my test image and the dithered -> webp was ~20% smaller than original jpg -> webp (50kb vs 40kb):
Honestly with modern image formats like avif/webp, I don't know that the filesize reduction is that compelling anymore, but I think it's a really cool-looking effect. ✨ The video game "Return of the Obra Dinn" famously used a 2-color palette with dithering for a completely unique art style:
There's so many creative things we can do with this. Here's a Bayer dither with 3x pixel scale and an original Game Boy color palette:
I've never heard of “Riemersma” before, but it's another dithering algorithm that does a remarkable job of making images seem like they have more colours than they do. This is only black, white, and two reds! Filesize reduced to just 13% of the original:
If we shrink the true size of the image first, we get a pixellated effect. This further reduces the filesize, but I think it's more interesting as an artistic effect. Bayer dithering doesn't usually look as good (IMO) with larger pixels, but error diffusion looks pretty darn cool. Only 10 colours:
Maybe the most common form of dithering is Bayer dithering, which selects from a limited palette based on a pre-defined pattern. If that pattern is small / zoomed-out, it's not really noticeable, but it dramatically reduces the filesize since only 8 colors are used.
🚨 Cool website alert: ditherit.com Upload an image and experiment with different dithering algorithms, either to reduce the filesize of an image or for artistic effect. Examples in thread! 🧵
Fun bonus: the donation thank-you page puts an exclamation mark at the end of the heading, but since the fundraiser name is "What Will I Become?", it reads like "Thank you for your generous donation?!". 😂
A student told me that they’re interviewing for a job, and the technical interview is done through an AI chatbot. I gave it a shot, and this was the very first question:
There's also a hackathon, if you want to join the challenge yourself. codetv-gsap-cloud.webflow.io Speaking of landing pages, the landing page for this hackathon is absolutely worth checking out. 💥
Specifically, we look at how to use the Anchor Positioning API to build a tooltip that avoids the age-old problem of overflowing when the anchor element happens to be near the top of the viewport:
✨ Just published the final bonus feature for Whimsical Animations! It’s a collection of 11 challenging animations and interactions, the final boss of the course. I had way too much fun with the cover art. 😂
😮 Cool website alert: Toronto Games Week has this lovely physics-based hero animation. 💯 torontogamesweek.com/index.html Do I know any Toronto-based game devs?
🏎️ Well this is fun! @rahulchaurasiya.bsky.social built a way to visualize different easing curves using racecars. racing-curve.vercel.app
A trend I’ve started noticing: my email newsletters get responded to by chatbots that have misunderstood my newsletter as some sort of customer service request. 😂 I’ve started having fun with them. Let’s see if I can get some free AI-generated recipes.
I didn’t run any formal benchmarks, but we can get a sense of scale by doing a performance timeline. On my machine (2021 Macbook pro), it takes 64 microseconds to do the JS calculation work.
Most animations are just one of many things happening on the page at that time, and if the JS thread gets busy with some other work, our animation will freeze until that work is completed. Interestingly, however, not all JS libraries are created equal. Motion, for example, seems to break this rule:
I think many of us would assume that CSS animations are faster, since we don't have to do extra work in JS on every single frame. And that's technically true, but in most cases, it’s too small to make a noticeable difference. The real issue is that JS animations run on the main thread:
Finally, I picked a lesson on 2D Canvas. I show you how to build this confetti effect. It’s a pretty advanced lesson, leveraging many techniques we cover in the course, but it covers one of the hardest things to wrap our minds around with Canvas: doing transforms.
Also: I hate that I need to specify this now, but I create these cover art images in Blender manually, without AI.
Here‘s one of the challenges. You’ll learn how to create stuff like this in the course 😄
I have way too much fun making the cover art for my course modules. 😂 Specifically, this is for the final bonus feature of Whimsical Animations. It’s a series of difficult challenges, including one Kirby-inspired effect.
🌸✨ I just launched my annual Spring Sale! You can save up to 50% on my online courses. (I realize that it's basically summer in most of the northern hemisphere right now 😂. But up here in Canada, the flowers just started blooming! Look at the trees near my office.) Details in thread. 🧵
🚨 Cool project alert: Bloom, a React component that generates an SVG highlight with a hand-drawn aesthetic. ✨ github.com/yeunoia/bloom
And one more, making use of all of the particle tricks we learn in Part 1:
Here's another example, taken from Pinterest. This challenge makes use of polar coordinates from Part 1 and some of the cursor tricks from Part 3. 😄
✨ I’m working on “Animation Challenges”, the final boss of my new animations course. It feels like that Karate Kid moment. We don’t cover any of these animations directly in the course, but all of them can be built using the lower-level techniques we learn. Wax on, wax off 🥷
I think everyone who thinks that it is no longer necessary to understand software engineering principles because of AI should spend a few minutes every day browsing /r/vibecoding. It's so so clear that technical skills are still worthwhile.
Aside from the initial position, we’re not painting any frames in the first half of the space! That's why it feels like it's teleporting. With "Ghosts" enabled, we can tweak the handles until there’s no more jumping, while preserving the smooth landing: