Unusual SVG Cubic Bezier Animation Transforming Curves into Points and Lines

As a beginner in SVG CSS animation, I am currently working on morphing three curved paths into three rectangles using cubic bezier routes. While I have managed to make it work, there is an issue during the transition where parts of it skew inward in a strange manner (refer to the CodePen provided below). The top right, middle, and bottom left transitions appear as expected but the top left and bottom right transitions are not behaving as anticipated. Is there a way to adjust the curves to prevent this effect from occurring, or is it just a side effect of the chosen method? If so, is there a more effective approach that can be used to achieve a smoother transition?

svg {
  height: 150px;
  cursor: pointer;
}

svg path {
  transition: d 1s ease;
}

svg:hover .top {
  d: path('M 1280,256 C 2560,256 2560,256 2560,256 C 2560,768 2560,768 2560,768 C 1280,768 1280,768 1280,768 C 0,768 0,768 0,768 C 0,256 0,256 0,256 C 1280,256 1280,256 1280,256');
}

svg:hover .middle {
  d: path('M 1280,1024 C 2560,1024 2560,1024 2560,1024 C 2560,1280 2560,1280 2560,1280 C 2560,1536 2560,1536 2560,1536 C 1280,1536 1280,1536 1280,1536 C 0,1536 0,1536 0,1536 C 0,1280 0,1280 0,1280 C 0,1024 0,1024 0,1024 C 1280,1024 1280,1024 1280,1024');
}

svg:hover .bottom {
  d: path('M 1280,1792 C 2560,1792 2560,1792 2560,1792 C 2560,2304 2560,2304 2560,2304 C 1280,2304 1280,2304 1280,2304 C 0,2304 0,2304 0,2304 C 0,1792 0,1792 0,1792 C 1280,1792 1280,1792 1280,1792');
}
<!DOCTYPE html>
<html>
  <body>
    <svg viewBox="0 0 2560 2560">
      <path class="top" d="
        M 1280,0
        C 1986.92447978368,0 2489.165,505 2553.665,1152
        C 2553.665,1152 2041.665,1152 2041.665,1152
        C 1976.434,789.00439808 1704.154687870208,512 1280,512
        C 855.8453121297921,512 583.566,789.00439808 518.335,1152
        C 518.335,1152 6.335,1152 6.335,1152
        C 70.835,505 573.07552021632,0 1280,0
      " />
      <path class="middle" d="
        M 1280,768
        C 1562.769791913472,768 1792,997.230208086528 1792,1280
        C 1792,1280 1792,1280 1792,1280
        C 1792,1562.769791913472 1562.769791913472,1792 1280,1792
        C 1280,1792 1280,1792 1280,1792
        C 997.230208086528,1792 768,1562.769791913472 768,1280
        C 768,1280 768,1280 768,1280
        C 768,997.230208086528 997.230208086528,768 1280,768
        C 1280,768 1280,768 1280,768
      " />
      <path class="bottom" d="
        M 1280,2048
        C 1704.154687870208,2048 1976.434,1770.99560192 2041.665,1408
        C 2041.665,1408 2553.665,1408 2553.665,1408
        C 2489.165,2055 1986.92447978368,2560 1280,2560
        C 573.07552021632,2560 70.835,2055 6.335,1408
        C 6.335,1408 518.335,1408 518.335,1408
        C 583.566,1770.99560192 855.8453121297921,2048 1280,2048
      " />
    </svg>
  </body>
</html>

CodePen (Tested in Chrome.)

Answer №1

It seems that the shape's appearance is influenced by a combination of factors:

  1. The curvature of the shape
  2. The type of linear interpolation used
  3. Your choice in creating straight lines with bezier curves, particularly the control points

In this case, both control points were set to match the curve endpoint.

C    ...      ...   1280,256 
C 2560,256 2560,256 2560,256

Due to the linear interpolation, some parts of the curves bulge outwards while others bulge inwards, depending on the path direction and your position relative to the curve.

A more effective approach would be to adjust the placement of the control points:

  1. Position the control points at the 1/3 and 2/3 markers of the line
  2. Use one control point at each end of the curve

In the example below, I opted for the second method for better results.

C    ...      ...   1280,256 
C 1280,256 2560,256 2560,256

svg {
  height: 150px;
  cursor: pointer;
}

svg path {
  transition: d 1s ease;
}

svg:hover .top {
  d: path('M 1280,256 C 1280,256 2560,256 2560,256 C 2560,256 2560,768 2560,768 C 2560,768 1280,768 1280,768 C 1280,768 0,768 0,768 C 0,768 0,256 0,256 C 0,256 1280,256 1280,256');
}
<svg viewBox="0 0 2560 2560">
  <path class="top" d="
        M 1280,0
        C 1986.92447978368,0 2489.165,505 2553.665,1152
        C 2553.665,1152 2041.665,1152 2041.665,1152
        C 1976.434,789.00439808 1704.154687870208,512 1280,512
        C 855.8453121297921,512 583.566,789.00439808 518.335,1152
        C 518.335,1152 6.335,1152 6.335,1152
        C 70.835,505 573.07552021632,0 1280,0
      " />
</svg>

Please note that CSS animation of the d attribute may not be fully supported across all browsers, currently limited to Webkit-based browsers like Chrome.

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

Using @at-root seems to be causing an error when combining the "a" selector with

I encountered an issue when attempting to use @at-root and Interpolation in my Sass code. Despite using a standard example for testing, I still receive an error: .button { @at-root a#{&} { color: green; } } Error sass/Site.scss (Line 28 of s ...

Ensuring that the carousel images maintain a consistent size when switching between images

Issue with Carousel I have been struggling with a carousel feature on my website. Despite following the code provided on the Bootstrap website, I am facing an issue where the height and width of the entire div change when loading the next image. I have tr ...

The dynamic loading of an HTML/JavaScript input range object within a div is not functioning properly

Hey there, I have a hidden div containing a range input: <div id="hiddencontainer" style="display:none;"> <input id="range1" type="range" min="1" max="10" step="1" name="rating" value="1" onmousemove="showrangevalue()"/> </div> The ...

The alignment of image and text next to each other is not functioning as intended

I've been attempting to display an image and text next to each other, but I'm encountering some issues. The current output looks like the figure below: https://i.stack.imgur.com/WxxrS.jpg The desired layout is as shown in the following link: ht ...

`Loading CSS files in Node.js with Express``

My CSS isn't loading properly when I run my HTML file. Even though the HTML is correctly linked to the CSS, it seems like express and node.js are not recognizing it. I find it confusing to understand the articles, tutorials, and stack overflow questio ...

Incorporating stick-to-top scroll functionality using AngularJS and ng

I am trying to implement a 'sticky' scroll on dynamic content. My current working example can be found here. It seems to be working, but I encounter a small 'flicker' when new items are appended. This issue seems to be related to the se ...

What is the best way to create a fading footer effect on scroll using jQuery?

Why is my footer not fading in after 1000px like I want it to? Instead, it appears immediately on the screen. I attempted using fadeIn() in jQuery but had no luck. I also tried to make it disappear with fadeOut(), again with no success. Am I missing someth ...

Reveal unseen information on the webpage upon clicking a link

I have successfully implemented a fixed header and footer on my webpage. The goal is to make it so that when a user clicks on a link in either the header or footer, the content of that page should appear dynamically. While I have explored various styles, ...

Image not found in Rotativa PDF document

We have implemented Rotativa to generate and save a PDF version of our web page on the server. Below is the ASP.NET MVC 4 code snippet used for this purpose: var pdfResult = new ActionAsPdf("Index", new { orderId = orderValidated.orderID }) { FileName = ...

Padding the body of a single-page Angular application to ensure proper spacing and

How do I add padding to the body of a template in an angular ng-app? Where is the best place to include CSS for a ng-app rendered template? please refer to this fiddle for an example https://jsfiddle.net/aghsqnpa/ div.ngview { padding: 25px 50px 75p ...

When the class name is identical, the click event appears to be malfunctioning

Why isn't the click event working in this code? What am I doing wrong? $(document).ready(function() { $('.dashboardList').click(function() { alert("hello"); }); }); <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1. ...

Leveraging the power of React in conjunction with an HTML template

After purchasing an HTML template from theme forest, I am now looking to incorporate React into it. While I find implementing Angular easy, I would like to expand my skills and learn how to use React with this template. Can anyone provide guidance on how ...

Find the elements of <a> tags specifically without the attribute href

Currently, I am extracting the class of all <a> elements in an HTML document of a webpage using VB.net from a WinForm: Dim htmlLinks As HtmlElementCollection = WebBrowser1.Document.GetElementsByTagName("a") For Each link As HtmlElement In htmlLi ...

Enigmatic void found beneath image surfacing

Similar Question: Dealing with Additional Space at the Bottom of an Anchor Tag Take a look at this example page here.. There seems to be a mysterious gap below the picture of the family, just before the gray-bordered (5px #333) div that holds the ima ...

Adaptable triple-column design

After completing the layout of my website, everything seems to be functioning well. However, I would like to ensure that I haven't overcomplicated it or used poor techniques. The structure involves a main DIV with a nested table DIV, inside of which ...

Setting up web pack with flag-icon-css integration

I have successfully set up a webpack project using https://github.com/teroauralinna/webpack-guide. Now, I am looking to integrate https://github.com/lipis/flag-icon-css into my project. To do so, I followed these steps: npm install flag-icon-css --save T ...

Display words on screen and then alter hue using HTML and CSS

Is there a way to dynamically change the color of text inside <a> tags from black to red after a specific time interval and keep it permanently red? do { document.getElementById("code").innerHTML +="<a>Hello World</a><br>"; awa ...

Using jQuery to add or remove multiple classes at once

My navigation tabs use jQuery to add and remove classes for the active tab. However, I'm facing an issue where the active class is not removed when a new tab is clicked or when the user scrolls to a new section. Please refer to the following gist for ...

Placing an eye icon on the password input field for optimal visibility and positioning

I am currently working on a Node.js project and I am attempting to incorporate an eye icon using Bootstrap into the password input field for visibility. Below is the code snippet of my input field: <div class="container"> <form ...

Activate an event on a shadow DOM element that is covered by an element in the light DOM (not directly related)

I am currently facing a challenge in retrieving the coordinates of a table cell within a shadow DOM. This table cell may have overlay elements displayed above it, which could span over multiple cells and may not necessarily be direct children of the cell I ...