Weeknotes 22:13

June 5, 2022

Week of May 29 - June 4

Adventures in SVG Masking

After a three-day weekend, I got back to work on Tuesday morning on the Real World Learning site we are building for the Kauffman Foundation. My next task was to replace static images with an SVG that I would animate with GreenSock ScrollTrigger and DrawSVG plugins. There are several “doodles” in the design that I wanted to animate by drawing paths as the reader scrolls down the page. The doodles were created by one of our newest team members, Kosta, an illustrator and animator. The doodles were rasterized images and not vectors.

After watching Cassie Evans‘ presentation, Unlocking SVG Superpowers, I explored using SVG masks. I used a very similar technique that Cassie used with clipPath. I saved the “doodles” as a PNG image (twice the size for high-density screens) and opened the doodles in Affinity Designer. In Affinity Designer, I used the pen tool to create paths that would be masked by the image. I could animate those paths with the DrawSVG plugin. For some of the doodles, I would draw multiple paths and/or have multiple images.

But on Tuesday morning, I was running into a problem where my masks did not look correct. I tried redrawing the paths in Affinity Designer but still was frustrated that my masks were not working as they had in several CodePen experiments that I had done.

Masks not applying properly on the left.

I finally mentioned my problem to my colleague, Ryan. About thirty minutes later, he came back to me with some “magic code” that made my masks work properly.

<mask maskUnits="userSpaceOnUse">

The problem had to do with the maskUnits attribute. By default, the maskUnits are set to objectBoundingBox. But according to this W3C specification,

Keyword objectBoundingBox should not be used when the geometry of the applicable element has no width or no height, such as the case of a horizontal or vertical line, even when the line has actual thickness when viewed due to having a non-zero stroke width since stroke width is ignored for bounding box calculations. When the geometry of the applicable element has no width or height and objectBoundingBox is specified, then the given effect (e.g., a gradient or a filter) will be ignored.

The SVG paths that I created did not have a width or height because they were lines with a stroke width added to them.

To be perfectly honest, I do not completely understand what is going on here. It has something to do with the coordinate systems used within the SVG canvas. What I do understand is that I need to set the maskUnits on my SVG mask to use userSpaceOnUse. It is a “magic code”.

I still ran into some other problems during the day but was able to diagnose those as user errors. In one of those instances that took me a while to figure out, I had used assigned an id of “#mask.” The pound in the id declaration was the problem. Those are much easier to fix.

I am grateful for teammates like Ryan who can help me when I get stuck. He had a hunch that my problem was tied to the bounding box of my paths and was able to know what to search for to find the solution. It is one of the advantages of working on such a talented team.

Whose fridge is it anyway?

For our Friday Campfire, my team played a game called “Whose fridge is it anyway?” Each of us sent in a picture of the inside of our fridge and one of our teammates put together a quiz using Google forms. There was also some fun commentary with each one, like “Who needs to go to the store?”

We had played a similar game a couple of months ago where we all sent in a baby picture and we had to guess which teammate it was. That game was a bit easier.

I only got one right in the fridge game, my own fridge. Womp womp (unfortunately this site is not as much fun as it use to be because the audio no longer autoplay in browsers).

Other highlights

  • After solving the masking issue on the Real World Learning site, I was able to create SVGs of all the doodles and animate them. We showed a preview to the client later in the week and they were thrilled.
  • After finishing the homepage on Thursday, I started building a second page for the Real World Learning site on Friday.
  • I implemented a tag solution for Connect2Canada and added a plugin to help improve the search functionality. The site already had tagged content and I just added the tags to the template and wrote CSS to make them distinct from the category listing.
  • I updated the content for two internship programs for a financial institution that we work for. One of the sites is opening up applications for students to apply for opportunities to work with small business owners for the fall semester.
  • I continue to go out each day with my son so he can practice his driving to prepare to take the road test to get his license later this summer.
  • I bought and installed a ceiling fan in our “dining room”, with the help of my son. The room is serving as my summer office. My daughter, who recently graduated from college, is living in my normal office space for the summer. The fan will make it much cooler to work in the space that I am in.

Articles I read

Books I read

What I watched

  • Obi-Wan Kenobi (Disney+)
  • Somebody Feed Phil (Netflix)
  • Everybody Loves Raymond (Peacock)
  • Lincoln (Amazon Prime) – I watched this one with my son on Saturday. I really enjoyed this movie. I was not aware of the story behind the passing of the 13th Amendment.

What I played

  • Wordle – I was so close on several of these only to have to use three guesses to get the final letter.
  • MLB The Show 21 (Braves) – I continue to struggle. Still having trouble stringing together a winning streak. I am living and dying by the home run. I want to generate more runs by stringing together hits and keeping the line moving.

Comments are closed.