SVG and CSS create realistic cloud effects
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"><code><fedisplacementmap in="SourceGraphic" scale="180"></fedisplacementmap></code></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"> <code>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; }</code></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"> <code>#cloud-circle { width: 500px; height: 275px; background: #000; border-radius: 50%; filter: url(#filter); box-shadow: 200px 200px 60px 0px #fff; }</code></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"> <code>#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; /* 向右移动*/ }</code></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"><code><svg height="0" width="0"><filter><feturbulence basefrequency="0.012" numoctaves="4" type="fractalNoise"></feturbulence><fedisplacementmap in="SourceGraphic" scale="170"></fedisplacementmap></filter><filter><feturbulence basefrequency="0.012" numoctaves="2" type="fractalNoise"></feturbulence><fedisplacementmap in="SourceGraphic" scale="150"></fedisplacementmap></filter><filter><feturbulence basefrequency="0.012" numoctaves="2" type="fractalNoise"></feturbulence><fedisplacementmap in="SourceGraphic" scale="100"></fedisplacementmap></filter></svg></code></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!

What it looks like to troubleshoot one of those impossible issues that turns out to be something totally else you never thought of.

@keyframesandCSSTransitionsdifferincomplexity:@keyframesallowsfordetailedanimationsequences,whileCSSTransitionshandlesimplestatechanges.UseCSSTransitionsforhovereffectslikebuttoncolorchanges,and@keyframesforintricateanimationslikerotatingspinners.

I know, I know: there are a ton of content management system options available, and while I've tested several, none have really been the one, y'know? Weird pricing models, difficult customization, some even end up becoming a whole &

Linking CSS files to HTML can be achieved by using elements in part of HTML. 1) Use tags to link local CSS files. 2) Multiple CSS files can be implemented by adding multiple tags. 3) External CSS files use absolute URL links, such as. 4) Ensure the correct use of file paths and CSS file loading order, and optimize performance can use CSS preprocessor to merge files.

Choosing Flexbox or Grid depends on the layout requirements: 1) Flexbox is suitable for one-dimensional layouts, such as navigation bar; 2) Grid is suitable for two-dimensional layouts, such as magazine layouts. The two can be used in the project to improve the layout effect.

The best way to include CSS files is to use tags to introduce external CSS files in the HTML part. 1. Use tags to introduce external CSS files, such as. 2. For small adjustments, inline CSS can be used, but should be used with caution. 3. Large projects can use CSS preprocessors such as Sass or Less to import other CSS files through @import. 4. For performance, CSS files should be merged and CDN should be used, and compressed using tools such as CSSNano.

Yes,youshouldlearnbothFlexboxandGrid.1)Flexboxisidealforone-dimensional,flexiblelayoutslikenavigationmenus.2)Gridexcelsintwo-dimensional,complexdesignssuchasmagazinelayouts.3)Combiningbothenhanceslayoutflexibilityandresponsiveness,allowingforstructur

What does it look like to refactor your own code? John Rhea picks apart an old CSS animation he wrote and walks through the thought process of optimizing it.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

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

Hot Article

Hot Tools

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft

Notepad++7.3.1
Easy-to-use and free code editor

SAP NetWeaver Server Adapter for Eclipse
Integrate Eclipse with SAP NetWeaver application server.

SublimeText3 Mac version
God-level code editing software (SublimeText3)

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment
