惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
V2EX
C
Check Point Blog
博客园 - Franky
月光博客
月光博客
T
Tenable Blog
博客园 - 聂微东
Cyberwarzone
Cyberwarzone
The GitHub Blog
The GitHub Blog
C
CERT Recently Published Vulnerability Notes
Scott Helme
Scott Helme
IT之家
IT之家
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
CXSECURITY Database RSS Feed - CXSecurity.com
F
Full Disclosure
博客园 - 司徒正美
Project Zero
Project Zero
Y
Y Combinator Blog
A
Arctic Wolf
美团技术团队
博客园 - 叶小钗
S
Securelist
F
Fortinet All Blogs
T
Threatpost
T
Threat Research - Cisco Blogs
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
酷 壳 – CoolShell
酷 壳 – CoolShell
MyScale Blog
MyScale Blog
大猫的无限游戏
大猫的无限游戏
Recorded Future
Recorded Future
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
S
Schneier on Security
Apple Machine Learning Research
Apple Machine Learning Research
L
LangChain Blog
P
Privacy International News Feed
博客园_首页
S
SegmentFault 最新的问题
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
腾讯CDC
P
Proofpoint News Feed
Cisco Talos Blog
Cisco Talos Blog
AWS News Blog
AWS News Blog
阮一峰的网络日志
阮一峰的网络日志
G
Google Developers Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
雷峰网
雷峰网
P
Proofpoint News Feed
Latest news
Latest news
G
GRAHAM CLULEY

CSS Articles by Temani Afif

Get Ready For the Powerful CSS border-shape Property! | CSS-Tricks Let’s Play With Gap Decorations! How to Control Infinite CSS Animations (Part 2 of 2) How to Control Infinite CSS Animations (Part 1 of 2) Two Circles, One Arrow, and Anchor Positioning Making a Responsive Pyramidal Grid With Modern CSS | CSS-Tricks How to Create a CSS-only Elastic Text Effect Making Complex CSS Shapes Using shape() | CSS-Tricks Responsive Hexagon Grid Using Modern CSS | CSS-Tricks Responsive List of Avatars Using Modern CSS (Part 2) | CSS-Tricks Responsive List of Avatars Using Modern CSS (Part 1) | CSS-Tricks Perfectly Pointed Tooltips: To The Corners Perfectly Pointed Tooltips: All Four Sides Perfectly Pointed Tooltips: A Foundation Sequential linear() Animation With N Elements | CSS-Tricks Infinite Marquee Animation using Modern CSS Better CSS Shapes Using shape() — Part 4: Close and Move | CSS-Tricks Drawing CSS Shapes using corner-shape Better CSS Shapes Using shape() — Part 3: Curves | CSS-Tricks Better CSS Shapes Using shape() — Part 2: More on Arcs | CSS-Tricks Better CSS Shapes Using shape() — Part 1: Lines and Arcs | CSS-Tricks Creating Blob Shapes using clip-path: shape() Creating Flower Shapes using clip-path: shape() Custom progress element using the attr() function A CSS-Only Star Rating Component and More! (Part 2) | CSS-Tricks A CSS-Only Star Rating Component and More! (Part 1) | CSS-Tricks How to Create Wavy Boxes Using CSS Full-Bleed Layout with Modern CSS Fancy Menu Navigation Using Anchor Positioning | CSS-Tricks How to Create a Zig-Zag Box Using CSS How to Create Zig-Zag CSS Loaders Using One Element Custom Progress Element Using Anchor Positioning & Scroll-Driven Animations How to Create Filling CSS Loaders Using One Element How to Create Curved-Edge and Rounded-Edge Shapes Using CSS CSS Tricks That Use Only One Gradient | CSS-Tricks How to create Shapes with Inner Curves using CSS Mask Custom Range Slider Using Anchor Positioning & Scroll-Driven Animations How to Get the Width/Height of Any Element in Only CSS How Keyboard Navigation Works in a CSS Game How To Create Cut-Out Shapes using The clip-path property The Modern Guide For Making CSS Shapes — Smashing Magazine css-shape.com: The Ultimate Collection of CSS-only Shapes ⚡️ Sliding 3D Image Frames In CSS — Smashing Magazine CSS Tricks To Master The clip-path Property Modern CSS Tooltips And Speech Bubbles (Part 2) — Smashing Magazine Do you need a Tooltip or a Speech Bubble? I have created 100 using CSS 😲 Modern CSS Tooltips And Speech Bubbles (Part 1) — Smashing Magazine Creating Flower Shapes using CSS Mask & Trigonometric Functions CSS Shapes: The Triangle The Complex But Awesome CSS border-image Property — Smashing Magazine CSS Tricks to add 3D Effects to your Text CSS Responsive Multi-Line Ribbon Shapes (Part 2) — Smashing Magazine CSS Responsive Multi-Line Ribbon Shapes (Part 1) — Smashing Magazine I have made 100+ CSS-only Ribbon Shapes | The Perfect Collection 🎀 How to create a CSS-only infinite scroll animation Re-Creating The Pop-Out Hover Effect With Modern CSS (Part 2) — Smashing Magazine Re-Creating The Pop-Out Hover Effect With Modern CSS (Part 1) — Smashing Magazine How to Create CSS Ribbon Shapes with a Single Element CSS Shapes: The Ribbon Revealing Images With CSS Mask Animations — Smashing Magazine css-loaders.com: The Biggest Collection of Loading Animations (more than 500 🤯) How To Define An Array Of Colors With CSS — Smashing Magazine CSS effects on images II Shines, Perspective, And Rotations: Fancy CSS 3D Effects For Images — Smashing Magazine What's your Lucky CSS Pattern? Check It Now! How to Add a CSS Reveal Animation to Your Images Modern Layouts using CSS Grid I created 100+ unique CSS patterns | The best collection 🤩 How to Create a Custom Range Slider Using CSS CSS Shapes: The Heart CSS Shapes: Polygon & Starburst A Text Reveal Animation using CSS CSS Tip: learn CSS the easy way! How to build a CSS-only accordion How to create Breadcrumb Navigation with CSS Different Ways to Get CSS Gradient Shadows | CSS-Tricks A CSS-only responsive Stepper component A Fancy Hover Effect For Your Avatar | CSS-Tricks How to make a zoom effect using CSS Creating a Custom Cursor using CSS CSS Infinite 3D Sliders | CSS-Tricks CSS Infinite Slider Flipping Through Polaroid Images | CSS-Tricks How to create a responsive sidebar menu using CSS CSS Infinite and Circular Rotating Image Slider | CSS-Tricks Making Static Noise From a Weird CSS Gradient Bug | CSS-Tricks CSS Grid and Custom Shapes, Part 3 | CSS-Tricks Fancy Image Decorations: Outlines and Complex Animations | CSS-Tricks Fancy Image Decorations: Masks and Advanced Hover Effects | CSS-Tricks Fancy Image Decorations: Single Element Magic | CSS-Tricks How to create an infinite image slider using CSS How to Create Wavy Shapes & Patterns in CSS | CSS-Tricks How I Made a Pure CSS Puzzle Game | CSS-Tricks How to create a Tooltip/Speech Bubble using CSS CSS Grid and Custom Shapes, Part 2 | CSS-Tricks CSS Grid and Custom Shapes, Part 1 | CSS-Tricks Zooming Images in a Grid Layout | CSS-Tricks How to create a CSS-only loader with one element Exploring CSS Grid’s Implicit Grid and Auto-Placement Powers | CSS-Tricks How to create background pattern using CSS & conic-gradient Single Element Loaders: The Bars | CSS-Tricks
Creating Wavy Circles with Fancy Animations in CSS
Temani Afif on March 15, 2024 · 2024-03-15 · via CSS Articles by Temani Afif

In a previous article, we created flower-like shapes using modern CSS (mask, trigonometric functions, etc). This article is a follow-up where we will create a similar shape and also introduce some fancy animations.

Article Series

Here is a demo of what we are building. Hover the image to see the animation

Cool right? If you check the HTML tab you won’t see a lengthy code structure. A single image element is all that we will be using to build that complex-looking effect. Don’t look at the CSS for now and let’s build this together.

You can also take a look at my online generator where you can easily generate the CSS code for those wavy circles.

Creating The Shape

It’s highly recommended that you read the previous article because I will be building on top of it. I will be reusing many tricks and the starting point of this article will be the last demo of the previous one.

And here is a figure to remind you the mask composition used to create the shape.

As you can see, a set of small circles is used in the “subtract” composition to create the inner curves, and another set of small circles is used in the “add” composition to create the outer curves. The idea is to move those circles in opposite directions to create and control our wavy circle.

Here is another figure to illustrate the trick

the differentd colored circles make the blob shape, and as they move around the blob changes shape.

The [1] above illustrates the initial shape where all the small circles are aligned in a way to create a bigger circle while touching each other. The red circles are the excluded ones and the blue circles are the added ones.

In [2] above we make the blue circles closer to the center while moving the red ones in the opposite direction. The result is weird because the circles no longer touch each other but if we increase their radius, we get a perfect result.

The idea is to move the circles and at the same time adjust their radius so they are always touching each other. Here is an interactive demo to better understand the movement of the circles. Use the slider to control the position of the circles.

Let’s write some code

Now that we have the geometry of shape in place, let’s translate this into code. It wasn’t an easy task at all. Finding the right formulas and translating everything into a CSS code was a bit tricky.

The first challenge is to find one variable that allows me to control the position of the small circles and at the same time their radius. I could have used multiple variables but having only one variable will make the shape easy to control as we only have to update one value and everything else will follow.

Initially, I thought about using a length variable which is logical since the radius can be expressed as a length and to move the circles I need a distance which is also a length. I wasn’t able to follow that root because finding the formulas and expressing them using CSS was almost impossible. Instead of a length I had to rely on an angle variable. It may sound wrong but it was indeed the right way to do it as I was able to find most of the formulas and write them using CSS.

Here is a figure to illustrate the angle I am referring to.

update to the angle between circles.

Let’s take two adjacent circles and draw a line between their center (illustrated in white). The [1] shows the initial shape where all the circles are perfectly aligned around the big circle. This will be the initial state so let’s consider we have an angle equal to 0deg. When we move the circles and get the shape in [2] the line will rotate a little and the angle of rotation will be our variable.

Don’t worry, I won’t start a boring geometry course. I just wanted to highlight the variable you need to adjust so you can visualize why it’s an angle and the angle of what. By the way, in the last interactive demo, you are adjusting that angle using the range slider.

Here is the full demo where you can play with the different values to control the shape.

If you want to dig into the math, check this question on StackExchange Mathematics. I struggled with some of the formulas so I had to ask some math gurus.

Introducing The Image Element

Let’s now consider an <img> element instead of a <div>.

It works fine but our goal is to have the image within the shape like the first example. To do this, we add some padding (or border) to leave space for the background and also add border-radius to round the image.

Now it’s perfect! I am using a padding value equal to .4*var(--r) but there is no particular logic behind it. It’s what gives me something that looks good to me. Feel free to update it if you want to increase or decrease the space around the image.

Adding The Animation

Let’s move to the interesting part which is the animation. We will first adjust the shape on hover and this is the easiest part because we already did the hard job by finding one variable to control the shape. All we have to do is to update that variable on hover.

img {
  --a: 28deg;
}
img:hover {
  --a: 10deg;
}Code language: CSS (css)

The above will simply change the shape but will not give us a smooth animation it is because by default we cannot animate CSS variables (custom properties). To do this we need to register them using @property.

@property --a {
  syntax: "<angle>";
  inherits: true;
  initial-value: 0deg;
}Code language: CSS (css)

Then add a transition like below

img {
  transition: --a .3s
}Code language: CSS (css)

Now we have a perfect hover effect!

Let’s tackle the rotation. It’s clear that we cannot rotate the whole element as the image needs to remain straight and only the shape needs to rotate. To do this, we will introduce a new angle variable and use it within the formulas that define the position of the circles.

If you look at the Sass loop that generates the code of the circles, you will notice that the increment $i is used to define an angle, and this angle is used to correctly place each circle. If we update that angle, we update the position. The idea is to update the angle of all the circles with the same value so they all move the same way to simulate a rotation.

In the demo above, you will see I am registering a new variable and applying an animation to it

@property --o {
  syntax: "<angle>";
  inherits: true;
  initial-value: 0deg;
}
img {
  animation: rotate 20s infinite linear;
}
@keyframes rotate {
  to { --o: 360deg; }
}Code language: CSS (css)

Then I am using that variable within the Sass loop to update the angle of the circles. Instead of 360deg*#{$i/$n}, we use 360deg*#{$i/$n} + var(--o) and instead of (360deg*#{$i} + 180deg)/#{$n} we use (360deg*#{$i} + 180deg)/#{$n} + var(--o).

The final touch is to increase the speed of the rotation on hover. For this, I am going to introduce the animation-composition property. It’s a pretty new propery so you may have not heard about it, but it’s a powerful property that I invite you to explore. Plus the browser support is pretty good.

I will update the code of the animation like below:

img {
  animation: 
    rotate 20s infinite linear,
    rotate 20s infinite linear paused;
  animation-composition: add
}
img:hover {
  animation-play-state: running;
}Code language: CSS (css)

I am applying the same animation twice while making the second one paused. On hover, both animations are running. Let’s have a look at the definition of animation-composition: add

The animation-composition CSS property specifies the composite operation to use when multiple animations affect the same property simultaneously.

Then:

add
The effect value builds on the underlying value of the property. This operation produces an additive effect.

We are using the same animation so we are affecting the same property (the variable --o) and the use of add will create an additive effect. It means that the element will rotate faster when both animations are running.

Try it!

The concept of animation-composition is not easy to grasp at first glance, but imagine that you add an animation on the top of another one. The first animation is rotating the element then we add another animation that will also rotate the element. If you rotate an element that is already rotating then you get a faster rotation. We can also decrease the rotation speed using the same technique. This time, the second animation needs to apply an opposite rotation using the reverse keywords.

Conclusion

We are done! We created a complex-looking effect using only CSS and a single HTML element. It was a good opportunity to explore modern CSS features such as mask, trigonometric functions, @property, etc

You are probably thinking it’s a bit too much, right? What’s the point of introducing all this complexity for a fancy effect that you will probably never use? The goal is not really to build the effect and use it but to push the limit of CSS and explore new features. In the end, you have a bunch of CSS tricks that you can use elsewhere.

We learned how to use mask-composite. We learned how to animate CSS variables using @property. We played with gradients. We discovered the animation-composition property. etc. One day, you will for sure need to use those CSS tricks!

Article Series