Custom (themeable) shape masks

Problem: Custom (themeable) shape masks

Saola Animate version: 2.7.1

OS: Windows 10

Notes:

I’m trying to create a simple SVG animation on hover, however, I need to ‘hide’ or mask certain parts of the animation. I figured out that I can do it by using a hider SVG and it’s working well. However, the website where I’m going to finally use it supports light/dark theme and so, I can’t hardcode just white SVG in the animation as when the user switches to dark theme, the ‘hack’ would be revealed. So, I’m looking for possible suggestions in achieving the desired results.

I think I can probably do it using another SVG with the required dark colour, but, how do I swap the images on theme change? I’m going to use it here: https://hrishikeshk.netlify.app/index.html. As you can see, I’m using simple CSS variables there and add a class to <body> to manipulate the theme. I am currently reworking on that website and would like to not touch the JavaScript there unless required.

I’m open to any other ideas.

Here’s my file: Themeable-Masking.saolapack (4.0 KB). The animation triggers on hover. Also, this is just an example, but, I’m going to be adding a few more icons in a similar manner. So, I’d need to manipulate them all in one go.

I might have found a ‘hacky’ way. It seems to work up to a certain extent.

I thought of using custom events. Here’s what I’m doing:

I created 3 functions to run on scene activated.

First function (dispatches the event):

Note: This event is actually going to be dispatched by my website, currently, I’m dispatching it using Saola Animate just for testing purposes.

if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches)
  {
    document.dispatchEvent(new CustomEvent('themeEvent',
      {
        detail:
          {
            name: 'dark'
          }
        }));
   }
else
  {
    document.dispatchEvent(new CustomEvent('themeEvent',
      {
        detail:
          {
            name: 'light'
          }
        }));
  }

Second function (shows/hides the masks):

Note: I’ve set the required classes to the group of the masks.

document.addEventListener('themeEvent', function(event)
  {
    if (event.detail.name == 'light')
      {
        document.querySelectorAll('.hider-light').forEach((hiderLight) =>
          {
            hiderLight.style.display = 'block';
          });
        document.querySelectorAll('.hider-dark').forEach((hiderDark) =>
          {
            hiderDark.style.display = 'none';
          });
      }
    else
      {
        document.querySelectorAll('.hider-light').forEach((hiderLight) =>
          {
            hiderLight.style.display = 'none';
          });
        document.querySelectorAll('.hider-dark').forEach((hiderDark) =>
          {
            hiderDark.style.display = 'block';
          });
      }
  })

Third function (watches for change in device theme):

Note: The function name used in this is same as the one used in my document.

window.matchMedia('(prefers-color-scheme: dark)').addListener(themeChecker);

However, this doesn’t work unless the theme is toggled. I mean that, because I have my ‘Light Hiders’ layered on top of ‘Dark Hiders’, they are not hidden in the rendered document even if the device theme is dark. However, if you toggle theme using your device’s settings or using browser’s developer options, it seems to work. I can’t seem to get it to work immediately on load.

What am I missing? Also, I’d appreciate if there’s any better method.

EDIT: Here’s the updated file by the way: Themeable-Masking (updated).saolapack (5.0 KB)

Hi Hrishikesh,

I think you can cut the icon to 3 parts: top, middle, bottom, and use animation to move the top part and scale the middle part.
Please see this sample: animate icon.saolapack (7.2 KB)

Regards

1 Like

That’s quite possible and simple. Thanks a lot!