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

The MuiPrivateTabScrollButton alters the dimensions and flexibility properties using CSS

I have been facing a challenge with overwriting the css of MuiPrivateTabScrollButton. Since this class is generated from material ui, I am unable to successfully overwrite it. Despite debugging and trying various fixes such as adding border colors, I still ...

Upon the second click, the addEventListener function is triggered

When using the window.addEventListener, I am encountering an issue where it only triggers on the second click. This is happening after I initially click on the li element to view the task information, and then click on the delete button which fires the eve ...

The CSS filter "progid:DXImageTransform.Microsoft.Alpha(style=1,opacity=80)" is not functioning properly in Firefox

Trying to apply a filter effect using CSS but encountering issues in Firefox: progid:DXImageTransform.Microsoft.Alpha(style=1,opacity=80 ) opacity: 0.5; -moz-opacity: 0.5; Any s ...

Establishing updated file path for resources in JavaScript based on environment

I'm currently facing an issue with my external Javascript file that uses the getScript() function to execute another JS file. Both files are located on static.mydomain.com, as I am trying to set up a Content Delivery Network (CDN) for the first time. ...

How can I target all ul elements except those contained within a div with a specific class using CSS?

In my global.scss file, I have defined global styles for ul elements as shown below: ul { list-style: none; margin: 0; padding: 0; } However, I am trying to find a way to style all ul elements except those within a specific jodit-wrapper class ...

How can I align text to the center and set the text color at the same

Looking to place text in the center of a colored box? Although attempting to center the text, you may find that it remains towards the top rather than in the middle of the box. How can you shift the text down so it aligns with the middle of the backgroun ...

Review Limited Screen Size for a Smartphone Website

I have been working on optimizing a mobile website and I utilized CSS to adjust the layout design for screen widths between 150px and 480px. However, during testing on an actual phone, the desktop layout is appearing instead of the custom layout set with C ...

The focusable attribute in SVG is malfunctioning

I've utilized the focusable attribute to ensure SVG elements receive focus within an HTML document. My goal is to navigate through SVG elements in the SVG tag using the TAB key, as indicated in this resource (http://www.w3.org/TR/SVGTiny12/interact.h ...

Incorporating CSS and JS files into a WordPress theme

To incorporate Css & Js files into my website pages, I plan to insert the following code into the functions.php file: function cssjsloading(){ wp_enqueue_style('bootstrap-rtl', get_template_directory_uri() . '/css/bootstrap-rtl.css&apo ...

Adjusting the decimal points of numbers within a table to create the illusion of a "centered" alignment within the cell

Looking for a table design featuring a column of decimal numbers, each with varying lengths before and after the decimal point, while keeping the decimal points aligned. The width of the column should be flexible, expanding to accommodate long numbers in ...

Alter the CSS display based on the user's userAgent if they are using an iPhone and window.navigator.standalone is set to true

Looking to create a unique webAPP with different content displays based on how it is accessed. If the user opens the webAPP through their Safari browser Or if they open the webAPP from a webclip on their home screen The detection is functioning, as conf ...

Which is better for cycling through a list of items: CSS or JavaScript?

Currently, I have a navigation bar set up as an unordered list (<ul>), but some list items are not visible. I want to implement functionality where clicking arrows will move the elements left or right by hiding or showing the leftmost or rightmost it ...

How can I restrict the number of items displayed in each row within a navigation submenu flexbox?

My primary navigation menu has numerous child items, and I want to ensure they remain visually appealing and organized. To achieve this, I am aiming to limit each row of submenu items to only 4. After researching other solutions online, I attempted adding ...

Is it a bug that using addClass or toggleClass with JQuery inside a click method does not seem to be functioning properly?

This appears to be a simple issue, yet it is not functioning correctly. I managed to make it work by placing the .normal class above the .highlight class, despite only adjusting the position and not altering the style. This lack of logic is puzzling. Sin ...

How can I implement a hover-over image change effect similar to the one seen in Gmail accounts?

I am attempting to implement a feature that allows users to change their image, similar to what can be done in a GMail account. When the user hovers over the image, an option to "change image" should appear. This may be a new concept for me because I am ...

Switching from real pixels to CSS pixels

The details provided in Mozilla's documentation on elementFromPoint clarify that the coordinates are specified in "CSS pixels" rather than physical pixels. This raises a question about what exactly CSS pixels entail. Many assume that a pixel in CSS is ...

What are the steps to ensure that data retrieved from an API is accurately displayed in a table?

My current goal is to collect data from the crypto compare API and display it in a table format. Although I am able to generate the necessary elements and append them to the table body, I am facing an unusual issue. Each time I use a for loop to iterate th ...

The background color of the body is being utilized by Div in Internet Explorer version 7

Within my HTML document, I have created a container div that holds several nested divs for a slideshow effect. This "container" div is positioned over the background image of the body element. The CSS styling for the body element is as follows: body { ba ...

Create spacing on the right side of a div with Bootstrap 4 offset, instead of the typical left side offset

Looking for a solution in Bootstrap 4 that mirrors the offset feature in Bootstrap 3, but pushes a div to the left instead of right. Need a way to have multiple dynamic divs within a row, where one div is pushed to the left on its own row without the nee ...

Position a div in the center both horizontally and vertically within a section, ensuring that each section expands to fill the entire page when scrolling

I'm currently working on coding a page layout where each section takes up the entire screen. My goal is to have the content within each section centered both vertically and horizontally. I'm unsure if this is achievable, so any guidance or advice ...