J'essaie de recréer cette image avec CSS:
Je n'aurais pas besoin de le répéter. C'est ce que j'ai commencé mais il a juste une ligne droite:
#wave {
position: absolute;
height: 70px;
width: 600px;
background: #e0efe3;
}
<div id="wave"></div>
Je ne suis pas sûr que ce soit votre forme, mais elle est proche - vous pouvez jouer avec les valeurs:
#wave {
position: relative;
height: 70px;
width: 600px;
background: #e0efe3;
}
#wave:before {
content: "";
display: block;
position: absolute;
border-radius: 100% 50%;
width: 340px;
height: 80px;
background-color: white;
right: -5px;
top: 40px;
}
#wave:after {
content: "";
display: block;
position: absolute;
border-radius: 100% 50%;
width: 300px;
height: 70px;
background-color: #e0efe3;
left: 0;
top: 27px;
}
<div id="wave"></div>
Je pense que c'est la bonne façon de créer une forme comme vous le souhaitez. En utilisant les possibilités SVG et un conteneur pour garder la forme sensible.
svg {
display: inline-block;
position: absolute;
top: 0;
left: 0;
}
.container {
display: inline-block;
position: relative;
width: 100%;
padding-bottom: 100%;
vertical-align: middle;
overflow: hidden;
}
<div class="container">
<svg viewBox="0 0 500 500" preserveAspectRatio="xMinYMin meet">
<path d="M0,100 C150,200 350,0 500,100 L500,00 L0,0 Z" style="stroke: none; fill:red;"></path>
</svg>
</div>
Mon implémentation CSS pure basée sur ce qui précède avec une largeur de 100%. J'espère que ça aide!
#wave-container {
width: 100%;
height: 100px;
overflow: hidden;
}
#wave {
display: block;
position: relative;
height: 40px;
background: black;
}
#wave:before {
content: "";
display: block;
position: absolute;
border-radius: 100%;
width: 100%;
height: 300px;
background-color: white;
right: -25%;
top: 20px
}
#wave:after {
content: "";
display: block;
position: absolute;
border-radius: 100%;
width: 100%;
height: 300px;
background-color: black;
left: -25%;
top: -240px;
}
<div id="wave-container">
<div id="wave">
</div>
</div>
Mon implémentation utilise l’élément svg en html et j’ai également créé un générateur pour créer l’onde souhaitée:
https://smooth.ie/blogs/news/svg-wavey-transitions-between-sections
<div style="height: 150px; overflow: hidden;">
<svg viewBox="0 0 500 150" preserveAspectRatio="none" style="height: 100%; width: 100%;">
<path d="M0.00,92.27 C216.83,192.92 304.30,8.39 500.00,109.03 L500.00,0.00 L0.00,0.00 Z" style="stroke: none;fill: #e1efe3;"></path>
</svg>
</div>
Voici un autre moyen de le faire :) Le concept est de créer un polygone de tracé de tracé avec la vague comme un côté.
Cette approche est assez flexible. Vous pouvez changer la position (gauche, droite, haut ou bas) dans laquelle apparaît l’onde, changer la fonction d’onde en n’importe quelle fonction (t) qui correspond à [0,1]). Le polygone peut également être utilisé pour la forme extérieure, ce qui permet au texte de circuler autour de la vague dans l'orientation «gauche» ou «droite».
À la fin, vous pouvez commenter un exemple illustrant l’animation de la vague.
function PolyCalc(f /*a function(t) from [0, infinity) => [0, 1]*/,
s, /*a slice function(y, i) from y [0,1] => [0, 1], with slice index, i, in [0, n]*/
w /*window size in seconds*/,
n /*sample size*/,
o /*orientation => left/right/top/bottom - the 'flat Edge' of the polygon*/
)
{
this.polyStart = "polygon(";
this.polyLeft = this.polyStart + "0% 0%, "; //starts in the top left corner
this.polyRight = this.polyStart + "100% 0%, "; //starts in the top right corner
this.polyTop = this.polyStart + "0% 0%, "; // starts in the top left corner
this.polyBottom = this.polyStart + "0% 100%, ";//starts in the bottom left corner
var self = this;
self.mapFunc = s;
this.func = f;
this.window = w;
this.count = n;
var dt = w/n;
switch(o) {
case "top":
this.poly = this.polyTop; break;
case "bottom":
this.poly = this.polyBottom; break;
case "right":
this.poly = this.polyRight; break;
case "left":
default:
this.poly = this.polyLeft; break;
}
this.CalcPolygon = function(t) {
var p = this.poly;
for (i = 0; i < this.count; i++) {
x = 100 * i/(this.count-1.0);
y = this.func(t + i*dt);
if (typeof self.mapFunc !== 'undefined')
y=self.mapFunc(y, i);
y*=100;
switch(o) {
case "top":
p += x + "% " + y + "%, "; break;
case "bottom":
p += x + "% " + (100-y) + "%, "; break;
case "right":
p += (100-y) + "% " + x + "%, "; break;
case "left":
default:
p += y + "% " + x + "%, "; break;
}
}
switch(o) {
case "top":
p += "100% 0%)"; break;
case "bottom":
p += "100% 100%)";
break;
case "right":
p += "100% 100%)"; break;
case "left":
default:
p += "0% 100%)"; break;
}
return p;
}
};
var text = document.querySelector("#text");
var divs = document.querySelectorAll(".wave");
var freq=2*Math.PI; //angular frequency in radians/sec
var windowWidth = 1; //the time domain window which determines the range from [t, t+windowWidth] that will be evaluated to create the polygon
var sampleSize = 60;
divs.forEach(function(wave) {
var loc = wave.classList[1];
var polyCalc = new PolyCalc(
function(t) { //The time domain wave function
return (Math.sin(freq * t) + 1)/2; //sine is [-1, -1], so we remap to [0,1]
},
function(y, i) { //slice function, takes the time domain result and the slice index and returns a new value in [0, 1]
return MapRange(y, 0.0, 1.0, 0.65, 1.0); //Here we adjust the range of the wave to 'flatten' it out a bit. We don't use the index in this case, since it is irrelevant
},
windowWidth, //1 second, which with an angular frequency of 2pi rads/sec will produce one full period.
sampleSize, //the number of samples to make, the larger the number, the smoother the curve, but the more pionts in the final polygon
loc //the location
);
var polyText = polyCalc.CalcPolygon(0);
wave.style.clipPath = polyText;
wave.style.shapeOutside = polyText;
wave.addEventListener("click",function(e) {document.querySelector("#polygon").innerText = polyText;});
});
function MapRange(value, min, max, newMin, newMax) {
return value * (newMax - newMin)/(max-min) + newMin;
}
//Animation - animate the wave by uncommenting this section
//Also demonstrates a slice function which uses the index of the slice to alter the output for a dampening effect.
/*
var t = 0;
var speed = 1/180;
var polyTop = document.querySelector(".top");
var polyTopCalc = new PolyCalc(
function(t) {
return (Math.sin(freq * t) + 1)/2;
},
function(y, i) {
return MapRange(y, 0.0, 1.0, (sampleSize-i)/sampleSize, 1.0);
},
windowWidth, sampleSize, "top"
);
function animate() {
var polyT = polyTopCalc.CalcPolygon(t);
t+= speed;
polyTop.style.clipPath = polyT;
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
*/
div div {
padding:10px;
/*overflow:scroll;*/
}
.left {
height:100%;
width:35%;
float:left;
}
.right {
height:200px;
width:35%;
float:right;
}
.top {
width:100%;
height: 200px;
}
.bottom {
width:100%;
height:200px;
}
.green {
background:linear-gradient(to bottom, #b4ddb4 0%,#83c783 17%,#52b152 33%,#008a00 67%,#005700 83%,#002400 100%);
}
.mainContainer {
width:100%;
float:left;
}
#polygon {
padding-left:20px;
margin-left:20px;
width:100%;
}
<div class="mainContainer">
<div class="wave top green">
Click to see the polygon CSS
</div>
<!--div class="wave left green">
</div-->
<!--div class="wave right green">
</div-->
<!--div class="wave bottom green"></div-->
</div>
<div id="polygon"></div>