Creating animations with an svg mask can be effective, however, it seems to only work properly

I have been experimenting with creating a transition effect using SVG masks and CSS. Initially, everything was working as intended, but after a few repetitions (usually 1 or 2, unpredictably), the transition effect would suddenly stop and become instantaneous. Upon thorough examination of my code and monitoring for any issues with the generated SVG, I found that everything appeared to be correct and consistent with the initial executions where the effect worked smoothly.

This anomaly occurs in both Firefox and Chrome browsers.

To demonstrate this issue, I have prepared a JSFiddle: https://jsfiddle.net/nrm4fwg0/1/


function lerp(start, end, t) {
  return start * (1 - t) + end * t;
}
const noise = (visible, wasVisible, durationSeconds = 1, seed = 44, liminal = 0.1) => {
  const startOp = lerp(liminal * 2, 1 + liminal * 2, wasVisible?1:0);
  const endOp = lerp(liminal * 2, 1 + liminal * 2, visible?1:0);

  const slope = -1 / (liminal * 2);
  const startIntercept = (startOp - liminal) * -slope;
  const endIntercept = (endOp - liminal) * -slope;


  return `
<svg xmlns="http://www.w3.org/2000/svg" viewport="0 0 100 100" width="100" height="100">
  <defs>
    <filter id="alpha-effect">
      <feFlood  x="0" y="0"
      width="100" height="100"/>
      <feGaussianBlur stdDeviation="3"/>
      <feComponentTransfer result="SMOOTH">
        <feFuncA type="table" tableValues="1 0.7 0.3 0"/>
      </feComponentTransfer>
      <feTurbulence seed="${seed}" result="NOISE" type="fractalNoise" baseFrequency="0.05" numOctaves="5"/>

      <feMerge>
        <feMergeNode in="NOISE"></feMergeNode>
        <feMergeNode in="SMOOTH"></feMergeNode>
    </feMerge>

      <feComponentTransfer>
        <feFuncA type="linear" slope="${slope}" intercept="${endIntercept}">
            <animate
            attributeName="intercept"
            from="${startIntercept}"
            to="${endIntercept}"
            dur="${durationSeconds}s" />
        </feFuncA>
      </feComponentTransfer>
    </filter>
  </defs>
  
  <rect x="0" y="0" width="100" height="100" 
        fill="blue" filter="url(#alpha-effect)"/>
</svg>
`;
};


let isCardVisible = true;
function toggleCard(){
    const card = document.querySelector('#card');
  const mask = noise(!isCardVisible, isCardVisible);
  isCardVisible = !isCardVisible;
 
  
  card.style['mask-image'] = `url(data:image/svg+xml;base64,${btoa(mask)})`;
  card.style['-webkit-mask-image'] = `url(data:image/svg+xml;base64,${btoa(mask)})`;
  card.style['mask-size'] = 'cover';
  card.style['-webkit-mask-size'] = 'cover';
  card.style['mask-repeat'] = 'no-repeat';  
}

document.querySelector('#button').addEventListener('click', toggleCard);

Answer №1

After some thought, I managed to come up with a solution, although I am still unsure of the reasoning behind it. If anyone has any insights on why this issue is occurring, I would greatly appreciate hearing them.

Essentially, I decided to make the ID of the filter random each time:

const id = `alpha-${Math.random()}`; 

Instead of using the fixed alpha-effect as before. This change ensured that the effect continued to work properly.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

:after pseudo-element along with HTML tags

I have recently designed a basic webpage in an attempt to simulate ajax using CSS. In order to achieve this, I aimed to create hidden radio buttons with visible labels, and load an external CSS file when the user clicks on a label. However, I encountered o ...

Is there a way to adjust the padding temporarily?

Important Note: Despite the misleading title of my question, it doesn't accurately reflect my actual query (sort of). Below is the code snippet in question: .one{ background-color: gray; } .two{ padding: 20px; } <div class = "one"> < ...

Discrepancies in button padding across desktop and mobile platforms

I have created a sample button and included a jsfiddle link to showcase the code. Due to the font properties of the specific font I'm using, I had to adjust the padding values differently for the top and bottom of the text to achieve a vertically cent ...

Unusual CSS behavior discovered while implementing horizontal scrolling navbar with overflow-x

I've been working on a navbar that will scroll horizontally when it exceeds the width of its parent container. It features a bottom border with a different color for the active link. Using a negative margin to overlap them works well, but as soon as ...

Easy jQuery image that smoothly fades in and out

Can anyone recommend a script that allows for creating a slideshow where images fade in and out, rather than sliding left and right? I have a list of images below that I would like to use for the slideshow. <ul class="slideshow"> <li><im ...

Explore three stylish ways to showcase dynamic JavaScript content using CSS

Objective: For Value 1, the CSS class should be badge-primary For Value 2, the CSS class should be badge-secondary For all other values, use the CSS class badge-danger This functionality is implemented in the handleChange function. Issue: Current ...

Utilize CSS to break through a backdrop

I have come across a rather peculiar question, and I'd like to elaborate with a code snippet: .container { width: 200px; height: 200px; background: rgba(200, 200, 200, .87); } .pin { position: absolute; left: 50px; top: 20px; } .overl ...

Creating a scrollable panel using CSS is easy with a solid border and a panel element

Using Vaadin to design my front-end, I encountered an issue where adding border-style:solid to the style.css file resulted in a scrollable v-panel. How can I retain the solid style while removing the scrolling feature? Please refer to the screenshot for cl ...

Issues with keyboard accessibility in drop down menus

Looking to improve the keyboard accessibility of my menu bar. Swapped out all instances of :hover with :focus, but unfortunately dropdown menus are still not accessible via keyboard. Does anyone have a solution for this issue? Appreciate any help! ...

What causes the issue when attempting to import multiple CSS files in a Vue.js project using @import more than once?

Currently, I am working on a project that involves one main component and several child components. These components require custom CSS files as well as additional vendor CSS files. A challenge I encountered is that I cannot use the @import "path/to/css/fi ...

How can I align the title of a cell to the left while centering the remaining content?

I have a dilemma with two table cells placed side by side that stack upon triggering a media query for an HTML newsletter. I wish to align the headlines "Be Ready" and "Stay Organized" to the left when the responsive code activates, but the use of "margin: ...

Using jQuery .animate() leading to erratic input movements

I am currently utilizing jQuery's .animate() feature to create a smooth animation effect on the width of a <div> element when a child <input> is in focus. Nevertheless, I'm encountering an issue where the input field jumps up and down ...

Establish initial content for the specified div area

I need help setting page1.html to display by default when the page loads. Can you provide some guidance? Appreciate your assistance in advance. <head>     <title>Test</title>     <meta http-equiv="content-type" content="tex ...

JavaScript does not function properly with dynamically loaded content

Trying to load the page content using the JQuery load() method. See below for the code snippet: $(window).ready(function() { $('#content').load('views/login.html'); }); .mdl-layout { align-items: center; justify-content: center ...

Adjusting the height of the navbar items to align with the size of the

In the bootstrap navbar below, I am trying to enlarge the search field to be large using 'input-lg', but this causes the other items in the navbar not to vertically center correctly. How can I align the other items in the navbar with the large in ...

Achieving Vertical Center Alignment in CSS

I'm having trouble understanding what's happening here: My goal is to vertically center an iframe and another div, both positioned alongside each other horizontally. What I've attempted is placing the iframe and div inside a new div called ...

Iterating over an array and displaying elements on the webpage

Struggling to access an array and loop through it, but only able to print out one element instead of all. Need a hint on how to solve this issue. See my code below: let toppingsCount; const burger = document.createElement('div'); const toppingsD ...

The right padding on an HTML table is not functioning properly when the table width is larger than

I am facing an issue with a table that has multiple columns. I want each column to have the same width, resulting in the total table width being wider than the page width. This is fine as it prompts the browser to display a horizontal scrollbar. However, d ...

Addressing some minor visual inconsistencies in an HTML bullet-pointed list

After reviewing my current code, it is displaying the following: https://i.stack.imgur.com/dvjrc.jpg I am attempting to make the following changes: Ensuring each line in the list fits properly within its corresponding box by utilizing vertical-align: to ...

Is there a way to expand this embedded video so that it spans the entire width of the screen

I have a code snippet with one row and two columns. I would like to embed a video from Vimeo in the first column so that it fills the entire column without any padding. Additionally, I want the two columns to be right next to each other with no space betwe ...