How to animate concave rectangle to convex - css

I have created a rectangle of the following shape using sketch.
When I hover it I need to animate and rest as the below shape.
Is there a way I can animate it using css only from concave to convex.
Any help would be appreciated. I am fine with svg solution as well.
Here is the link to the fiddle for svg.
<svg width="641px" height="313px" viewBox="0 0 641 313" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 52.5 (67469) - http://www.bohemiancoding.com/sketch -->
<title>Concave</title>
<desc>Created with Sketch.</desc>
<defs>
<path d="M0,252.683363 C104.477953,274.894454 210.133596,286 316.966929,286 C423.800262,286 531.811286,274.894454 641,252.683363 L641,565 L0,565 L0,252.683363 Z" id="path-1"></path>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="iteration-3" transform="translate(-752.000000, -3299.000000)">
<g id="case--study" transform="translate(0.000000, 2766.000000)">
<g transform="translate(50.000000, 100.000000)" id="case--study--1-copy">
<g transform="translate(702.000000, 181.000000)">
<use id="bottom" fill="#000000" fill-rule="nonzero" xlink:href="#path-1"></use>
</g>
</g>
</g>
</g>
</g>
</svg>

For a CSS only solution I would consider a radial-gradient and some background animation:
.box {
height:50px;
width:600px;
padding-top:50px;
background:
/*concave*/
radial-gradient(410px 50px at 50% 0,transparent, 80%, #000 80.5%) center,
/*convexe*/
radial-gradient(410px 50px at 50% 50px,#000, 80%, transparent 80.5%)center,
linear-gradient(#000,#000) content-box;
background-size:100% 100%,100% 0px,auto;
background-repeat:no-repeat;
transition:1s all;
}
.box:hover {
background-size:100% 0,100% 100%,auto;
}
<div class="box"></div>
You can also have it for a full width rectangle:
.box {
height:50px;
padding-top:50px;
background:
/*concave*/
radial-gradient(70% 50px at 50% 0,transparent, 80%, #000 80.5%) center,
/*convexe*/
radial-gradient(70% 50px at 50% 50px,#000, 80%, transparent 80.5%)center,
linear-gradient(#000,#000) content-box;
background-size:100% 100%,100% 0px,auto;
background-repeat:no-repeat;
transition:1s all;
}
.box:hover {
background-size:100% 0,100% 100%,auto;
}
<div class="box"></div>
In case you will have a bigger height or dynamic height better consider a pseudo element so the effect won't get affected by height changing:
.box {
height: 80vh;
position: relative;
padding-top: 50px;
background: #000 content-box;
}
.box::before {
content: "";
position: absolute;
top: 1px;
left: 0;
right: 0;
padding: inherit;
background:
/*concave*/
radial-gradient(70% 50px at 50% 0, transparent, 80%, #000 80.5%) bottom,
/*convexe*/
radial-gradient(70% 50px at 50% 50px, #000, 80%, transparent 80.5%)bottom;
background-size: 100% 100%, 100% 0px;
background-repeat: no-repeat;
transition: 1s all;
}
.box:hover::before {
background-size: 100% 0, 100% 100%;
}
<div class="box"></div>
Update
You can also adjust the effect like below:
.box {
height: 80vh;
position: relative;
padding-top: 100px;
background: #000 content-box;
}
/*concave*/
.box::before {
content: "";
position: absolute;
top: 50px;
left: 0;
right: 0;
height: 51px;
background:
radial-gradient(70% 50px at 50% 0, transparent, 80%, #000 80.5%) top center;
background-size: 100% 200%;
background-repeat: no-repeat;
transition: 0.5s all 0.4s ease-out;
}
/*convexe*/
.box::after {
content: "";
position: absolute;
top: 1px;
left: 0;
right: 0;
height: 51px;
background:
radial-gradient(70% 50px at 50% 50px, #000, 80%, transparent 80.5%)bottom center;
background-size: 200% 0%;
background-repeat: no-repeat;
transition: 0.5s all ease-in;
}
.box:hover::before {
background-position: bottom center;
background-size: 200% 200%;
transition: 0.5s all ease-in;
}
.box:hover::after {
background-size: 100% 100%;
transition: 0.5s all 0.4s ease-out;
}
<div class="box"></div>

One solution could be to create the shape with SVG and then transition the path via CSS:
body {
width: 40vw;
display: block;
margin: 0 auto;
}
.path {
transition: d 2s ease-in-out;
}
.path:hover{
d: path('M0 20 Q 50 0 100 20 L100 60 L0 60 Z');
}
<svg viewBox="0 0 100 60" xmlns="http://www.w3.org/2000/svg">
<path class="path" d="M0 20 Q 50 40 100 20 L100 60 L0 60 Z" fill="black"/>
</svg>
<p>hover over the shape</p>

Related

CSS animation rendering - staggering

I have created this CodePen for a rotating border around a button and although the principle seems to be good, it is not working as it should - the rendering seems extremely slow and staggering (I have the M1 MacBook Pro).
.button {
width: 206px;
height: 70px;
line-height: 70px;
text-align: center;
position: relative;
}
.button::after {
content: "";
border-radius: 35px;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
clip-path: url(#mask);
border: 3px solid black;
}
.curve-1 {
animation: ʕ•̫͡•ʕ•̫͡•ʔ•̫͡•ʔ 20s infinite linear;
transform-origin: 35px center;
//animation-play-state: paused;
//transform: rotate(-315deg)
}
.curve-2 {
animation: ʕ•̫͡•ʕ•̫͡•ʔ•̫͡•ʔ•̫͡•ʔ•̫͡•ʔ 20s infinite linear;
transform-origin: 35px center;
translate: 136px 0;
}
.line {
animation: ʕ•̫͡•ʕ•̫͡•ʔ•̫͡•ʔ•̫͡•ʔ•̫͡•ʕ•̫͡•ʔ 20s infinite linear;
}
svg {
display: block;
}
#keyframes ʕ•̫͡•ʕ•̫͡•ʔ•̫͡•ʔ {
0% {
transform: rotate(45deg);
}
22% {
transform: rotate(-135deg);
}
27% {
transform: rotate(-180deg);
}
88% {
transform: rotate(-180deg);
}
89% {
transform: rotate(-225deg);
}
100% {
transform: rotate(-315deg);
}
}
#keyframes ʕ•̫͡•ʕ•̫͡•ʔ•̫͡•ʔ•̫͡•ʔ•̫͡•ʔ {
0% {
transform: rotate(0deg);
}
38% {
transform: rotate(0deg)
}
39% {
transform: rotate(-45deg);
}
50% {
transform: rotate(-135deg);
}
72% {
transform: rotate(-360deg);
}
100% {
transform: rotate(-360deg);
}
}
#keyframes ʕ•̫͡•ʕ•̫͡•ʔ•̫͡•ʔ•̫͡•ʔ•̫͡•ʕ•̫͡•ʔ {
0%, 100% {
width: 0;
x: 35px;
y: 35px;
}
11% {
width: 0;
x: 35px;
y: 35px;
}
22% {
width: 55px;
x: 35px;
y: 35px;
}
39% {
width: 55px;
x: 116px;
y: 35px;
}
50% {
width: 0;
x: 171px;
y: 35px;
}
61% {
width: 0;
x: 171px;
y: 0;
}
72% {
width: 55px;
x: 116px;
y: 0;
}
89% {
width: 55px;
x: 35px;
y: 0;
}
100% {
width: 0;
x: 35px;
y: 0;
}
}
<div class="button">button text</div>
<svg view-box="0 0 206 70" width="206" height="70">
<defs>
<clipPath id="mask">
<path d="M10.2513 10.1652C3.73208 16.8036 0.103643 25.7716 0.165885 35.0968C0.228128 44.422 3.97596 53.3408 10.5832 59.8905L35.1651 34.8632L10.2513 10.1652Z" fill="#000" class="curve-1"/>
<path d="M10.2513 10.1652C3.73208 16.8036 0.103643 25.7716 0.165885 35.0968C0.228128 44.422 3.97596 53.3408 10.5832 59.8905L35.1651 34.8632L10.2513 10.1652Z" fill="#000" class="curve-2"/>
<rect fill="#000" height="35" class="line">
</clipPath>
</defs>
</svg>
<svg view-box="0 0 206 70" width="206" height="70">
<path d="M10.2513 10.1652C3.73208 16.8036 0.103643 25.7716 0.165885 35.0968C0.228128 44.422 3.97596 53.3408 10.5832 59.8905L35.1651 34.8632L10.2513 10.1652Z" fill="#000" class="curve-1"/>
<path d="M10.2513 10.1652C3.73208 16.8036 0.103643 25.7716 0.165885 35.0968C0.228128 44.422 3.97596 53.3408 10.5832 59.8905L35.1651 34.8632L10.2513 10.1652Z" fill="#000" class="curve-2"/>
<rect fill="#000" height="35" class="line">
</svg>
Does anybody know anything about CSS rendering and why could this be happening?
I also created this CodePen where I just wanted to demonstrate that animating a clip-path is possible and it seems to work just fine here...
.masked {
width: 500px;
clip-path: url(#mask)
}
.mask {
width: 500px;
}
.circle {
animation: ʕ•̫͡•ʕ•̫͡•ʔ•̫͡•ʔ 2s infinite;
}
#keyframes ʕ•̫͡•ʕ•̫͡•ʔ•̫͡•ʔ {
0% {
translate: 0;
}
50% {
translate: 40px;
}
100% {
translate: 100px;
}
}
<img src="https://images.unsplash.com/photo-1542273917363-3b1817f69a2d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Nnx8dHJlZXxlbnwwfHwwfHw%3D&auto=format&fit=crop&w=900&q=60" class="masked"/>
<svg viewport="0 0 100 60">
<circle cx="50" cy="30" r="20" class="circle">
</svg>
<svg width="0" height="0">
<defs>
<clipPath id="mask">
<circle cx="100" cy="100" r="40" class="circle" />
</clipPath>
</defs>
</svg>
I have no idea why this's happening, if anyone knows the answer, I would be glad.
Thanks
Why so complicated? The same animation can be achieved with the stroke-dasharray technique.
For me, the animation appears smooth. Whether it is the same for you depends probably on hardware, but I am far down from your computing power.
.button {
width: 206px;
height: 70px;
line-height: 70px;
text-align: center;
position: relative;
border: 3px solid transparent;
}
.button .line {
position: absolute;
overflow: visible;
top: 0;
left: 0;
width: 100%;
height: 100%;
fill: none;
stroke: black;
stroke-width: 3px;
stroke-dasharray: 10px 90px;
animation: around 20s linear infinite;
}
#keyframes around {
0% {
stroke-dashoffset: 100px;
}
100% {
stroke-dashoffset: 0px;
}
}
<div class="button">button text<svg class="line" view-box="0 0 206 70">
<path d="M35,-1.5 A 36.5 36.5 0 0 0 35,71.5 H 171 A 36.5 36.5 0 0 0 171,-1.5 Z" pathLength="100" />
</svg>

Animating svg fill from bottom to top

I have a simple layout:
split screen, one section is white, the other is black.
centered logo, half black and half white
when you hover the black section, it gets filled from bottom to top with white
Now, what I try to do:
Fill the logo from bottom to top with black when I hover the section on the right.
Fill the logo from top to bottom with white when I hover the section on the left
I tried many things... but I always failed.
I think the easiest solution would be to have a rectangle with a linear gradient as a background-image, add a mask and then move the background-position.
Here is a snippet:
$( document ).ready(function() {
$(".split-half").hover(function(){
var elem = $(this);
$(".split-half").each(function(){
$(this).removeClass('active');
setTimeout(function(){
elem.addClass('active');
}, 400);
});
});
});
body *, *:after, *:before {
box-sizing: border-box;
margin:0;
padding:0;
}
html, body {
height: 100%;
}
.split-half {
display: block;
width: 50%;
height: 100%;
position: absolute;
z-index: 1;
padding: 5%;
}
.split-half:nth-child(1) {
background: #fff;
left: 0;
}
.split-half:nth-child(1):after {
content: '';
width: 100%;
height: 0;
position: absolute;
top: 0;
left: 0;
background: #000;
transition: height .3s;
}
.split-half:nth-child(1).active:hover:after {
height: 100%;
z-index: -1;
}
.split-half:nth-child(2) {
background: #000;
right: 0;
}
.split-half:nth-child(2):after {
content: '';
width: 100%;
height: 0;
position: absolute;
bottom: 0;
left: 0;
background: #fff;
transition: height .3s;
}
.split-half:nth-child(2).active:hover:after {
height: 100%;
z-index: -1;
}
.split-half:nth-child(2).active:hover + #logo #rect {
background-position: 0% 100%;
}
#logo {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-39.8%, -50%);
max-width: 420px;
min-width: 120px;
width: 10%;
height: auto;
z-index: 10;
}
#logo #rect {
background-image: linear-gradient(to bottom, white 0%, white 50%, black 50%, black 100%);
background-position: 0% 0%;
background-size: 100% 200%;
height: 100%;
width: 100%;
transition: all .3s;
mask: url(#mhSvg);
position: absolute;
top: 0;
right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section>
<div class="split-half"></div>
<div class="split-half">
</div>
<div id="logo">
<svg width="100%" height="100%" viewBox="0 0 187 174" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
<defs>
<g id="hSvg">
<path d="M74.624,173.782l111.609,-55.886l-24.82,-12.41l-24.82,12.41l-24.82,-12.41l24.82,-12.41l-24.82,-12.41l-111.773,55.804l24.984,12.492l61.969,-31.066l24.82,12.41l-61.969,31.066" style="fill:#fff;"/>
</g>
<mask id="mhSvg" x="0" y="0" width="100%" height="100%">
<g id="hSvg">
<path d="M74.624,173.782l111.609,-55.886l-24.82,-12.41l-24.82,12.41l-24.82,-12.41l24.82,-12.41l-24.82,-12.41l-111.773,55.804l24.984,12.492l61.969,-31.066l24.82,12.41l-61.969,31.066" style="fill:#fff;"/>
</g>
</mask>
<g id="aSvg">
<path d="M0.082,0l74.542,37.271l0,136.511l-24.82,-12.41l0,-62.05l-24.902,-12.451l0,62.05l-24.82,-12.41l0,-136.511Zm24.902,62.091l0,-24.82l24.82,12.41l0,24.821l-24.82,-12.411Z"/>
</g>
</defs>
<g>
<use xlink:href="#hSvg" x="0" y="0" />
<use xlink:href="#aSvg" x="0" y="0" />
</g>
</svg>
<div id="rect">
</div>
</div>
</section>
For now, as you can see, I fail to position the mask.
Do you know how I can position the mask ?
Or do you think of a better method to achieve the effect ?
Thank you in advance !
Edit:
Well, I found a solution with masks... but it won't be a good solution as it's not cross browsers.
$( document ).ready(function() {
$(".split-half").hover(function(){
var elem = $(this);
$(".split-half").each(function(){
$(this).removeClass('active');
setTimeout(function(){
elem.addClass('active');
}, 400);
});
});
});
/* line 3, ../sass/style.scss */
body *, *:after, *:before {
box-sizing: border-box;
}
html, body {
height: 100%;
margin:0;
padding: 0;
}
.split-half {
display: block;
width: 50%;
height: 100%;
position: absolute;
z-index: 1;
padding: 5%;
}
.split-half:nth-child(1) {
background: #fff;
left: 0;
}
.split-half:nth-child(1):after {
content: '';
width: 100%;
height: 0;
position: absolute;
top: 0;
left: 0;
background: #000;
transition: height .3s;
}
.split-half:nth-child(1).active:hover:after {
height: 100%;
z-index: -1;
}
.split-half:nth-child(1).active:hover ~ #logo #A {
background-position: 0% 0%;
}
.split-half:nth-child(2) {
background: #000;
right: 0;
}
.split-half:nth-child(2):after {
content: '';
width: 100%;
height: 0;
position: absolute;
bottom: 0;
left: 0;
background: #fff;
transition: height .3s;
}
.split-half:nth-child(2).active:hover:after {
height: 100%;
z-index: -1;
}
/* line 58, ../sass/style.scss */
.split-half:nth-child(2).active:hover + #logo #H {
background-position: 0% 100%;
}
#logo {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-38.5%, -50%);
z-index: 10;
}
#logo #H {
background-image: linear-gradient(to bottom, white 0%, white 50%, black 50%, black 100%);
background-position: 0% 0%;
background-size: 100% 200%;
height: 100%;
width: 100%;
transition: all .3s;
mask: url(#mhSvg);
position: absolute;
top: 0;
right: 0;
}
#logo #A {
background-image: linear-gradient(to bottom, white 0%, white 50%, black 50%, black 100%);
background-position: 0% 100%;
background-size: 100% 200%;
height: 100%;
width: 100%;
transition: all .3s;
mask: url(#maSvg);
position: absolute;
top: 0;
right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section>
<div class="split-half"></div>
<div class="split-half">
</div>
<div id="logo">
<svg width="194" height="181" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
<defs>
<g id="hSvg">
<path d="M74.624,173.782l111.609,-55.886l-24.82,-12.41l-24.82,12.41l-24.82,-12.41l24.82,-12.41l-24.82,-12.41l-111.773,55.804l24.984,12.492l61.969,-31.066l24.82,12.41l-61.969,31.066" style="fill:#fff;"/>
</g>
<mask id="mhSvg" x="0" y="0" width="120" height="114">
<g id="hSvg">
<path d="M74.624,173.782l111.609,-55.886l-24.82,-12.41l-24.82,12.41l-24.82,-12.41l24.82,-12.41l-24.82,-12.41l-111.773,55.804l24.984,12.492l61.969,-31.066l24.82,12.41l-61.969,31.066" style="fill:#fff;"/>
</g>
</mask>
<mask id="maSvg" x="0" y="0" width="120" height="114">
<g id="aSvg">
<path d="M0.082,0l74.542,37.271l0,136.511l-24.82,-12.41l0,-62.05l-24.902,-12.451l0,62.05l-24.82,-12.41l0,-136.511Zm24.902,62.091l0,-24.82l24.82,12.41l0,24.821l-24.82,-12.411Z" style="fill:#fff"/>
</g>
</mask>
</defs>
<g>
</svg>
<div id="H">
</div>
<div id="A">
</div>
</div>
</section>
I may have to dig at the suggestion made by #RobertLongson that is to say animate the stops of a linear-gradient.
Edit 2:
I tried animating the linear-gradient position, thanks to kute.js.
It works in firefox, chrome, but not in IE/Edge or on the website, they do have an exemple working on IE/Edge.
Here is my pen, I'm still wondering why it doesn't work.
https://codepen.io/AmauryH/pen/brBgKo
Here's one way to do it. I'm using an animated CSS linear-gradient for the split-half <div> elements. And using mix-blend-mode: difference to ensure the logo contrasts with the animated background.
This should work on all browsers except IE/Edge.
body *, *:after, *:before {
box-sizing: border-box;
margin:0;
padding:0;
}
html, body {
height: 100%;
}
.split-half {
display: block;
width: 50%;
height: 100%;
position: absolute;
z-index: 1;
padding: 5%;
}
.split-half:nth-child(1) {
background: linear-gradient(to top, #ffffff 50%,#000000 50%);
background-size: 100% 200%;
background-position: 0 100%;
left: 0;
transition: background-position 0.5s;
}
.split-half:nth-child(1):hover {
background-position: 0 0;
}
.split-half:nth-child(2) {
background: linear-gradient(to top, #ffffff 50%,#000000 50%);
background-size: 100% 200%;
right: 0;
transition: background-position 0.5s;
}
.split-half:nth-child(2):hover {
background-position: 0 100%;
}
#logo {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-39.8%, -50%);
max-width: 420px;
min-width: 120px;
width: 10%;
height: auto;
z-index: 10;
mix-blend-mode: difference;
}
<section>
<div class="split-half"></div>
<div class="split-half"></div>
<div id="logo">
<svg width="100%" height="100%" viewBox="0 0 187 174" style="fill-rule:evenodd;">
<defs>
<linearGradient x1="0" y1="100%" x2="0" y2="0">
<stop offset="0" stop-color="white"/>
<stop offset="0" stop-color="black"/>
</linearGradient>
</defs>
<g>
<path id="hSvg" d="M74.624,173.782l111.609,-55.886l-24.82,-12.41l-24.82,12.41l-24.82,-12.41l24.82,-12.41l-24.82,-12.41l-111.773,55.804l24.984,12.492l61.969,-31.066l24.82,12.41l-61.969,31.066" style="fill:#fff;"/>
<path id="aSvg" d="M0.082,0l74.542,37.271l0,136.511l-24.82,-12.41l0,-62.05l-24.902,-12.451l0,62.05l-24.82,-12.41l0,-136.511Zm24.902,62.091l0,-24.82l24.82,12.41l0,24.821l-24.82,-12.411Z" style="fill:#fff;"/>
</g>
</svg>
</div>
</section>
I've finally decided to start from a blank page and went for a different approach.
A container with a linear-gradient background (half white/half black) and the logo as a svg background-image
Two more containers inside with height 0. One with a black background, the other with a white background
In each a fullscreen span with the logo as a background image. (one logo full black, the other full white)
Then, I just have to animate the height of the containers from 0 to 100% to get the transition I wanted.
To get the white background to fill the screen from bottom to top, I had to use a simple trick... I've rotated the container with the background from a 180deg angle, and I've rotated it's children with the same angle.
Here is a snippet:
var vHeight = $(window).height();
var vWidth = $(window).width();
var screen1 = $('#screen1');
var currentMousePos = { x: -1, y: -1 };
$(document).mousemove(function(event) {
currentMousePos.x = event.pageX;
currentMousePos.y = event.pageY;
if ( currentMousePos.y <= vHeight ){
if ( currentMousePos.x >= ((vWidth / 2) + (vWidth / 10)) ) {
$('.svgb-wrapper').css('height', '0');
$('.svgw-wrapper').css('height', '100%');
}
else if ( currentMousePos.x <= ((vWidth / 2) - (vWidth / 10)) ) {
$('.svgb-wrapper').css('height', '100%');
$('.svgw-wrapper').css('height', '0');
}
else {
$('.svgb-wrapper').css('height', '0');
$('.svgw-wrapper').css('height', '0');
}
};
});
* {
margin:0; padding:0; border:0;
}
body *, *:after, *:before {
box-sizing: border-box;
}
html, body {
height: 100%;
background: #000;
color: #fff;
}
#screen1 {
height: 100%;
background: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB2aWV3Qm94PSIwIDAgMTg3IDE3NCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW\a 5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzdHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVqb2lu\aOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNDE0MjE7Ij48cmVjdCBpZD0iUGxhbi1kZS10cmF2YWlsMSIgeD0iMCIgeT0iMCIgd2lkdGg9IjE4Ni4zNjgiIGhlaWdodD0iMTczLjc4MiIgc3R5bG\aU9ImZpbGw6bm9uZTsiLz48Y2xpcFBhdGggaWQ9Il9jbGlwMSI+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjE4Ni4zNjgiIGhlaWdodD0iMTczLjc4MiIvPjwvY2xpcFBhdGg+PGcgY2xpcC1wYXRo\aPSJ1cmwoI19jbGlwMSkiPjxwYXRoIGlkPSJoU3ZnIiBkPSJNNzQuNjI0LDE3My43ODJsMTExLjYwOSwtNTUuODg2bC0yNC44MiwtMTIuNDFsLTI0LjgyLDEyLjQxbC0yNC44MiwtMTIuNDFsMjQuOD\aIsLTEyLjQxbC0yNC44MiwtMTIuNDFsLTExMS43NzMsNTUuODA0bDI0Ljk4NCwxMi40OTJsNjEuOTY5LC0zMS4wNjZsMjQuODIsMTIuNDFsLTYxLjk2OSwzMS4wNjYiIHN0eWxlPSJmaWxsOiNmZmY7\aIi8+PHBhdGggaWQ9ImFTdmciIGQ9Ik0wLjA4MiwwbDc0LjU0MiwzNy4yNzFsMCwxMzYuNTExbC0yNC44MiwtMTIuNDFsMCwtNjIuMDVsLTI0LjkwMiwtMTIuNDUxbDAsNjIuMDVsLTI0LjgyLC0xMi\a 40MWwwLC0xMzYuNTExbDAsMFptMjQuOTAyLDYyLjA5MWwwLC0yNC44MmwyNC44MiwxMi40MWwwLDI0LjgyMWwtMjQuODIsLTEyLjQxMWwwLDBaIi8+PC9nPjwvc3ZnPg==") no-repeat left 55% center, linear-gradient(to right, #ffffff 0%, #ffffff 50%, #000000 50%, #000000 100%);
background-size: 33%, cover;
}
#screen1 .svgw-wrapper {
height: 0;
width: 100%;
overflow: hidden;
position: absolute;
top: 0;
-moz-transition: all 0.6s;
-o-transition: all 0.6s;
-webkit-transition: all 0.6s;
transition: all 0.6s;
background: #000;
}
#screen1 .svgw-wrapper .svgw {
position: absolute;
top: 0;
display: block;
height: 100vh;
width: 100%;
background: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PCF\a ET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy\a 53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHdpZHRoPSIxMDAlI\aiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxODcgMTc0IiB2ZXJzaW9uPSIxLjEiIHhtbG5z\aPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzM\aub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiIHN0eWxlPSJmaWxsLXJ1bGU6ZX\aZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pd\aGVybGltaXQ6MS40MTQyMTsiPjxyZWN0IGlkPSJQbGFuLWRlLXRyYXZhaWwxIiB4PSIwIiB5PSIw\aIiB3aWR0aD0iMTg2LjM2OCIgaGVpZ2h0PSIxNzMuNzgyIiBzdHlsZT0iZmlsbDpub25lOyIvPjx\ajbGlwUGF0aCBpZD0iX2NsaXAxIj48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTg2LjM2OCIgaG\aVpZ2h0PSIxNzMuNzgyIi8+PC9jbGlwUGF0aD48ZyBjbGlwLXBhdGg9InVybCgjX2NsaXAxKSI+P\aHBhdGggaWQ9ImhTdmciIGQ9Ik03NC42MjQsMTczLjc4MmwxMTEuNjA5LC01NS44ODZsLTI0Ljgy\aLC0xMi40MWwtMjQuODIsMTIuNDFsLTI0LjgyLC0xMi40MWwyNC44MiwtMTIuNDFsLTI0LjgyLC0\axMi40MWwtMTExLjc3Myw1NS44MDRsMjQuOTg0LDEyLjQ5Mmw2MS45NjksLTMxLjA2NmwyNC44Mi\awxMi40MWwtNjEuOTY5LDMxLjA2NiIgc3R5bGU9ImZpbGw6I2ZmZjsiLz48cGF0aCBpZD0iYVN2Z\ayIgZD0iTTAuMDgyLDBsNzQuNTQyLDM3LjI3MWwwLDEzNi41MTFsLTI0LjgyLC0xMi40MWwwLC02\aMi4wNWwtMjQuOTAyLC0xMi40NTFsMCw2Mi4wNWwtMjQuODIsLTEyLjQxbDAsLTEzNi41MTFsMCw\awWm0yNC45MDIsNjIuMDkxbDAsLTI0LjgybDI0LjgyLDEyLjQxbDAsMjQuODIxbC0yNC44MiwtMT\aIuNDExbDAsMFoiIHN0eWxlPSJmaWxsOiNmZmY7Ii8+PC9nPjwvc3ZnPg==") no-repeat left 55% center;
background-size: 33%;
}
#screen1 .svgb-wrapper {
height: 0;
width: 100%;
overflow: hidden;
position: absolute;
bottom: 0;
background: #fff;
-moz-transition: all 0.6s;
-o-transition: all 0.6s;
-webkit-transition: all 0.6s;
transition: all 0.6s;
-moz-transform: rotateX(180deg);
-ms-transform: rotateX(180deg);
-webkit-transform: rotateX(180deg);
transform: rotateX(180deg);
}
#screen1 .svgb-wrapper .svgb {
position: absolute;
top: 0;
display: block;
height: 100vh;
width: 100%;
background: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB2aWV3Qm94PSIwIDAgMTg3IDE3NCIgdmV\ayc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW\a 5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzd\aHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVqb2lu\aOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNDE0MjE7Ij48cmVjdCBpZD0iUGxhbi1kZS10cmF\a 2YWlsMSIgeD0iMCIgeT0iMCIgd2lkdGg9IjE4Ni4zNjgiIGhlaWdodD0iMTczLjc4MiIgc3R5bG\aU9ImZpbGw6bm9uZTsiLz48Y2xpcFBhdGggaWQ9Il9jbGlwMSI+PHJlY3QgeD0iMCIgeT0iMCIgd\a 2lkdGg9IjE4Ni4zNjgiIGhlaWdodD0iMTczLjc4MiIvPjwvY2xpcFBhdGg+PGcgY2xpcC1wYXRo\aPSJ1cmwoI19jbGlwMSkiPjxwYXRoIGlkPSJoU3ZnIiBkPSJNNzQuNjI0LDE3My43ODJsMTExLjY\awOSwtNTUuODg2bC0yNC44MiwtMTIuNDFsLTI0LjgyLDEyLjQxbC0yNC44MiwtMTIuNDFsMjQuOD\aIsLTEyLjQxbC0yNC44MiwtMTIuNDFsLTExMS43NzMsNTUuODA0bDI0Ljk4NCwxMi40OTJsNjEuO\aTY5LC0zMS4wNjZsMjQuODIsMTIuNDFsLTYxLjk2OSwzMS4wNjYiLz48cGF0aCBpZD0iYVN2ZyIg\aZD0iTTAuMDgyLDBsNzQuNTQyLDM3LjI3MWwwLDEzNi41MTFsLTI0LjgyLC0xMi40MWwwLC02Mi4\awNWwtMjQuOTAyLC0xMi40NTFsMCw2Mi4wNWwtMjQuODIsLTEyLjQxbDAsLTEzNi41MTFsMCwwWm\a 0yNC45MDIsNjIuMDkxbDAsLTI0LjgybDI0LjgyLDEyLjQxbDAsMjQuODIxbC0yNC44MiwtMTIuN\a DExbDAsMFoiLz48L2c+PC9zdmc+") no-repeat left 55% center;
background-size: 33%;
-moz-transform: rotateX(180deg);
-ms-transform: rotateX(180deg);
-webkit-transform: rotateX(180deg);
transform: rotateX(180deg);
}
#screen2 {
-moz-transition: all 0.6s;
-o-transition: all 0.6s;
-webkit-transition: all 0.6s;
transition: all 0.6s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
<section id="screen1">
<div class="svgw-wrapper">
<span class="svgw"></span>
</div>
<div class="svgb-wrapper">
<span class="svgb"></span>
</div>
</section>
It's a cross browser solution.
The only problem is the background-position and the background-size that are not working as expected in IE, but I'll probably live with that !

How can I let a hexagon morph into a triangle (animation)

I have a question on how I can morph a hexagon into a triangle. So the animation it starts off as a hexagon, it's transforms or morphs into a triangle which goes then back to the hexagon (infinite iteration)
<div class="hexagon"></div>
<div id="triangle-up"></div>
<div id="triangle-down"></div>
My CSS code
.hexagon {
position: relative;
width: 130px;
height: 75.06px;
background-color: #2196F3;
margin: 0 auto;
margin-top: 50px;
}
.hexagon:before,
.hexagon:after {
content: "";
position: absolute;
width: 0;
border-left: 65px solid transparent;
border-right: 65px solid transparent;
}
.hexagon:before {
bottom: 100%;
border-bottom: 37.53px solid #2196F3;
}
.hexagon:after {
top: 100%;
width: 0;
border-top: 37.53px solid #2196F3;
}
#triangle-up {
width: 0;
height: 0;
margin: 0 auto;
margin-top: -86px;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid #2196F3;
animation: triangle-up_show;
animation-duration: 4s;
animation-timing-function: linear;
animation-play-state: paused;
animation-delay: 3s;
}
#triangle-down {
width: 0;
height: 0;
margin: 0 auto;
margin-top: -100px;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-top: 100px solid #2196F3;
animation: triangle-down_show;
animation-duration: 6s;
animation-timing-function: linear;
animation-play-state: paused;
}
#keyframes hexagon_hide {
0% { opacity: 1; }
100% { opacity: 0; }
}
#keyframes triangle-up_show {
0% { opacity: 0 }
50% { opacity: 1 }
100% { opacity: 0 }
}
#keyframes triangle-down_show {
0% { opacity: 0 }
50% { opacity: 1 }
100% { opacity: 0 }
}
In css this can be done with the polygon clip and animation:
.shape {
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
background: red;
width: 300px;
height: 300px;
animation: morph 2s infinite;
}
#keyframes morph {
0% {clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);}
50% {clip-path: polygon(50% 0%, 50% 0, 100% 0, 50% 100%, 0 0, 50% 0);}
100% {clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);}
}
<div class="shape">
</div>
I find this site http://bennettfeely.com/clippy/ a good tool for morphing polygon clips in css
I'm aware this isn't css but this could be done using an svg animation:
<svg id="color-fill" xmlns="http://www.w3.org/2000/svg" version="1.1" width="300" height="300" xmlns:xlink="http://www.w3.org/1999/xlink">
<polygon id="shape" class="hex">
<animate
dur="2.5s"
repeatCount="indefinite"
attributeName="points"
values="300,150 225,280 75,280 0,150 75,20 225,20;
300,20 150,280 150,280 0,20 75,20 225,20;
300,20 150,280 150,280 0,20 75,20 225,20;
300,150 225,280 75,280 0,150 75,20 225,20;
300,150 225,280 75,280 0,150 75,20 225,20;"/>
</polygon>
</svg>
I hope this helps anyway :)
https://css-tricks.com/svg-shape-morphing-works/

animate radial-gradient CSS3 : move from left to right? [duplicate]

This question already has answers here:
How to animate a radial-gradient using CSS?
(3 answers)
Closed 2 years ago.
I want animate a background with a radial-gradient radial-gradient(circle, rgba(255,255,255,0.8) 0, rgba(255,255,255,0) 100%), to move it from left to right
http://jsfiddle.net/odsb1fjh/2/
how can I do to animate this radial-gradient to move infinite on div from left to right?
I have already try animation and keyframe background-position: left/right bottom; but don't works.
Try this
div
{
position:absolute;
width: 250px;
height: 250px;
background-color: black;
background-image: url(http://frontend.lostboys.nl/presenations/Icons-fonts/img/chrome.png)
}
div:after
{
content:'';
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
background-image: -webkit-radial-gradient(circle, rgba(255,255,255,0.8) 0, rgba(255,255,255,0) 100%);
background-position: -1500px 0;
background-repeat: no-repeat;
-webkit-animation: animation 3s ease-in-out infinite;
}
#-webkit-keyframes animation {
from {background-position: -250px 0;}
to {background-position: 250px 0;}
}
<div></div>
or this
div
{
position:absolute;
width: 250px;
height: 250px;
background-color: black;
background-image: url(http://frontend.lostboys.nl/presenations/Icons-fonts/img/chrome.png);
overflow:hidden
}
div:after
{
content:'';
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
background-image: -webkit-radial-gradient(circle, rgba(255,255,255,0.8) 0, rgba(255,255,255,0) 100%);
-webkit-animation: animation 3s ease-in-out infinite;
}
#-webkit-keyframes animation {
from {left: -250px;}/**you can use translate3d(-250px,0,0)*/
to {left: 250px;}/** translate3d(250px,0,0)*/
}
<div></div>
"but we can see the border of "square" where is the light radial" - Why use radial background at all, simply use:
div
div {
position: absolute;
width: 250px;
height: 250px;
background-color: black;
background-image: url(http://frontend.lostboys.nl/presenations/Icons-fonts/img/chrome.png);
overflow: hidden;
}
div:after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgb(255, 255, 255);
background: linear-gradient(
90deg,
rgba(250, 250, 250, 0) 0%,
rgba(250, 250, 250, 0.5) 60%,
rgba(250, 250, 250, 0) 100%
);
-webkit-animation: animation 3s ease-in-out infinite;
}
#-webkit-keyframes animation {
from {
left: -250px;
}
to {
left: 250px;
}
}
<div></div>

CSS Only Marker Shape

I want to create a CSS only shape that looks like a marker or guitar pick.
My Codepen demo I've been working from: http://codepen.io/Vestride/pen/otcem
// CSS Marker
// I was attempting to make this shape in CSS. The marker on the far right is an image. Next to it is SVG. The rest are my attempts :|
// stackoverflow question: http://stackoverflow.com/questions/11982066/css-only-marker-shape
// Top part is a perfect circle
// Bottom half is edges that curve out!
body {
margin: 40px 20px;
background: url(http://subtlepatterns.com/patterns/furley_bg_#2X.png) ;
background-size: 600px 600px;
}
figure {
position: relative;
float: left;
margin-left: 60px;
width: 80px;
height: 80px;
}
figure:first-child {
margin-left: 0;
}
.one {
border-radius: 50% 50% 0 50%;
background: hotpink;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
.two {
background: skyblue;
border-top-left-radius: 50%;
border-top-right-radius: 50% 100%;
border-bottom-left-radius: 100% 50%;
border-bottom-right-radius: 0%;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
.three {
border-radius: 50%;
background: lightgreen;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
.three::before {
content: '';
position: absolute;
width: 106%;
height: 106%;
background: lightgreen;
border-top-left-radius: 60%;
border-top-right-radius: 50% 100%;
border-bottom-left-radius: 100% 50%;
border-bottom-right-radius: 0%;
}
.four {
border-radius: 50% 50% 0 50%;
background: seagreen;
overflow-x: visible;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
.four::before {
content: '';
position: absolute;
width: 100%;
height: 100%;
background: red;
border-top-left-radius: 50%;
border-top-right-radius: 50% 100%;
border-bottom-left-radius: 100% 50%;
border-bottom-right-radius: 0%;
}
.five {
width: 80px;
height: 102px;
background-image: url(http://i.imgur.com/t80ZS.png);
/* Overlay the objective */
/*margin-left: -80px;
opacity: 0.6;*/
}
.svg {
position: relative;
float: left;
margin-left: 60px;
}
<figure class="one"></figure>
<figure class="two"></figure>
<figure class="three"></figure>
<figure class="four"></figure>
<figure class="svg">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="81px" height="104px" viewBox="0 0 81 104">
<g transform="translate(1, 1)"><path fill="#FFFFFF" stroke="#CCCCCC" stroke-width="2" d="M78.399,39.2c0,36.998-39.199,62.599-39.199,62.599S0,76.198,0,39.2C0,17.55,17.551,0,39.2,0 C60.848,0,78.399,17.55,78.399,39.2z"/></g>
</svg>
</figure>
<!-- Image -->
<figure class="five"></figure>
I've been unsuccessful in replicating the curvy edges by the point. Ideally I'd like to accomplish this with one element (+pseudo elements).
Take a look at this one, i changed their css abit:
http://codepen.io/anon/pen/HLJlu
With SVG
You can achieve the marker shape with an inline svg. The following example uses a path element with 2 cubic bezier curve commands:
svg{width:80px;height:100px;}
<svg viewbox="0 0 80 100">
<path d="M40 99.5 C-22.5 57.5 0 0 40 0.5 C80 0 102.5 57.5 40 99.5z" stroke-width="1" stroke="grey" fill="transparent"/>
</svg>
With CSS
You can also make the marker shape with CSS only using border radius, absolute positioning and 2 pseudo elements. Note that this example uses only one div element
div{
position:relative;
width:80px;
height:102px;
overflow:hidden;
border-radius:40px;
}
div:before, div:after{
content:'';
position:absolute;
top:0px;
width:240px;
height:150px;
border:1px solid green;
}
div:before{
left:0;
border-top-left-radius:40px;
border-bottom-left-radius:240px 110px;
}
div:after{
right:0;
border-top-right-radius:40px;
border-bottom-right-radius:240px 110px;
}
<div></div>
<svg x="0px" y="0px" width="32px" height="45px"
viewBox="38 12 128 180" style="cursor:help;" >
<style type="text/css">
.st0{ fill:#FFF;stroke:#000;stroke-width:6;stroke-miterlimit:10;}
.st1{fill:#FFFFFF;}
.st2{fill:#1309FF;}
.st3{fill:#1309FF;}
.st4{fill:#1309FF;}
.st6{font-size:57.2285px;}
</style>
<path class="st0" d="M158.5,73.8c0-32.3-26.2-58.4-58.4-58.4c-32.3,0-58.4,26.2-58.4,58.4c0,16.6,6.9,31.5,18,42.1
c7.2,7.2,16.7,17.2,20.1,22.5c7,10.9,20,47.9,20,47.9s13.3-37,20.4-47.9c3.3-5.1,12.2-14.4,19.3-21.6
C151.2,106.1,158.5,90.9,158.5,73.8z"/>
<circle class="st4" cx="100.1" cy="74.7" r="44.1"/>
<text x="100" y="90" class="st1 st5 st6" text-anchor="middle" >12</text>
</svg>
This will be better OR This
<svg width="32px" height="45px" viewBox="38 12 128 180" >
<path style="fill:#FFFFFF;stroke:#020202;stroke-width:4;stroke-miterlimit:10;" d="M158.5,73.8c0-32.3-26.2-58.4-58.4-58.4c-32.3,0-58.4,26.2-58.4,58.4c0,16.6,6.9,31.5,18,42.1c7.2,7.2,16.7,17.2,20.1,22.5c7,10.9,20,47.9,20,47.9s13.3-37,20.4-47.9c3.3-5.1,12.2-14.4,19.3-21.6C151.2,106.1,158.5,90.9,158.5,73.8z"/>
<circle style="fill:' + color + ';" cx="100.1" cy="74.7" r="44.1"/>
<text x="100" y="90" text-anchor="middle" style="font-size:57.2285px;fill:#FFFFFF;">12</text>
</svg>

Resources