Using mask for SVG animation implementation

Looking to add an SVG animation to my download button.

My goal is to have the arrow scroll down recursively within the red box.

Something similar can be seen here.

The animation needs some calibration, but the issue lies in the fact that the mask isn't functioning as intended; the arrow remains visible when moving out of the red box.

What could be causing this problem?

Hoping for a solution that doesn't involve JavaScript.

View it on jsfiddle

@keyframes arrow-slide-recursively {
  from {
    transform: translate(0%, 0%)
  }
  to {
    transform: translate(0%, 50%)
  }
}

.fanbox-helper-fixed-menu-button {
  background-color: transparent;
  cursor: pointer;
  border: medium;
  padding: 4px;
  width: 54px;
  height: 54px;
}


.fanbox-helper-fixed-menu-button.busy {
  opacity: 0.3;
  pointer-events: none;
}

#fanbox-helper-quick-save-button.busy .arrow {
  animation: arrow-slide-recursively 2s linear infinite;
}
<button id="fanbox-helper-quick-save-button" class="fanbox-helper-fixed-menu-button busy">
  <svg class="fanbox-helper-svg-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
    <mask id="fanbox-helper-quick-save-arrow-area" x="120" width="272" height="440">
      <rect x="120" width="272" height="440" fill="red"></rect>
    </mask>
    
    <rect x="120" width="272" height="440" fill="red"></rect>
    
    <g id="fanbox-helper-quick-save-arrow" mask="#fanbox-helper-quick-save-arrow-area">
      <path class="arrow stick" stroke="black" stroke-linecap="round" stroke-linejoin="round" fill="none" d="m256,96 l0,256" stroke-width="40"></path>
      <path class="arrow edge left" stroke="black" stroke-linecap="round" stroke-linejoin="round" fill="none" stroke-width="40" d="m256,392 l-104,-104"></path>
      <path class="arrow edge right" stroke="black" stroke-linecap="round" stroke-linejoin="round" fill="none" stroke-width="40" d="m256,392 l104,-104"></path>
    </g>
    <path class="bowl" stroke="black" stroke-linecap="round" stroke-linejoin="round" fill="none" stroke-width="40" d="m64,312 l0,148 l384,0 l0,-148"></path>
  </svg>
</button>

Answer №1

You have not properly applied the mask - make sure to enclose the reference in a url() function like this

svg{
  overflow:visible;
  outline:1px solid #ccc;
}

@keyframes arrow-slide-recursively {
  from {
    transform: translate(0%, 0%)
  }
  to {
    transform: translate(0%, 50%)
  }
}

.fanbox-helper-fixed-menu-button {
  background-color: transparent;
  cursor: pointer;
  border: medium;
  padding: 4px;
  width: 54px;
  height: 54px;
}


.fanbox-helper-fixed-menu-button.busy {
  opacity: 0.3;
  pointer-events: none;
}

#fanbox-helper-quick-save-button.busy .arrow {
  animation: arrow-slide-recursively 2s linear infinite;
}
<button id="fanbox-helper-quick-save-button" class="fanbox-helper-fixed-menu-button busy">
  
  <svg class="fanbox-helper-svg-icon" xmlns="http://www.w3.org/2000/svg" id="Capa_1" viewBox="0 0 512 512">
    <mask id="fanbox-helper-quick-save-arrow-area" >
      <rect x="120" width="272" height="440" fill="#fff"></rect>
    </mask>
    <rect x="120" width="272" height="440" fill="red"></rect>
    
    <g id="fanbox-helper-quick-save-arrow" mask="url(#fanbox-helper-quick-save-arrow-area)">
      <path class="arrow stick" stroke="black" stroke-linecap="round" stroke-linejoin="round" fill="none" d="m256,96 l0,256" stroke-width="40"></path>
      <path class="arrow edge left" stroke="black" stroke-linecap="round" stroke-linejoin="round" fill="none" stroke-width="40" d="m256,392 l-104,-104"></path>
      <path class="arrow edge right" stroke="black" stroke-linecap="round" stroke-linejoin="round" fill="none" stroke-width="40" d="m256,392 l104,-104"></path>
    </g>
    <path class="bowl" stroke="black" stroke-linecap="round" stroke-linejoin="round" fill="none" stroke-width="40" d="m64,312 l0,148 l384,0 l0,-148"></path>
  </svg>
</button>

In addition, using a red fill color will create semi-transparency. To achieve full opacity within the mask's rectangle, use '#fff' or 'white'.

I suggest utilizing a clip-path instead, as it is more efficient and does not introduce an alpha channel.

svg {
  overflow: visible;
  outline: 1px solid #ccc;
}

@keyframes arrow-slide-recursively {
  from {
    transform: translate(0%, 0%)
  }
  to {
    transform: translate(0%, 50%)
  }
}

.fanbox-helper-fixed-menu-button {
  background-color: transparent;
  cursor: pointer;
  border: medium;
  padding: 4px;
  width: 54px;
  height: 54px;
}

.fanbox-helper-fixed-menu-button.busy {
  opacity: 0.3;
  pointer-events: none;
}

.busy .arrow {
  animation: arrow-slide-recursively 2s linear infinite;
}
<button id="fanbox-helper-quick-save-button" class="fanbox-helper-fixed-menu-button busy">

  <svg class="fanbox-helper-svg-icon" xmlns="http://www.w3.org/2000/svg" id="Capa_1" viewBox="0 0 512 512">
    <clipPath id="clip">
          <rect x="120" width="272" height="440" fill="red" />
    </clipPath>
    <rect x="120" width="272" height="440" fill="red"></rect>

      <g class="fanbox-helper-quick-save-arrow" clip-path="url(#clip)" >
        <path  class="arrow" stroke="black" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M256 96v256m0 40-104-104m104 104 104-104" stroke-width="40" />
      </g>
    <path class="bowl" stroke="black" stroke-linecap="round" stroke-linejoin="round" fill="none" stroke-width="40" d="m64,312 l0,148 l384,0 l0,-148"></path>
  </svg>
</button>

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

problem | JQuery slide causing automatic page scroll to top

Here is the HTML for my slide: <div class="slide_container"> <div class="one_slide"> <a href="#"><img alt="slide_img" class="slide_img img-responsive" src="images/slide2.jpg"></a> </div> ...

What is the best way to have a sound play when the page is loaded?

Is there a way to automatically play a sound when the page loads? <audio src="song.mp3"> Your browser does not support the audio element. </audio> I've attempted it with the following method: <script type="text/javasc ...

Using Bootstrap, Express, and Node.js to create a login form

As I am new to node.js and express, I am still trying to understand the basic functionality. Currently, I have a simple sign-in form where I want to load another HTML page and call a node.js function upon clicking the sign-in button. What would be the best ...

Encountering issues with the interaction between Bootstrap and my custom CSS file in a Flask app with

I am encountering an issue with my template where I have included both Bootstrap and CSS files, with Bootstrap loaded before CSS. However, when I try to apply custom CSS using IDs or classes, the changes do not reflect. Strangely, styling for h1 elements i ...

Today, I am experimenting with HTML5 File Upload using Capybara and Selenium Webdriver in Ruby

I have encountered a problem with a simple modal that allows users to upload a file using a browse button. Due to some unknown issue, possibly related to the fact that it is an HTML5 file input and the browser adds its own functions to it, testing this has ...

Variety of perspectives on Magento products

Is there a way to configure Magento 1.7 to display view.phtml for bundled products and view.phtml for simple products, or the other way around? I am looking to customize the views for different product types - what is the best approach to achieve this? ...

Execute a Python script even if Python is not installed on your device

One of my clients needs to access certain files through sftp. I was able to accomplish this using Python on my computer. However, I now face the challenge of implementing the same solution on his laptop without requiring him to install Python. What would ...

"Troubleshooting the issue of multiple root nodes in Vue.js even when there

While working on my Vue.js code, I encountered an issue with a v-for loop. Despite having only one HTML node within it, Vue is giving me two errors: vue.js:597 [Vue warn]: Error compiling template: <div id="products" v-for="p in productList"> ...

Utilize a single JavaScript script to handle numerous HTML forms within the same webpage

I am currently facing an issue with a page that contains multiple forms needing the same JavaScript code. This specific code is designed to add more input fields to the form, which it does successfully. However, the problem lies in the fact that it adds in ...

Ways to conceal the contents of a page behind a transparent background div while scrolling

I created a Plunkr with the following markup: <body> <div class="container-fluid"> <div class="row"> <div class="col-sm-12"> <nav class="navbar navbar-fixed-top"> <div class="container-fluid"& ...

Element misbehaving after a certain point

I'm encountering an issue with a piece of code that is not working as expected. The problem seems to be specifically with the after element. The desired behavior is for two lines to draw from the top left corner and the bottom right corner when hoveri ...

Troubleshooting: Android compatibility issues with dynamic source for HTML 5 video

My HTML5 video with dynamic source loaded using JavaScript is functioning properly in a web browser but encountering issues within an Android PhoneGap build application. Take a look at the code snippet below: JavaScript code: $('#video_player' ...

How to use jQuery to set the padding-right equal to the width of a child element

My goal is to set the padding-right css property based on the width of a child element. Here's my approach: Using jQuery $('.parent_element').css('padding-right', $(this).children('.child_element').width() + 'px&ap ...

Tips for toggling the appearance of like and add to cart icons

I am attempting to create a simple functionality for liking and adding items to a cart by clicking on the icons, which should immediately change the icon's color when clicked. However, I am facing an issue where the parent div's link is also bein ...

Attempting to conceal my default drop-down menu

I need to find a way to hide my drop down menu by default, as it currently shows up automatically. The drop down menu in question is under "My Account". This is the HTML code I'm working with: <li class="hoverli"> <a href="/customer/ac ...

Interactive webpages with dynamic HTML content, similar to the design of popular platforms such

Explore the source code of Dropbox's homepage or any Soundcloud page. They utilize various scripts and minimal pure HTML content (article, main, p, div). This method of generating pages is referred to as dynamic content/HTML. The main function seems ...

Is it possible to continuously refresh a DIV element?

After spending the past 4 or 5 hours scouring Stack and various other resources, I am still unable to find a solution to my problem. The issue at hand involves an Iframe within a page that displays 5 lines of information fetched from a database. This info ...

Click on a button to initiate the download of a collection of images

In my simple HTML structure, there is a button designed for downloading purposes: <div id="getImageWrapper"> <div class="image"> <p class="image-name">{{imageName}}</p> <button class="download-btn" @click="ge ...

Interactive dropdown menu that scrolls upon clicking

Is there a way to make the page automatically scroll down to the bottom of a dropdown menu when it is clicked? Currently, users have to manually scroll down after opening the menu. I initially tried using anchors for this functionality, but it interfered w ...

Detecting changes in a readonly input in Angular 4

Here is a code snippet where I have a readonly input field. I am attempting to change the value of this readonly input from a TypeScript file, however, I am encountering difficulty in detecting any changes from any function. See the example below: <inp ...