I'm trying to make a button that has the shape of a blob and it has to keep animating
i've tried to make it using a div and the border-raduis but it's not exactly what I wanted to have
body{
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.blob{
width: 70px;
height: 70px;
background: red;
background-size: cover;
animation: animate 3s infinite;
}
#keyframes animate {
0%, 100% {
border-radius: 64% 36% 27% 73% / 55% 58% 42% 45%;
}
25% {
border-radius: 73% 27% 26% 38% / 73% 36% 64% 27%;
}
50% {
border-radius: 28% 72% 44% 56% / 49% 40% 60% 51%;
}
75% {
border-radius: 40% 60% 70% 30% / 47% 62% 38% 53%;
}
}
<div class="blob"></div>
here's what I want to acheive:
I have the svg file and here's the code related to it: but I don't know how to animate it
<svg xmlns="http://www.w3.org/2000/svg" width="145.674" height="166.22" viewBox="0 0 145.674 166.22">
<g id="Groupe_14" data-name="Groupe 14" transform="translate(-1700.966 -2837.689)">
<path id="Tracé_20" data-name="Tracé 20" d="M1977.5,2710.2c-10.74-18.359-2.366-46.848-50.324-38.788s-46.643,29.758-40.99,45.729,18.584,22.436-4.436,43.976-13.428,55.913,28.775,51.076,30.156,19.347,52.486,22.571,29.024-9.6,26.974-25.8-4.111-32.767,11.2-43.692c15.162-10.82,13.807-12.831,12.3-25.244C2007.673,2715.5,1988.238,2728.555,1977.5,2710.2Z" transform="translate(-168.06 168.139)" fill="#fa7268" stroke="#707070" stroke-width="1"/>
</g>
</svg>
CSS property clip path with polygon can solve your problem very easily. See the example below.
img {
width: 300px;
}
.clip-animation {
clip-path: polygon(100% 50%,84.70057014808336% 54.5684167277018%,91.0518476172854% 60.99980941685713%,82.33578363789503% 63.39392013277814%,93.30127018922194% 75%,77.76736691019323% 71.30665001530522%,80.05203820042827% 80.05203820042827%,71.30665001530522% 77.76736691019323%,75% 93.30127018922192%,63.39392013277814% 82.33578363789503%,60.99980941685714% 91.0518476172854%,54.56841672770181% 84.70057014808336%,50% 100%,45.4315832722982% 84.70057014808336%,39.000190583142874% 91.0518476172854%,36.606079867221865% 82.33578363789505%,25.00000000000001% 93.30127018922194%,28.693349984694787% 77.76736691019323%,19.947961799571733% 80.05203820042827%,22.23263308980677% 71.30665001530522%,6.698729810778076% 75.00000000000001%,17.664216362104966% 63.39392013277815%,8.948152382714603% 60.99980941685715%,15.299429851916635% 54.568416727701816%,0% 50.00000000000001%,15.299429851916635% 45.431583272298205%,8.94815238271459% 39.00019058314288%,17.66421636210496% 36.60607986722188%,6.698729810778062% 25.000000000000014%,22.23263308980676% 28.693349984694787%,19.947961799571715% 19.947961799571747%,28.69334998469477% 22.232633089806775%,24.99999999999998% 6.698729810778083%,36.60607986722184% 17.664216362104973%,39.00019058314284% 8.948152382714603%,45.43158327229816% 15.299429851916642%,49.99999999999999% 0%,54.568416727701795% 15.299429851916635%,60.99980941685711% 8.94815238271459%,63.39392013277812% 17.66421636210496%,74.99999999999997% 6.6987298107780475%,71.3066500153052% 22.23263308980675%,80.05203820042826% 19.947961799571722%,77.76736691019323% 28.69334998469477%,93.30127018922192% 24.99999999999998%,82.33578363789502% 36.60607986722184%,91.0518476172854% 39.00019058314283%,84.70057014808336% 45.43158327229816%)}
.clip-animation {
animation: clip 1s infinite
}
#keyframes clip {
0% {
clip-path: polygon(100% 50%,84.70057014808336% 54.5684167277018%,91.0518476172854% 60.99980941685713%,82.33578363789503% 63.39392013277814%,93.30127018922194% 75%,77.76736691019323% 71.30665001530522%,80.05203820042827% 80.05203820042827%,71.30665001530522% 77.76736691019323%,75% 93.30127018922192%,63.39392013277814% 82.33578363789503%,60.99980941685714% 91.0518476172854%,54.56841672770181% 84.70057014808336%,50% 100%,45.4315832722982% 84.70057014808336%,39.000190583142874% 91.0518476172854%,36.606079867221865% 82.33578363789505%,25.00000000000001% 93.30127018922194%,28.693349984694787% 77.76736691019323%,19.947961799571733% 80.05203820042827%,22.23263308980677% 71.30665001530522%,6.698729810778076% 75.00000000000001%,17.664216362104966% 63.39392013277815%,8.948152382714603% 60.99980941685715%,15.299429851916635% 54.568416727701816%,0% 50.00000000000001%,15.299429851916635% 45.431583272298205%,8.94815238271459% 39.00019058314288%,17.66421636210496% 36.60607986722188%,6.698729810778062% 25.000000000000014%,22.23263308980676% 28.693349984694787%,19.947961799571715% 19.947961799571747%,28.69334998469477% 22.232633089806775%,24.99999999999998% 6.698729810778083%,36.60607986722184% 17.664216362104973%,39.00019058314284% 8.948152382714603%,45.43158327229816% 15.299429851916642%,49.99999999999999% 0%,54.568416727701795% 15.299429851916635%,60.99980941685711% 8.94815238271459%,63.39392013277812% 17.66421636210496%,74.99999999999997% 6.6987298107780475%,71.3066500153052% 22.23263308980675%,80.05203820042826% 19.947961799571722%,77.76736691019323% 28.69334998469477%,93.30127018922192% 24.99999999999998%,82.33578363789502% 36.60607986722184%,91.0518476172854% 39.00019058314283%,84.70057014808336% 45.43158327229816%);
}
50% {
clip-path: polygon(84.70057014808336% 54.5684167277018%,91.0518476172854% 60.99980941685713%,82.33578363789503% 63.39392013277814%,93.30127018922194% 75%,77.76736691019323% 71.30665001530522%,80.05203820042827% 80.05203820042827%,71.30665001530522% 77.76736691019323%,75% 93.30127018922192%,63.39392013277814% 82.33578363789503%,60.99980941685714% 91.0518476172854%,54.56841672770181% 84.70057014808336%,50% 100%,45.4315832722982% 84.70057014808336%,39.000190583142874% 91.0518476172854%,36.606079867221865% 82.33578363789505%,25.00000000000001% 93.30127018922194%,28.693349984694787% 77.76736691019323%,19.947961799571733% 80.05203820042827%,22.23263308980677% 71.30665001530522%,6.698729810778076% 75.00000000000001%,17.664216362104966% 63.39392013277815%,8.948152382714603% 60.99980941685715%,15.299429851916635% 54.568416727701816%,0% 50.00000000000001%,15.299429851916635% 45.431583272298205%,8.94815238271459% 39.00019058314288%,17.66421636210496% 36.60607986722188%,6.698729810778062% 25.000000000000014%,22.23263308980676% 28.693349984694787%,19.947961799571715% 19.947961799571747%,28.69334998469477% 22.232633089806775%,24.99999999999998% 6.698729810778083%,36.60607986722184% 17.664216362104973%,39.00019058314284% 8.948152382714603%,45.43158327229816% 15.299429851916642%,49.99999999999999% 0%,54.568416727701795% 15.299429851916635%,60.99980941685711% 8.94815238271459%,63.39392013277812% 17.66421636210496%,74.99999999999997% 6.6987298107780475%,71.3066500153052% 22.23263308980675%,80.05203820042826% 19.947961799571722%,77.76736691019323% 28.69334998469477%,93.30127018922192% 24.99999999999998%,82.33578363789502% 36.60607986722184%,91.0518476172854% 39.00019058314283%,84.70057014808336% 45.43158327229816%,100% 50%);
}
100% {
clip-path: polygon(91.0518476172854% 60.99980941685713%,82.33578363789503% 63.39392013277814%,93.30127018922194% 75%,77.76736691019323% 71.30665001530522%,80.05203820042827% 80.05203820042827%,71.30665001530522% 77.76736691019323%,75% 93.30127018922192%,63.39392013277814% 82.33578363789503%,60.99980941685714% 91.0518476172854%,54.56841672770181% 84.70057014808336%,50% 100%,45.4315832722982% 84.70057014808336%,39.000190583142874% 91.0518476172854%,36.606079867221865% 82.33578363789505%,25.00000000000001% 93.30127018922194%,28.693349984694787% 77.76736691019323%,19.947961799571733% 80.05203820042827%,22.23263308980677% 71.30665001530522%,6.698729810778076% 75.00000000000001%,17.664216362104966% 63.39392013277815%,8.948152382714603% 60.99980941685715%,15.299429851916635% 54.568416727701816%,0% 50.00000000000001%,15.299429851916635% 45.431583272298205%,8.94815238271459% 39.00019058314288%,17.66421636210496% 36.60607986722188%,6.698729810778062% 25.000000000000014%,22.23263308980676% 28.693349984694787%,19.947961799571715% 19.947961799571747%,28.69334998469477% 22.232633089806775%,24.99999999999998% 6.698729810778083%,36.60607986722184% 17.664216362104973%,39.00019058314284% 8.948152382714603%,45.43158327229816% 15.299429851916642%,49.99999999999999% 0%,54.568416727701795% 15.299429851916635%,60.99980941685711% 8.94815238271459%,63.39392013277812% 17.66421636210496%,74.99999999999997% 6.6987298107780475%,71.3066500153052% 22.23263308980675%,80.05203820042826% 19.947961799571722%,77.76736691019323% 28.69334998469477%,93.30127018922192% 24.99999999999998%,82.33578363789502% 36.60607986722184%,91.0518476172854% 39.00019058314283%,84.70057014808336% 45.43158327229816%,100% 50%,84.70057014808336% 54.5684167277018%);
}
}
<img class="clip-animation" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/building-to-be-clipped.jpg">
Related
Why this isn't working? What am I doing wrong?
CSS
#-webkit-keyframes test {
0% {
background-image: url('frame-01.png');
}
20% {
background-image: url('frame-02.png');
}
40% {
background-image: url('frame-03.png');
}
60% {
background-image: url('frame-04.png');
}
80% {
background-image: url('frame-05.png');
}
100% {
background-image: url('frame-06.png');
}
}
div {
float: left;
width: 200px;
height: 200px;
-webkit-animation-name: test;
-webkit-animation-duration: 10s;
-webkit-animation-iteration-count: 2;
-webkit-animation-direction: alternate;
-webkit-animation-timing-function: linear;
}
DEMO
http://jsfiddle.net/hAGKv/
Updated for 2020: Yes, it can be done! Here's how.
Snippet demo:
#mydiv{ animation: changeBg 1s infinite; width:143px; height:100px; }
#keyframes changeBg{
0%,100% {background-image: url("https://i.stack.imgur.com/YdrqG.png");}
25% {background-image: url("https://i.stack.imgur.com/2wKWi.png");}
50% {background-image: url("https://i.stack.imgur.com/HobHO.png");}
75% {background-image: url("https://i.stack.imgur.com/3hiHO.png");}
}
<div id='mydiv'></div>
Background image [isn't a property that can be animated][1] - you can't tween the property.
Original Answer: (still a good alternative)
Instead, try laying out all the images on top of each other using position:absolute, then animate the opacity of all of them to 0 except the one you want repeatedly.
It works in Chrome 19.0.1084.41 beta!
So at some point in the future, keyframes could really be... frames!
You are living in the future ;)
Works for me.
Notice the use of background-image for transition.
#poster-img {
background-repeat: no-repeat;
background-position: center;
position: absolute;
overflow: hidden;
-webkit-transition: background-image 1s ease-in-out;
transition: background-image 1s ease-in-out;
}
This is really fast and dirty, but it gets the job done: jsFiddle
#img1, #img2, #img3, #img4 {
width:100%;
height:100%;
position:fixed;
z-index:-1;
animation-name: test;
animation-duration: 5s;
opacity:0;
}
#img2 {
animation-delay:5s;
-webkit-animation-delay:5s
}
#img3 {
animation-delay:10s;
-webkit-animation-delay:10s
}
#img4 {
animation-delay:15s;
-webkit-animation-delay:15s
}
#-webkit-keyframes test {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
}
}
#keyframes test {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
}
}
I'm working on something similar for my site using jQuery, but the transition is triggered when the user scrolls down the page - jsFiddle
I needed to do the same thing as you and landed on your question. I ended up taking finding about the steps function which I read about from here.
JSFiddle of my solution in action (Note it currently works in Firefox, I'll let you add the crossbrowser lines, trying to keep the solution clean of clutter)
First I created a sprite sheet that had two frames. Then I created the div and put that as the background, but my div is only the size of my sprite (100px).
<div id="cyclist"></div>
#cyclist {
animation: cyclist 1s infinite steps(2);
display: block;
width: 100px;
height: 100px;
background-image: url('../images/cyclist-test.png');
background-repeat: no-repeat;
background-position: top left;
}
The animation is set to have 2 steps and have the whole process take 1 second.
#keyframes cyclist {
0% {
background-position: 0 0;
}
100% {
background-position: 0 -202px; //this should be cleaned up, my sprite sheet is 202px by accident, it should be 200px
}
}
Thiago above mentioned the steps function but I thought I'd elaborate more on it. Pretty simple and awesome stuff.
Your code can work well with some adaptations :
div {
background-position: 50% 100%;
background-repeat: no-repeat;
background-size: contain;
animation: animateSectionBackground infinite 240s;
}
#keyframes animateSectionBackground {
00%, 11% { background-image: url(/assets/images/bg-1.jpg); }
12%, 24% { background-image: url(/assets/images/bg-2.jpg); }
25%, 36% { background-image: url(/assets/images/bg-3.jpg); }
37%, 49% { background-image: url(/assets/images/bg-4.jpg); }
50%, 61% { background-image: url(/assets/images/bg-5.jpg); }
62%, 74% { background-image: url(/assets/images/bg-6.jpg); }
75%, 86% { background-image: url(/assets/images/bg-7.jpg); }
87%, 99% { background-image: url(/assets/images/bg-8.jpg); }
}
Here is the explanation of the percentage to suit your situation:
First you need to calculate the "chunks". If you had 8 differents background, you need to do :
100% / 8 = 12.5% (to simplify you can let fall the decimals) => 12%
After that you obtain that :
#keyframes animateSectionBackground {
00% { background-image: url(/assets/images/bg-1.jpg); }
12% { background-image: url(/assets/images/bg-2.jpg); }
25% { background-image: url(/assets/images/bg-3.jpg); }
37% { background-image: url(/assets/images/bg-4.jpg); }
50% { background-image: url(/assets/images/bg-5.jpg); }
62% { background-image: url(/assets/images/bg-6.jpg); }
75% { background-image: url(/assets/images/bg-7.jpg); }
87% { background-image: url(/assets/images/bg-8.jpg); }
}
If you execute this code, you will see the transition will be permanantly. If you want the backgrounds stay fixed while a moment, you can do like this :
#keyframes animateSectionBackground {
00%, 11% { background-image: url(/assets/images/bg-1.jpg); }
12%, 24% { background-image: url(/assets/images/bg-2.jpg); }
25%, 36% { background-image: url(/assets/images/bg-3.jpg); }
37%, 49% { background-image: url(/assets/images/bg-4.jpg); }
50%, 61% { background-image: url(/assets/images/bg-5.jpg); }
62%, 74% { background-image: url(/assets/images/bg-6.jpg); }
75%, 86% { background-image: url(/assets/images/bg-7.jpg); }
87%, 99% { background-image: url(/assets/images/bg-8.jpg); }
}
That mean you want :
bg-1 stay fixed from 00% to 11%
bg-2 stay fixed from 12% to 24%
etc
By putting 11%, the transtion duration will be 1% (12% - 11% = 1%).
1% of 240s (total duration) => 2.4 seconds.
You can adapt according to your needs.
The linear timing function will animate the defined properties linearly. For the background-image it seems to have this fade/resize effect while changing the frames of you animation (not sure if it is standard behavior, I would go with #Chukie B's approach).
If you use the steps function, it will animate discretely. See the timing function documentation on MDN for more detail. For you case, do like this:
-webkit-animation-timing-function: steps(1,end);
animation-timing-function: steps(1,end);
See this jsFiddle.
I'm not sure if it is standard behavior either, but when you say that there will be only one step, it allows you to change the starting point in the #keyframes section. This way you can define each frame of you animation.
Like the above stated, you can't change the background images in the animation. I've found the best solution to be to put your images into one sprite sheet, and then animate by changing the background position, but if you're building for mobile, your sprite sheets are limited to less than 1900x1900 px.
I needed to do the same thing recently. Here's a simple implementation
#wrapper { width:100%; height:100%; position:relative; }
#wrapper img { position:absolute; top:0; left:0; width:100%; height:auto; display:block; }
#wrapper .top { animation:fadeOut 2s ease-in-out; animation-fill-mode:forwards; }
#keyframes fadeOut {
0% { opacity:1; }
100% { opacity:0; }
}
<div id="wrapper">
<img src="img1.jpg" class="top" style="z-index:2;">
<img src="img2.jpg" style="z-index:1;">
</div>
You can use animated background-position property and sprite image.
You can follow by this code:
#cd{
position: relative;
margin: 0 auto;
height: 281px;
width: 450px;
}
#cf img{
left: 0;
position: absolute;
-moz-transition: opacity 1s ease-in-out;
transition: opacity 1s ease-in-out;
}
#cf img.top:hover{
opacity: 0;
}
<div id="cf">
<img class="button" src="Birdman.jpg" />
<img src="Turtle.jpg" class="top" />
</div>
You can use the jquery-backstretch image which allows for animated slideshows as your background-images!
https://github.com/jquery-backstretch/jquery-backstretch
Scroll down to setup and all of the documentation is there.
Well I can change them in chrome. Its simple and works fine in Chrome using -webkit css properties.
I have a cartoon of an antique "detour" sign that has cataphote reflectors embedded in the letters. I want the reflectors to brighten as the image is hovered. That's easily done, I know, simply by swapping out a version of the image with the reflectors darkened with an image of them brightened on hover (per the markup below). However, doing it this way makes the reflectors appear to blink on or off. I want them to get increasingly bright as the cursor nears the center of the image and, of course, dim as the cursor moves away from it, as would occur in real life. (If your headlights beamed at the reflectors at an oblique angle, the light they reflect back would be dimmer than if your headlights hit them straight on.)
My thought is just to increase the opacity of the brightened version of the image in response to the position of the hovering cursor. So, what I need (I think) is a script that detects the cursor position and increases or decreases the opacity accordingly: opacity: 0; at the edge and opacity: 1; at the center. Probably not too challenging for someone adept in javascript/jquery. I've hunted around for a script that does that or something very close to it but haven't been able to locate one that is close enough for me to modify.
I have an additional issue in that in Firefox, at least, the hover image "flicks" the first time it is invoked. I've tried all of the preloading suggestions I could find here on stackoerflow but none of them work. I found that a sprite solved the flicking problem, but wasn't sure how that would work with the way I want the image to animate. Presuming non-sprite images are the way to go maybe if the script invokes the "bright" version of the image at an initial opacity of 0 as the cursor crosses the threshhold, it will also hide the loading "flick...?" Just a guess. Alternatively, I could redesign the hovered version so that it is just the reflectors if that would solve everything else.
Finally, as you can see, the sign is a button that returns a random page. Assuming what I need to solve this problem is a script, can I run both scripts off of the same id (#detour) or should this script use a class name instead? (I am clearly an example of a little knowledge being a dangerous thing.)
Anyway, here's what I've got.
.detour-box {
position: relative;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
#detour {
position: absolute;
background: transparent url(https://sodyot.com/wp-content/uploads/2021/03/detour-sign_3.png) no-repeat center center;
background-size: 100%;
clip-path: polygon(48% 0%, 49% 1%, 50% 0%, 69% 19%, 81% 31%, 94% 42%, 100% 48%, 100% 49%, 85% 65%, 76% 75%, 63% 88%, 53% 99%, 52% 100%, 48% 97%, 37% 87%, 28% 79%, 16% 67%, 8% 59%, 0 49%, 3% 45%, 14% 35%, 28% 20%);
width: 300px;
height: 295px;
}
#detour:hover {
background: transparent url(https://sodyot.com/wp-content/uploads/2021/03/detour-sign_3on.png) no-repeat center center;
background-size: 100%;
cursor: pointer;
}
<div class="detour-box">
<button id="detour" class="detour" onclick="randomlink()"></button>
</div>
It's not possible to transition from one image to another on the same element by changing the src or background-image value. But you can do it by having both images, and hiding one by default.
Having one image hidden opens the possibility to fade or crossfade between the images. Lay them on top of each other, with the hidden image on top, and show the hidden image on hover.
The image on top can now fade-in by changing the opacity value. With the transition property you can control the transition.
.detour-box {
position: relative;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
#detour {
position: absolute;
display: grid;
grid-template: 1fr / 1fr;
clip-path: polygon(48% 0%, 49% 1%, 50% 0%, 69% 19%, 81% 31%, 94% 42%, 100% 48%, 100% 49%, 85% 65%, 76% 75%, 63% 88%, 53% 99%, 52% 100%, 48% 97%, 37% 87%, 28% 79%, 16% 67%, 8% 59%, 0 49%, 3% 45%, 14% 35%, 28% 20%);
width: 300px;
height: 295px;
cursor: pointer;
}
#detour img {
grid-area: 1 / 1 / 2 / 2;
width: 100%;
height: 100%;
}
#detour img:last-child {
opacity: 0;
transition: opacity 250ms ease-in-out;
z-index: 1;
}
#detour:hover img:last-child {
opacity: 1;
}
<div class="detour-box">
<button id="detour" class="detour" onclick="randomlink()">
<img src="https://sodyot.com/wp-content/uploads/2021/03/detour-sign_3.png" alt="Detour sign off"/>
<img src="https://sodyot.com/wp-content/uploads/2021/03/detour-sign_3on.png" alt="Detour sign on"/>
</button>
</div>
If we punch holes in the detour sign we only need one image.
The background image can have a linear gradient put behind it, the color(s) of which are changed as the mouse moves. In this snippet the color is always some gray, going up to white, and is changed depending on the y movement of the mouse. It would be easy to change it to take x into account as well. And there could be a real gradient to the background to give different effects - depends just what effect is wanted.
The JS alters a CSS variable, --col, depending on the distance from the center.
function makeColor(d) {
d = Math.floor(d);
return 'rgb(' + d + ',' + d + ',' + d + ')';//could use rgba to get opacity also
}
const detour = document.getElementById("detour");
const dimCol = 128;//set this to the initial (switched off) r, g and b gray
detour.style.setProperty('--col', makeColor(dimCol));
detour.addEventListener('mouseout', function () {
detour.style.setProperty('--col', makeColor(dimCol));
});
detour.addEventListener('mousemove', function () {
const rect = detour.getBoundingClientRect();// this should be in a window resize function if you have one
const h = rect.height;// ditto
const y = event.clientY - rect.top; //ditto
const distanceY = Math.abs(y - h/2)/h;
const d = 255 * (1 - 2 * distanceY);
detour.style.setProperty('--col', makeColor(dimCol + (d * (255 - dimCol) / 255)));
});
.detour-box {
position: relative;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
div#detour {
position: absolute;
background-color: transparent;
background-image: url(https://ahweb.org.uk/detour-with-holes.png), linear-gradient(to bottom, transparent 0%, transparent 40%, var(--col) 40%, var(--col) 60%, transparent 60%, transparent 100%);
background-repeat: no-repeat;
background-position: center center;
background-size: 100%, 70%;
clip-path: polygon(48% 0%, 49% 1%, 50% 0%, 69% 19%, 81% 31%, 94% 42%, 100% 48%, 100% 49%, 85% 65%, 76% 75%, 63% 88%, 53% 99%, 52% 100%, 48% 97%, 37% 87%, 28% 79%, 16% 67%, 8% 59%, 0 49%, 3% 45%, 14% 35%, 28% 20%);
width: 300px;
height: 295px;
margin: 0;
padding: 0;
}
<div class="detour-box">
<div id="detour" class="detour" onclick="randomlink()"></div>
</div>
It is fine to have more than one event listener on an element, so the existing onclick remains.
I am creating an interactive touchscreen display using a program called Intuiface and have created some background tiles/squares that I want to make look 'alive' by transitioning slowly between colours.
I have used a linear-gradient transition in CSS to do it but the problem is that the transition looks choppy. The program is running 12 visible tiles (it is a very large touchscreen).
I have tried using fewer colours and running on more powerful GPUs (I think it is CPU run anyway) but this hasn't helped.
body {
width: 100wh;
height: 90vh;
background: linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB);
background-size: 400% 400%;
animation: Gradient 15s ease infinite;
}
#keyframes Gradient {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
At the moment the animations are noticeably choppy. I would like the transition to be much smoother. Does anyone know how I can achieve this?
Here is the code snippet.
body {
width: 100wh;
height: 90vh;
background: linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB);
background-size: 400% 400%;
animation: Gradient 15s ease infinite;
}
#keyframes Gradient {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
<html>
<body>
</body>
</html>
Animating background-* properties can be resource intensive - you can try animating transform for relatively better performance - see demo below using traslate for the animation:
body {
margin: 0;
}
div {
height: 100vh;
overflow: hidden;
}
div:after {
content: '';
display: block;
width: 400vw;
height: 400vh;
background: linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB);
animation: gradient 15s ease infinite;
}
#keyframes gradient {
50% {
transform: translate(-300vw, -300vh);
}
}
<div></div>
Since your animation lasts 15 seconds, trying to run it at full 60fps would mean calculating 15*60 = 900 frames.
Since the difference between a frame and the next is quite small, you can make the CPU work quite less asking for a stepped animation, for instance with steps(75)
It could be also good to set slight delays between animations, so that they don't execute at the same time
body {
width: 100wh;
height: 90vh;
background: linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB);
background-size: 400% 400%;
animation: Gradient 15s infinite steps(75);
}
#keyframes Gradient {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
<html>
<body>
</body>
</html>
I'm working on the animation of a square that should increase its shake while the time is passing starting from no shake till a big shake right now I have this code but it is not working properly.
#BplusBT{
position: relative;
width: 40px;
height: 40px;
background-color: blue;
}
.ballepacioH{
background-repeat: no-repeat;
background-size: contain;
width: 4px;
height: 4px;
list-style-type: none;
}
<div class='column'>
<li id='BplusBT'></li>
<li class='ballepacioH'></li>
<li id='BplusBT'></li>
<li class='ballepacioH'></li>
<li id='BplusBT'></li>
</div>
var div = document.createElement('div');
div.innerHTML = htmlLeyenda;
sym.$("recuadro_esferas").append(div);
var circles = document.querySelectorAll("#BplusBT");
for (var i = 0; i < 3; i++) {
var circle = circles[i];
circles.keyframes = [{
transform: "translate(" + "0px, 2px)"
}, {
transform: "translate(" + "0px, -2px)"
},{
transform: "translate(" + "0px, 0px)"
}];
circle.animProps = {
duration: 10 + 5 * i,
easing: "ease-out",
iterations: Infinity
}
var animationPlayer = circle.animate(circle.keyframes, circle.animProps);
}
It's pretty simple actually, just define multiple animation states and play around with their %'s, then split them into groups with the same % difference between the starting and ending state. The example below has three groups with 5%, 3% and 1% difference between the states, meaning 5% transforms will take the longest and 1% the shortest amount of the animation duration:
.ballepacioH {
position: relative;
width: 40px;
height: 40px;
background-color: blue;
list-style: none;
animation: shake 2s infinite;
}
#keyframes shake {
0%, 49% {transform: initial} /* 2s * 0.49 = 0.98s of idle time */
/* 5% apart / starts slow */
49.01%, 54% {transform: translate(2px, 2px)}
59.01%, 64% {transform: translate(-2px, -2px)}
69.01%, 74% {transform: translate(2px, 2px)}
79.01%, 84% {transform: translate(-2px, -2px)}
/* 3% apart */
84.01%, 87% {transform: translate(2px, 2px)}
87.01%, 90% {transform: translate(-2px, -2px)}
90.01%, 93% {transform: translate(2px, 2px)}
93.01%, 96% {transform: translate(-2px, -2px)}
/* 1% apart / ends fast */
96.01%, 97% {transform: translate(2px, 2px)}
97.01%, 98% {transform: translate(-2px, -2px)}
98.01%, 99% {transform: translate(2px, 2px)}
99.01%, 100% {transform: translate(-2px, -2px)}
}
<div class='column'>
<li class='ballepacioH'></li>
</div>
Note: Id's are meant to be unique, i.e. don't use the same id for multiple elements.
I have been able to animate a div with a background image as well as resize it along the path. However, I am trying to get this CSS-based animation to stop at a certain percentage of the progress.
The premise is to visually show a student her/his progress of completing a varying number of tasks (8 of 12 complete. 68%). That is not a problem with a straight progress bar, but I am looking to use an image of a mountain with a hiker moving along a path. I can get the hiker image from start to end with the following code, but I need it to stop based on the progress of the student.
I am trying to keep this as simple as I can, but do not have to use CSS.
.mtnBg
{
height:306px;
width:450px;
border:1px silver solid;
background-image: url(https://comps.canstockphoto.com/mountain-with-trail-and-sun-retro-style-eps-vector_csp43572145.jpg);
background-repeat: no-repeat;
background-size: 100%;
display:block;
opacity:.18;
z-index:-1;
}
.animSurround {
margin:0;
padding:0;
height:32px;
width:32px;
display:block;
position:relative;
left:140px;
bottom:50px;
border:1px none black;
animation: yAxis 2.8s 1 ease;
}
.anim {
background-image: url(https://www.tenstickers.co.uk/wall-stickers/img/preview/hiker-icon-sticker-8451.png);
background-repeat: no-repeat;
min-height:32px;
min-width:32px;
background-size: 100%;
animation-iteration-count:1;
animation: zoom-move 2.8s ease 1;
animation-fill-mode: forwards;
}
.anim::after {
/* Render dot, and animate along Y-axis */
min-height:96px;
min-width:96px;
}
#keyframes zoom-move {
0% {
transform: scale(3) translateX(calc(0px)) translateY(0px);
opacity: 0.50;
border-radius:32px;
background-color: rgba(256 , 256, 256, 1);
}
25% {
transform: scale(2.6) translateX(60px) translateY(-19px);
opacity: 1;
border-radius:32px;
background-color: rgba(256 , 256, 256, 1);
}
50% {
transform: scale(1.7) translateX(68px) translateY(-50px);
opacity: 1;
border-radius:32px;
background-color: rgba(256 , 256, 256, 1);
animation-play-state: paused;
}
93% {
background-color: rgba(256 , 256, 256, 1);
}
99% {
transform: scale(1.1) translateX(161px) translateY(-122px);
opacity: 1;
border-radius:32px;
background-color: rgba(76, 175, 80, 1);
}
100% {
transform: scale(1.1) translateX(161px) translateY(-122px);
opacity: 1;
border-radius:32px;
background-color: rgba(76, 175, 80, 1);
}
}
<div class="mtnBg"></div>
<div class="animSurround">
<div class="anim"></div>
</div>
Any help would be appreciated.
You can rely on the animation-play-state property. The is idea to convert the % value to the time when the animation should be paused. So you using JS/jQuery you run the animation and after this amount of time you set the property animation-play-state:
Here is an example with a simplied animation:
/* if we want the animation to run until 10%
we consider a duratioon of Xs and we should run until 0.1 * Xs
The duration will only affect the speed
so use a small value to simulate an instant change.
*/
var duration = 3;
function stop_animation(element, percent) {
var stop = (percent / 100) * duration; /* we get the value un second*/
stop *= 1000 /* we transform to milliseconds */
element.css('animation', 'anim ' + duration + 's linear');
setTimeout(function() {
element.css('animation-play-state', 'paused');
}, stop);
}
stop_animation($('.element').eq(0),50);
stop_animation($('.element').eq(1),20);
.container {
width: 200px;
height: 50px;
border: 1px solid;
border-left: 0;
background: linear-gradient(to right, #000 10%, transparent 11%) 0 0/20px 100%;
}
.element {
height: 100%;
width: 20px;
margin-left: 0;
background: red;
}
#keyframes anim {
from {
margin-left: 0;
}
to {
margin-left: calc(100% - 20px);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="element"></div>
</div>
<div class="container">
<div class="element"></div>
</div>