I'm almost there, I found the perfect CSS pyramid: https://codepen.io/SL20XX/pen/NZLGjx
But I want to apply this gradient instead of the single "#00B4FF" color:
background-image: linear-gradient(39deg, #12103E 0%, #721B34 100%);
I tried many tweaks but doesn't work. I'm confused with the "$color" variable.
How would you do?
Thanks a lot!
You can put a border-image on each surface rather than a border color.
This snippet does this but has to clip each surface back into a triangle shape.
Note: to get the shading effect you need to decide what linear-gradient you want for each of the lighten/darken colors in your original and subsitute those for the one linear-gradient used here.
<style>
.container {
--color: #00B4FF;
--speed: 5s;
}
.container {
width: 400px;
height: 400px;
margin: 0 auto;
position: relative;
perspective: 300px;
perspective-origin: 50% 40%;
}
.side {
position: absolute;
left: 140px;
top: 150px;
width: 0;
height: 0;
border-left: 60px solid transparent;
border-right: 60px solid transparent;
border-bottom: 120px solid #ccc;
transform-origin: 50% 0%;
animation: spin var(--speed) infinite linear;
}
.back {
animation-delay: calc(var(--speed) / -2);
}
.right {
animation-delay: calc(var(--speed) / -4);
}
.left {
animation-delay: calc(var(--speed) * -0.75);
}
#keyframes spin {
0% {
transform: rotateY(0deg) rotateX(30deg);
/*border-bottom-color: lighten(#0000FF, 5%);*/
border-image: linear-gradient(red, yellow);
clip-path: polygon(0 100%, 100% 100%, 50% 0);
}
25% {
transform: rotateY(90deg) rotateX(30deg);
/*border-bottom-color: darken(#0000FF, 5%);*/
border-image: linear-gradient(red, yellow);
clip-path: polygon(0 100%, 100% 100%, 50% 0);
opacity: 1;
}
25.1% {
opacity: 0;
}
50% {
transform: rotateY(180deg) rotateX(30deg);
/*border-bottom-color: darken(#0000FF, 12%);*/
border-image: linear-gradient(red, yellow);
clip-path: polygon(0 100%, 100% 100%, 50% 0);
}
74.9% {
opacity: 0;
}
75% {
transform: rotateY(270deg) rotateX(30deg);
/*border-bottom-color: darken(#0000FF, 15%);*/
border-image: linear-gradient(red, yellow);
clip-path: polygon(0 100%, 100% 100%, 50% 0);
opacity: 1;
}
100% {
transform: rotateY(360deg) rotateX(30deg);
/*border-bottom-color: lighten(#0000FF, 5%);*/
border-image: linear-gradient(red, yellow);
clip-path: polygon(0 100%, 100% 100%, 50% 0);
}
}
.shadow {
position: absolute;
top: 300px;
left: 175px;
width: 50px;
height: 50px;
background-color: #bbb;
box-shadow: 0 0 40px 40px #bbb;
animation: shadow var(--speed) infinite linear;
}
#keyframes shadow {
0% {
transform: rotateX(90deg) rotateZ(0deg);
}
100% {
transform: rotateX(90deg) rotateZ(-360deg);
}
}
</style>
<div class="container">
<div class="side left"></div>
<div class="side front"></div>
<div class="side right"></div>
<div class="side back"></div>
<div class="shadow"></div>
</div>
Related
I'm trying to get my head around transforms and 3d animation perspectives for css. I have created a piece of code that displays an 8 sided die and then rotates it for the viewer.
However, the die seems to rotate around an invisible center object,
rather than the center of the die being the center point for the rotation animation.
I realize that I must not be grasping something about the code I have written through trial and error.
Here is a fiddle to show what I mean about the way the shape seems to rotate around an invisible center: https://jsfiddle.net/4qbLct3b/
Instead, I want the center of the 3 dimensional object to be the center point of the rotation animation.
HTML
body {
perspective: 9000px;
padding-top: 10%;
}
.d8 {
height: 64px;
width: 64px;
margin: auto;
}
.tetra {
position: relative;
height: 86.6%;
width: 100%;
margin: 0 auto;
transform-style: preserve-3d;
transform: rotatex(0deg) rotateY(0deg) rotatez(0deg);
animation: rotate 10s linear infinite;
}
.tetra div {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
-webkit-clip-path: polygon(50% -2.5%, 102.5% 102.5%, -2.5% 102.5%);
clip-path: polygon(50% -2.5%, 102.5% 102.5%, -2.5% 102.5%);
-webkit-clip-path: border-box;
clip-path: border-box;
background: teal;
transform-origin: 0% 100%;
transform: rotatex(35deg);
transform-style: preserve-3d;
}
.tetra .face2 {
transform-origin: 0% 100%;
transform: rotatey(90deg) rotatex(-35deg);
background: gold;
}
.tetra .face3 {
transform-origin: 0% 100%;
left: 100%;
transform: rotatey(90deg) rotatex(35deg);
background: red;
}
.tetra .face4 {
transform-origin: 0% 100%;
transform: rotateY(-90deg) translateX(-100%) rotateY(90deg) rotatex(-35deg);
background: black;
}
.tetra .face5 {
transform-origin: 0% 100%;
transform: rotateY(-90deg) translateX(-100%) rotateY(90deg) rotatex(-145deg);
background: orange;
}
.tetra .face6 {
transform-origin: 0% 100%;
left: 100%;
transform: rotatey(90deg) rotatex(145deg);
background: green;
}
.tetra .face7 {
transform-origin: 0% 100%;
transform: rotatey(90deg) rotatex(-145deg);
background: brown;
}
.tetra .face8 {
background: grey;
transform-origin: 0% 100%;
transform: rotatex(145deg);
}
#keyframes rotate {
50% {
transform: rotatex(180deg) rotateY(180deg) rotatez(180deg);
}
100% {
transform: rotatex(360deg) rotateY(360deg) rotatez(360deg);
}
}
<div class="d8">
<div class="tetra">
<div class="face1"></div>
<div class="face2"></div>
<div class="face3"></div>
<div class="face4"></div>
<div class="face5"></div>
<div class="face6"></div>
<div class="face7"></div>
<div class="face8"></div>
</div>
</div>
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/
I've created this snippet on Codepen: the earth rotates and the car moves. However, when car moves it makes the earth rotate too. I want all elements to go their own path.
Why does the car affect the earth, and how can that be avoided?
body {
background: url(https://news.vanderbilt.edu/files/NASA_SMBH1.jpg);
background-size: 1000px;
}
#firstimg {
background-image: url(http://www.21tech.ir/dfxhfgh.gif);
position: absolute;
background-repeat: no-repeat;
background-size: 100px;
animation: anim1 14s infinite linear;
margin: 40px;
}
#earth {
margin-left: 100px;
width: 500px;
height: 500px;
background: url(http://www.drodd.com/images14/map-of-earth1.jpg);
border-radius: 50%;
background-size: 1000px;
box-shadow: inset 16px 0 40px 6px rgb(0, 0, 0), inset -3px 0 6px 2px rgba(255, 255, 255, 0.2);
animation-name: rotate;
animation-duration: 30s;
animation-iteration-count: infinite;
animation-timing-function: linear;
filter: brightness(50%);
}
#keyframes rotate {
from {
background-position-x: 0px;
}
to {
background-position-x: 1000px;
}
}
#keyframes anim1 {
0%,
100% {
transform: translate(0, 0) rotate(0deg)
}
50% {
transform: translate(20px, 20px) rotate(10deg)
}
}
<div id="firstimg">
<div>
<div id="earth"></div>
You have not closed you firstimg div tag, hence it runs under a single div
<div id="firstimg"></div>
<div id="earth"></div>
Follow Codepen
I have this pen which tries to emulate an object revolving around something. This works, but it isn't smooth. While revolving it pauses around the left and right edges.
I thought it had something to do with animation-timing-function but can't get the desired result with any of the in-built functions like ease-in-out or linear or a custom cubic-bezier function.
How can I make the animation feel smooth? If there are better ways something like this can be done, feel free to let me know.
.overlay {
background-image: -webkit-repeating-linear-gradient(0deg, transparent, transparent 1%, rgb(255, 255, 255) 2%, rgb(255, 255, 255) 2%);
background-image: repeating-linear-gradient(90deg, transparent, transparent 1%, rgb(255, 255, 255) 2%, rgb(255, 255, 255) 2%);
height: 200px;
position: relative;
width: 40%;
margin: auto;
}
.circle {
width: 100px;
height: 100px;
border-radius: 50%;
background: #888;
position: absolute;
z-index: -1;
left: 0;
display: inline-block;
}
.move {
-webkit-animation: moveAndGlow 2s infinite ease-in-out;
animation: moveAndGlow 2s infinite ease-in-out;
}
#-webkit-keyframes moveAndGlow {
25% {
background: #ccc;
-webkit-transform: scale(.5);
transform: scale(.5);
margin-top: 25px;
}
50% {
left: 100%;
margin-left: -100px;
background: #888;
-webkit-transform: scale(1);
transform: scale(1);
margin-top: 0;
}
75% {
background: #000;
-webkit-transform: scale(1.5);
transform: scale(1.5);
margin-top: 25px;
}
}
#keyframes moveAndGlow {
25% {
background: #ccc;
-webkit-transform: scale(.5);
transform: scale(.5);
margin-top: 25px;
}
50% {
left: 100%;
margin-left: -100px;
background: #888;
-webkit-transform: scale(1);
transform: scale(1);
margin-top: 0;
}
75% {
background: #000;
-webkit-transform: scale(1.5);
transform: scale(1.5);
margin-top: 25px;
}
}
<div class="overlay">
<span class="circle move"></span>
</div>
If you want to move you element in a 3d environement, you can use the perspective property and actual 3d rotation.
Right now you are animating on straight lines between positions so simulating a rotation is almost imposible. I built the following example, you will need to tweak the size to fit it into your project but you should get the idea.
Also note that I put the gradient background in a pseudo element so it appear in front of the moving object :
.overlay {
height: 200px;
position: relative;
width: 40%;
margin: auto;
perspective:500px;
margin-top:50px;
}
.overlay:after{
content:'';
position:absolute;
top:-100px; left:-10%;
width:120%; height:100%;
background-image: repeating-linear-gradient(90deg, transparent, transparent 1%, rgb(255, 255, 255) 2%, rgb(255, 255, 255) 2%);
}
.circle {
width: 100px;
height: 100px;
border-radius: 50%;
background: #888;
position: absolute;
z-index: -1;
left: 50%;
margin-left:-50px;
transform: rotateY(0deg) translateX(-100px) rotateY(0deg);
display: inline-block;
}
.move {
animation: moveAndGlow 2s infinite linear;
}
#keyframes moveAndGlow {
to{ transform:rotateY(360deg) translateX(-100px) rotateY(-360deg); }
}
<div class="overlay">
<span class="circle move"></span>
</div>
I found this made it smoother
.move {
-webkit-animation: moveAndGlow 2s infinite linear;
animation: moveAndGlow 2s infinite linear;
}
#-webkit-keyframes moveAndGlow {
25% {
background: #ccc;
-webkit-transform: scale(.5);
transform: scale(.5);
margin-top: 25px;
-webkit-animation-timing-function:ease-in;
}
50% {
left: 100%;
margin-left: -100px;
background: #888;
-webkit-transform: scale(1);
transform: scale(1);
margin-top: 0;
-webkit-animation-timing-function:ease-out;
}
75% {
background: #000;
-webkit-transform: scale(1.5);
transform: scale(1.5);
margin-top: 25px;
-webkit-animation-timing-function:ease-in;
}
}
I'd like to make a radial progress indicator with css that has it's middle circle transparent. See here: http://codepen.io/geedmo/pen/InFfd – it's a perfect example of what I want to do but the middle (.overlay) has background-color which overlays the bigger circle. However, I'd like to have it transparent (the bigger circle would have transparent middle too). How to do it?
<div class="wrap">
<div class="progress-radial progress-25">
<div class="overlay">25%</div>
</div>
<div class="progress-radial progress-50">
<div class="overlay">50%</div>
</div>
<div class="progress-radial progress-75">
<div class="overlay">75%</div>
</div>
<div class="progress-radial progress-90">
<div class="overlay">90%</div>
</div>
</div>
SASS:
// Colors
$barColor: tomato
$overlayColor: #fffde8
$backColor: #2f3439
#import url(http://fonts.googleapis.com/css?family=Noto+Sans)
body
padding: 30px 0
background-color: $backColor
font-family: 'Noto Sans', sans-serif
.wrap
width: 600px
margin: 0 auto
/* -------------------------------------
* Bar container
* ------------------------------------- */
.progress-radial
float: left
margin-right: 30px
position: relative
width: 100px
height: 100px
border-radius: 50%
border: 2px solid $backColor // remove gradient color
/* -------------------------------------
* Optional centered circle w/text
* ------------------------------------- */
.progress-radial .overlay
position: absolute
width: 60px
height: 60px
background-color: $overlayColor
border-radius: 50%
margin-left: 20px
margin-top: 20px
text-align: center
line-height: 60px
font-size: 16px
/* -------------------------------------
* Mixin for progress-% class
* ------------------------------------- */
$step: 5 // step of % for created classes
$loops: round(100 / $step)
$increment: 360 / $loops
$half: round($loops / 2)
#for $i from 0 through $loops
.progress-#{$i*$step}
#if $i < $half
$nextdeg: 90deg + ( $increment * $i )
border-image: linear-gradient(90deg, $backColor 50%, transparent 50%, transparent), linear-gradient($nextdeg, $barColor 50%, $backColor 50%, $backColor)
#else
$nextdeg: -90deg + ( $increment * ( $i - $half ) )
border-image: linear-gradient($nextdeg, $barColor 50%, transparent 50%, transparent), linear-gradient(270deg, $barColor 50%, $backColor 50%, $backColor)
This is the result I'd like to get:
html code :
<div class="wrapper">
<div class="pie spinner lightBlue"></div>
<div class="pie filler lightBlue"></div>
<div class="mask"></div>
</div>
css code :
body {
background-color: #f3f3f4;
}
.lightBlue {
border: 10px solid #a8d2d2;
}
.wrapper {
width: 250px;
height: 250px;
margin: 10px auto;
position: relative;
background: white;
background-color: #f3f3f4;
-webkit-transition: width 0.5s, height 0.5s;
transition: width 0.5s, height 0.5s;
-webkit-animation: finalRota 2s 10s linear forwards;
animation: finalRota 2s 10s linear forwards;
}
.wrapper .pie {
width: 50%;
height: 100%;
position: absolute;
background-color: radial-gradient(left center, circle, #00ccff 0px, #000088 100%);
-webkit-transform-origin: 100% 50%;
-ms-transform-origin: 100% 50%;
transform-origin: 100% 50%;
}
.wrapper .spinner {
border-radius: 100% 0 0 100% / 50% 0 0 50%;
z-index: 200;
background-color: radial-gradient(right center, circle, #00ccff 0px, #000088 100%);
border-right: none;
-webkit-animation: rota 10s linear forwards;
animation: rota 10s linear forwards;
}
.wrapper .filler {
border-radius: 0 100% 100% 0 / 0 50% 50% 0;
left: 50%;
border: 10px solid #8dbdbb;
opacity: 0;
z-index: 100;
border-left: none;
-webkit-animation: fill 10s steps(1, end) forwards;
animation: fill 10s steps(1, end) forwards;
}
.wrapper .mask {
width: 50%;
height: 100%;
position: absolute;
background: inherit;
opacity: 1;
z-index: 300;
-webkit-animation: mask 10s steps(1, end) forwards;
animation: mask 10s steps(1, end) forwards;
}
#-webkit-keyframes opoFinalRota {
100% {
-webkit-transform: rotate(30deg);
-ms-transform: rotate(30deg);
transform: rotate(30deg);
}
}
#keyframes opoFinalRota {
100% {
-webkit-transform: rotate(30deg);
-ms-transform: rotate(30deg);
transform: rotate(30deg);
}
}
#-webkit-keyframes rota {
0% {
-webkit-transform: rotate(300deg);
transform: rotate(300deg);
}
100% {
-webkit-transform: rotate(60deg);
transform: rotate(60deg);
}
}
#keyframes rota {
0% {
-webkit-transform: rotate(300deg);
transform: rotate(300deg);
}
100% {
-webkit-transform: rotate(60deg);
transform: rotate(60deg);
}
}
#-webkit-keyframes mask {
0% {
opacity: 1;
}
50%, 100% {
opacity: 0;
}
}
#keyframes mask {
0% {
opacity: 1;
}
50%, 100% {
opacity: 0;
}
}
#-webkit-keyframes fill {
0% {
opacity: 0;
}
50%, 100% {
opacity: 1;
}
}
#keyframes fill {
0% {
opacity: 0;
}
50%, 100% {
opacity: 1;
}
}
and a demo : http://jsfiddle.net/usrs01ye/2/
Just set your $overlayColor variable to transparent
$overlayColor: transparent
Here's a working codepen