search
HomeWeb Front-endCSS TutorialDrawing Realistic Clouds with SVG and CSS

SVG and CSS create realistic cloud effects

Drawing Realistic Clouds with SVG and CSS

In Greek mythology, Zeus created the Cloud Fairy Nefere. Like other Greek myths, this story is quite bizarre. Here is a short and suitable version:

According to legend, Neferele was created by Zeus in the image of his beautiful wife. A mortal met Nefere and fell in love with her. Together they... In the end, incredible that this cloud gave birth to a half-man and half-male centaur baby.

Very strange, right? I personally can't understand. Fortunately, the process of creating clouds in a browser is much simpler and more serious.

Recently, I found that developer Yuan Chuan has implemented a realistic cloud effect generated by code. For me, this effect that was implemented in the browser was once a myth.

Just browse this sample code and we can imagine that by using<filter></filter> CSS box-shadow of elements (including two SVG filters) can achieve a convincing single cloud effect.

The realistic effect we want is achieved through the clever combination of feTurbulence and feDisplacementMap . These SVG filters are powerful, complex and offer very exciting features (including an Oscar-winning algorithm!). However, its underlying complexity can be daunting.

While the physics of SVG filters are beyond the scope of this article, there is a lot of documentation available on MDN and w3.org. Very helpful pages about feTurbulence and feDisplacementMap are available for free (and as a chapter in this wonderful book).

In this article, we will focus on learning how to use these SVG filters to achieve amazing results. We don’t need to get a deeper look at how the algorithms behind the scenes work, just as artists don’t need to understand the molecular structure of pigments to render amazing landscapes.

Instead, let's keep an eye on several SVG properties that are crucial to drawing convincing clouds in your browser. Using these properties, we can use these powerful filters with ease and learn how to customize them accurately in our projects.

Start with the basics

There are five values ​​worth paying attention to in the CSS box-shadow attribute:

 <code>box-shadow:<offsetx><offsety><blurradius><spreadradius><color> ;</color></spreadradius></blurradius></offsety></offsetx></code>

Let's turn these values ​​up (probably higher than any sensible developer would use) so that the shadow itself becomes a character on the stage.

 <code>#cloud-square { background: turquoise; box-shadow: 200px 200px 50px 0px #000; width: 180px; height: 180px; } #cloud-circle { background: coral; border-radius: 50%; box-shadow: 200px 200px 50px 0px #000; width: 180px; height: 180px; }</code>

Have you ever played or seen shadow dramas?

Just like changing the shape with your hands to change the shadow, the "source shape" in our HTML can be moved and deformed to move and change the shape of the shadow rendered in the browser. box-shadow copies the original size and "transform" functionality on border-radius . SVG filters are applied to elements and their shadows at the same time.

<code><svg height="0" width="0"><filter><feturbulence basefrequency=".01" numoctaves="10" type="fractalNoise"></feturbulence><fedisplacementmap in="SourceGraphic" scale="10"></fedisplacementmap></filter></svg></code>

This is the markup for our current SVG. It won't render because we haven't defined any visuals (not to mention zero width and height). Its sole purpose is to save a filter, which we provide to our SourceGraphic (that is, ours<div> ). Our Source<code><div> Its shadows are distorted independently by the filter. We will add the necessary CSS rules, linking the HTML element ( <code>#cloud-circle ) to the SVG filter using its ID:

 <code>#cloud-circle { filter: url(#filter); box-shadow: 200px 200px 50px 0px #fff; }</code>

Look!

OK, admit it, adding SVG filters is quite inconspicuous.

don’t worry! We just touched the surface and there were a lot of good things to see.

Experiment feDisplacementMap scale property

Performing some non-scientific experiments on this attribute can produce dramatic effects. For the moment, let's keep all values ​​in feTurbulence unchanged, just adjust scale property of DisplacementMap .

As scale value increases (in 30 increments), our source<div> Distortions occur and shadows are cast to reflect the random form of clouds in the sky.<pre class="brush:php;toolbar:false">&lt;code&gt;&lt;fedisplacementmap in=&quot;SourceGraphic&quot; scale=&quot;180&quot;&gt;&lt;/fedisplacementmap&gt;&lt;/code&gt;</pre> <p> OK, we have made some progress! Let's change the color a little to create a more convincing cloud effect and enhance it.</p> <pre class="brush:php;toolbar:false"> &lt;code&gt;body { background: linear-gradient(165deg, #527785 0%, #7FB4C7 100%); } #cloud-circle { width: 180px; height: 180px; background: #000; border-radius: 50%; filter: url(#filter); box-shadow: 200px 200px 50px 0px #fff; }&lt;/code&gt;</pre> <p> Now we are closer to the realistic cloud effect!</p> <h3> Modify the <code>blur value of box-shadow

The following series of images shows the effect of blur value on box-shadow . Here, the blur value increases in 10 pixels increments.

To give our clouds some cumulus-like effect, we can broaden our source slightly<div> .<pre class="brush:php;toolbar:false"> &lt;code&gt;#cloud-circle { width: 500px; height: 275px; background: #000; border-radius: 50%; filter: url(#filter); box-shadow: 200px 200px 60px 0px #fff; }&lt;/code&gt;</pre> <p> etc! We widened the source element, and now it blocks the white shadow we call clouds. Let's "re-cast" the shadows to a longer distance so that our clouds are not obscured by the source image. (Imagine removing your hands from the wall so that you won't block the shadow drama's view.)</p> <p> This can be easily achieved with some CSS positioning.<code><div> It is the parent element of the cloud and is statically positioned by default. Let's use some absolute positioning to transfer our source<code><div> "Pull" it up and remove the document stream. Initially, this will also reposition our shadows, so we also need to increase the distance between the shadows and slightly adjust the position of the element.<pre class="brush:php;toolbar:false"> &lt;code&gt;#cloud-circle { width: 500px; height: 275px; background: #000; border-radius: 50%; filter: url(#filter); box-shadow: 400px 400px 60px 0px #fff; /* 增加阴影偏移量*/ position: absolute; /* 将父元素移出文档流*/ top: -320px; /* 向下移动*/ left: -320px; /* 向右移动*/ }&lt;/code&gt;</pre> <p> Yes! We have already got a pretty convincing cloud.</p> <p> The images rendered into the browser depict the clouds quite well - but, I'm not sure... Can this cloud really reflect the cloud fairy Neferre? I believe we can do better!</p> <h3 id="Express-depth-using-layers"> Express depth using layers</h3> <p> This is what we want:</p> <p> Judging from the depth, texture and richness of the clouds in this photo, one thing is clear: Zeus attended the art school. At least, he must have read The Universal Principles of Design, which expounds a powerful and seemingly ordinary concept:</p> <blockquote><p> […] Lighting deviation plays an important role in the interpretation of depth and sense of nature and can be operated in various ways by the designer…using the contrast between light and dark areas to change the appearance of depth.</p></blockquote> <p> This passage provides us with a clue on how we can greatly improve the cloud code we generate ourselves. We can render clouds that are highly similar to those in the reference image by stacking layers of different shapes, sizes, and colors together. This just requires calling our filter multiple times as needed. </p> <pre class="brush:php;toolbar:false">&lt;code&gt;&lt;svg height=&quot;0&quot; width=&quot;0&quot;&gt;&lt;filter&gt;&lt;feturbulence basefrequency=&quot;0.012&quot; numoctaves=&quot;4&quot; type=&quot;fractalNoise&quot;&gt;&lt;/feturbulence&gt;&lt;fedisplacementmap in=&quot;SourceGraphic&quot; scale=&quot;170&quot;&gt;&lt;/fedisplacementmap&gt;&lt;/filter&gt;&lt;filter&gt;&lt;feturbulence basefrequency=&quot;0.012&quot; numoctaves=&quot;2&quot; type=&quot;fractalNoise&quot;&gt;&lt;/feturbulence&gt;&lt;fedisplacementmap in=&quot;SourceGraphic&quot; scale=&quot;150&quot;&gt;&lt;/fedisplacementmap&gt;&lt;/filter&gt;&lt;filter&gt;&lt;feturbulence basefrequency=&quot;0.012&quot; numoctaves=&quot;2&quot; type=&quot;fractalNoise&quot;&gt;&lt;/feturbulence&gt;&lt;fedisplacementmap in=&quot;SourceGraphic&quot; scale=&quot;100&quot;&gt;&lt;/fedisplacementmap&gt;&lt;/filter&gt;&lt;/svg&gt;&lt;/code&gt;</pre> <p> Applying our layers will give us the opportunity to explore <code>feTurbulence and achieve its versatility. We will select the smoother type available: fractalNoise and turn numOctaves up to 6.

<code><feturbulence basefrequency="n" numoctaves="6" type="fractalNoise"></feturbulence></code>

what does that mean? Now, let's focus on baseFrequency property. Here is the result we get when we increase the value of n:

Words such as turbulence , noise , frequency , and octave can appear strange or even confusing. But don't worry! Comparing the effect of this filter to sound waves is actually completely accurate. We can associate low frequencies ( baseFrequency=0.001 ) with low noise and high frequencies ( baseFrequency=0.1 ) with higher, clearer tones.

We can see that for cumulus-like effects, the value of baseFrequency may comfortably lie in the ranges of ~0.005 and ~0.01.

Add details using numOctaves

Incrementing numOctaves allows us to render images with extremely fine details. This requires a lot of calculations, so be aware that high values ​​can seriously affect performance. Try to avoid increasing this value unless your browser is wearing a helmet and knee pads.

The good news is that we don't need to adjust this value too high to produce detail and fineness. As shown in the above image, we can set the numOctaves value to 4 or 5.

The results are as follows

Use seed attribute to achieve infinite changes

There is a lot to be said about seed attribute because it hints at the magic happening behind the scenes. However, for our purpose, the utility of seed can be summarized in four words: "different values, different shapes".

The Perlin noise function (mentioned earlier) uses this value as the starting point for its random number generator. Selecting not to include this property will default seed to zero. However, if this property is included, no matter what value we assign to seed , we don't need to worry about performance issues.

The above GIF represents some of the features provided by seed . Remember that each cloud is a layered composite cloud. (Although I've adjusted the properties of each layer, I keep their respective seed values ​​consistent.)

Here, carefully looking at the reference image, I have already put 3 clouds<div> (Different opacity) superimpose on a base<code><div> superior. By trial and error and inputting arbitrary <code>seed values, I ended up with a shape similar to the shape of a cloud in the photo.

Impressive

Of course, think we draw on the browser<div> Neferele who would be better than Zeus would be arrogant. However, the more mysteries we are able to dig out from CSS and SVG filters, the more we are able to create something visually amazing and highly similar to Thor’s original creation. Then, we can continue to conduct further experiments!<p> Reflected mist</p> <p> High-rise cirrus cloud</p> <p> In this article, we are just dabbing in a sea of ​​power and complexity. SVG filters usually look overwhelming and inaccessible.</p> <p> However, like the examples in the A Single Div project or Diana Smith's drawing skills, a relaxed and pleasant method of experiment always brings amazing results!</p> <h4 id="Achievement-unlocks-Neferre-Cloud-Generator"> Achievement unlocks! Neferre Cloud Generator</h4> <p> I believe many of you would be happy to dig deep into all the technical details needed to make clouds, but might prefer some more convenient ways to use clouds in your project. I developed a gadget to help generate clouds and experiment with shapes and changes.</p> <p> Generate clouds!</p> <p> Have any questions, suggestions or comments? Please contact me on Twitter or leave a comment in this post.</p> <p> <small>Thank you very much to Amelia Bellamy-Royds for your valuable suggestions on this article.</small></p> </div>

The above is the detailed content of Drawing Realistic Clouds with SVG and CSS. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Simulating Mouse MovementSimulating Mouse MovementApr 22, 2025 am 11:45 AM

If you've ever had to display an interactive animation during a live talk or a class, then you may know that it's not always easy to interact with your slides

Powering Search With Astro Actions and Fuse.jsPowering Search With Astro Actions and Fuse.jsApr 22, 2025 am 11:41 AM

With Astro, we can generate most of our site during our build, but have a small bit of server-side code that can handle search functionality using something like Fuse.js. In this demo, we’ll use Fuse to search through a set of personal “bookmarks” th

Undefined: The Third Boolean ValueUndefined: The Third Boolean ValueApr 22, 2025 am 11:38 AM

I wanted to implement a notification message in one of my projects, similar to what you’d see in Google Docs while a document is saving. In other words, a

In Defense of the Ternary StatementIn Defense of the Ternary StatementApr 22, 2025 am 11:25 AM

Some months ago I was on Hacker News (as one does) and I ran across a (now deleted) article about not using if statements. If you’re new to this idea (like I

Using the Web Speech API for Multilingual TranslationsUsing the Web Speech API for Multilingual TranslationsApr 22, 2025 am 11:23 AM

Since the early days of science fiction, we have fantasized about machines that talk to us. Today it is commonplace. Even so, the technology for making

Jetpack Gutenberg BlocksJetpack Gutenberg BlocksApr 22, 2025 am 11:20 AM

I remember when Gutenberg was released into core, because I was at WordCamp US that day. A number of months have gone by now, so I imagine more and more of us

Creating a Reusable Pagination Component in VueCreating a Reusable Pagination Component in VueApr 22, 2025 am 11:17 AM

The idea behind most of web applications is to fetch data from the database and present it to the user in the best possible way. When we deal with data there

Using 'box shadows' and clip-path togetherUsing 'box shadows' and clip-path togetherApr 22, 2025 am 11:13 AM

Let's do a little step-by-step of a situation where you can't quite do what seems to make sense, but you can still get it done with CSS trickery. In this

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.