React inlined SVG paths are not responding to css animations - javascript

I uploaded my code and svgs to this github repo.
I have some svgs of some circles, blobs and triangles. I am trying to make the circles shake, like how the guy shakes in this code pen when you hover on him, I am trying to make the blobs move like waves like in this code pen, and I'm trying to make the triangles spin around. The blobs and triangles are not responding at all, even though I can see that they have the styling applied when I inspect the html. The circles have some effect, but not the one I want.
Here is the code for each
circles.scss
.circles > circle {
animation: shake 2.2s cubic-bezier(.36,.07,.19,.97) both;
}
#keyframes shake {
10%, 90% {
transform: translate3d(-1px, 0, 0);
}
20%, 80% {
transform: translate3d(2px, 0, 0);
}
30%, 50%, 70% {
transform: translate3d(-4px, 0, 0);
}
40%, 60% {
transform: translate3d(4px, 0, 0);
}
}
triangles.scss
.triangles > g > path {
animation: triangle-animation 2.2s cubic-bezier(.36,.07,.19,.97) both;
}
#keyframes triangle-animation {
10%, 90% {
tranform: rotate(5deg);
}
20%, 80% {
tranform: rotate(90deg);
}
30%, 50%, 70% {
tranform: rotate(180deg);
}
40%, 60% {
tranform: rotate(30deg);
}
100% {
tranform: rotate(0deg);
}
}
waves.scss
.waves > path {
animation: wave-animation 4s infinite alternate;
// animation-duration: 4s;
// animation-iteration-count: infinite;
// animation-direction: alternate;
}
#keyframes wave-animation {
0% {
margin-left:0px;
margin-top:0px;
}
50% {
margin-left:-2000px;
margin-top:200px;
}
100% {
margin-left:0px;
margin-top:0px;
}
}
And this is my main App.js file
import React from 'react';
import Blobs from 'svg/Blobs.svg'
import Circles from 'svg/Circles.svg';
import Triangles from 'svg/Triangles.svg';
export default () => (
<div>
<Circles className="circles" />
<Blobs className=" w-100 h-100 waves" />
<Triangles className='w-100 triangles' />
</div>
);
The styles are imported in index.js
Thank you

Create components with the svg code inside then add your css classes ...
I advise you to start from scratch and create your own svg, it's easier than using already created svg.
(check the demo at the bottom of the page with the triangles, circles and waves)
App.js
import React from 'react';
import './style.css';
import Triangles from './svg/Triangles';
export default function App() {
return (
<div>
<Triangles />
</div>
);
}
Triangles.js
import React from 'react';
export default function Triangles() {
return (
<div className="triangles">
<svg className="triangle one">
<path d="M150 0 L30 200 L270 200 Z" />
</svg>
<svg className="triangle two">
<path d="M120 0 L30 180 L200 200 Z" />
</svg>
<svg className="triangle three">
<path d="M10 0 L40 280 L190 170 Z" />
</svg>
</div>
);
}
style.css
/* Triangles */
.triangles {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 50vh;
}
.triangle {
position: absolute;
fill: rgb(23, 233, 224);
fill-opacity: 0.4;
animation-name: spin;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
.triangle.one {
height: 210px;
width: 300px;
animation-duration: 5000ms;
}
.triangle.two {
height: 150px;
width: 400px;
animation-duration: 9000ms;
}
.triangle.three {
height: 120px;
width: 300px;
animation-duration: 3000ms;
}
#keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
Demo : Stackblitz

Related

Apply animation to remove a text

I have implemented a nav tab-like view. Three buttons and when we click on one button the text corresponding to the other two buttons get hidden. But I want that when we update the text then we must be seeing some animation like fade in.
var prevId = 1;
function updateView(id) {
document.getElementById("subsec"+prevId).style.visibility = "hidden";
document.getElementById("subsec"+id).style.visibility = "visible";
prevId = id;
}
<div id="subsec1" >
Tab 1
</div>
<button onclick="updateView(1)"></button>
<div id="subsec2" style="visibility: hidden">
Tab 2
</div>
<button onclick="updateView(2)"></button>
<div id="subsec3" style="visibility: hidden">
Tab 3
</div>
<button onclick="updateView(3)"></button>
Can anyone help me with this. I have attached an example of how my view looks.
Example: I am currently on tab 3 and I click on tab 1 then tab 3 content should disappear but through animation and content of tab 1 must appear on-screen through animation only(like fade in).
Please read this from w3schools.com.
Try adding css like
.fadeIn {
animation-name: FadeIn;
animation-duration: 4s;
animation-fill-mode: both;
}
.fadeOut {
animation-name: FadeOut;
animation-duration: 4s;
animation-fill-mode: both;
}
#keyframes FadeIn {
from { opacity: 0%; }
to { opacity: 100%; }
}
#keyframes FadeOut {
from { opacity: 100%; }
to { opacity: 0%; }
}
and then adding javascript like so:
var prevId = 1;
function updateView(id) {
document.getElementById("subsec"+prevId).className = "fadeOut";
document.getElementById("subsec"+id).className = "fadeIn";
preId = id;
}
replace visibility: in html to opacity: 0%, and set the classes at the beginning if you want them to have animation at the beginning.
This is not optimalized.
I had a little play about to show how you might use a slightly simplified HTML markup and a modified button clickhandler function to trigger adding new styles (animations) to your tabs.
The CSS animations here are very basic examples but should serve to illustrate the effect of fading in.
const clickhandler=function(e){
document.querySelectorAll('button[data-tab]').forEach(bttn=>bttn.classList.remove('activebttn') );
document.querySelectorAll('div[data-tab]').forEach( div=>div.classList.remove('active','initial') );
document.querySelector('div[ data-tab="'+this.dataset.tab+'" ]').classList.add('active');
this.classList.add('activebttn');
}
document.querySelectorAll('button[data-tab]').forEach( bttn=>bttn.addEventListener('click',clickhandler) );
div[data-tab]{
background:white;
border:1px solid rgba(0,0,0,0.25);
border-radius:1rem 0 1rem 0;
box-shadow:0 0 1rem rgba(0,0,0,0.25);
margin:1rem auto;
width:600px;
min-height:400px;
padding:1rem;
opacity:0;
}
div[data-tab]:not(.active){
display:none;
}
#keyframes fadein{
0% { opacity:0; }
100% { opacity:1; background:whitesmoke; }
}
#keyframes fadeout{
0%{ opacity:100%;display:block; }
100%{ opacity:0%; background:white; display:none; }
}
#keyframes shake {
10%, 90% {
transform: translate3d(-1px, 0, 0);
}
20%, 80% {
transform: translate3d(2px, 0, 0);
}
30%, 50%, 70% {
transform: translate3d(-4px, 0, 0);
}
40%, 60% {
transform: translate3d(4px, 0, 0);
}
}
.active{
animation-name:fadein, shake;
animation-duration:1s, 1s;
animation-timing-function:ease-in-out;
animation-fill-mode: forwards;
animation-delay: 250ms,750ms;
}
.hide{
animation-name:fadeout;
animation-duration:1s;
animation-timing-function:ease-in-out;
animation-fill-mode: forwards;
animation-delay: 250ms;
}
.initial{
display:block!important;
opacity:1!important;
}
button{
background:rgba(0,0,0,0.25);
border-radius:1rem;
border:1px solid transparent;
width:200px;
cursor:pointer;
padding:1rem;
transition:ease-in-out 250ms all;
}
button:hover{
border:1px solid gray;
background:rgba(255,255,255,0.25);
box-shadow:0 0 5px rgba(0,0,0,0.25);
}
button:active,
.activebttn{
border:1px solid gray;
background:rgba(0,255,0,0.25);
}
<button data-tab=1>Tab 1</button>
<button data-tab=2>Tab 2</button>
<button data-tab=3>Tab 3</button>
<div data-tab=1 class='initial'>
Code finance. Let's put a pin in that one-sheet we need to button up our approach optimize for search nor my supervisor didn't like the latest revision you gave me can you switch back to the first revision?.
</div>
<div data-tab=2>
We need to socialize the comms with the wider stakeholder community prairie dogging, roll back strategy drink the Kool-aid meeting assassin, but form without content style without meaning, yet can we jump on a zoom.
</div>
<div data-tab=3>
Cloud native container based knowledge process outsourcing blue sky. Tribal knowledge. I called the it department about that ransomware because of the old antivirus, but he said that we were using avast 2021 let's schedule a standup during the sprint to review our kpis.
</div>

Is there a JavaScript function to do a animation in reverse after clicking a button a 2nd time?

I'm still learning JavaScript, and not too familiar with it or I have just flat out forgotten it. But I have a button on my page that looks like this:
function hiddenjs() {
var x = document.getElementById("hiddenjs");
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "block";
}
}
.hiddenjsa {
margin: 0 auto;
background-color: red;
animation-name: expandz;
animation-duration: 1.5s;
animation-timing-function: ease-out;
animation-delay: 0;
animation-direction: alternate;
animation-fill-mode: both;
animation-play-state: running;
}
#keyframes expandz {
0% {
transform: scale(.3);
background-color: red;
border-radius: 100%;
}
50% {
background-color: rgb(71, 8, 8);;
}
100% {
transform: scale(1.5);
background-color: rgb(139, 139, 3);
}
}
<div class="btn4">
<button class="btn4a" onclick="hiddenjs()">List of Other Games I'm going to review!</button>
</div>
<div id="hiddenjs" class="hiddenjsa">
Note: These are NOT clickable links yet as I have yet to review them and add them to the site.
These are just references to which I am in the process of reviewing!
</div>
I was wondering, without jQuery, or any other forms of language if there is a way through JavaScript alone, that you can do a toggle button to do the animation (which I've done) and when you click said button again, it does the animation but in reverse?
I've read up a few things on it but can't find something without copy and pasting a jQuery snippet, and I don't want to do that because I want to understand what I'm doing.
You can set an animation on each click to either expand or reverse the expansion. Instead of display settings, set the scale at the start of the forward animation as 0.
This snippet deliberately has two keyframes which are identical but one set to run in reverse, just to make it clearer what is going on.
function hiddenjs() {
var x = document.getElementById("hiddenjs");
if ( x.style.animationDirection != "normal" ) {
x.style.animationDirection = "normal";
x.style.animationName = "expandz";
}
else {
x.style.animationDirection = "reverse";
x.style.animationName= "expandz1";
}
}
.hiddenjsa {
margin: 0 auto;
transform: scale(0);
background-color: red;
animation-duration: 1.5s;
animation-timing-function: ease-out;
animation-delay: 0;
animation-fill-mode: forwards;
}
#keyframes expandz {
0% { transform: scale(0); }
1% {
transform: scale(.3);
background-color: red;
border-radius: 100%;
}
50% {
background-color: rgb(71, 8, 8);;
}
100% {
transform: scale(1.5);
background-color: rgb(139, 139, 3);
}
}
#keyframes expandz1 {
0% { transform: scale(0); }
1% {
transform: scale(.3);
background-color: red;
border-radius: 100%;
}
50% {
background-color: rgb(71, 8, 8);;
}
100% {
transform: scale(1.5);
background-color: rgb(139, 139, 3);
}
}
<div class="btn4" style=“z-index:100;”>
<button class="btn4a" onclick="hiddenjs()">List of Other Games I'm going to review!</button>
</div>
<div id="hiddenjs" class="hiddenjsa">
Note: These are NOT clickable links yet as I have yet to review them and add them to the site.
These are just references to which I am in the process of reviewing!
</div>

how to make an animating blob button using js and css?

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">

Consistent filling of SVG's rectangles

How to make each of these squares filled with red colour consistently left to right; and when one filled with red, previous will have default colour?
#foo > rect {
height: 32px;
width: 32px;
}
<svg id=foo height=32 width=160>
<rect x=0 y=0 />
<rect x=64 y=0 />
<rect x=128 y=0 />
</svg>
This animation must be repeatable.
If you are open to a CSS solution you can simulate such effect using background animation where you can easily scale to any number of square but without fading:
.rect {
height: 32px;
width:calc(40px*10); /* 10 Squares*/
background:
/* This gradient will make the red color to fade from the first to the last*/
linear-gradient(red,red) 0 0/32px 100% no-repeat,
/* This gradient will create the squares (32px of black then 8px of transparent)*/
repeating-linear-gradient(to right,black 0 32px,transparent 32px 40px);
margin:0 5px;
animation:change 10s steps(10) infinite;
}
#keyframes change{
to {
background-position:calc(100% + 32px) 0,0 0;
}
}
<div class="rect"></div>
With CSS variable you can control the different values:
.rect {
--s: 32px; /* Square size */
--nb: 10; /* Square number */
--gap: 8px; /* gap between squares */
--c1:black;
--c2:red;
height: var(--s);
width:calc((var(--gap) + var(--s))*var(--nb));
background:
linear-gradient(var(--c2),var(--c2)) 0 0/var(--s) 100% no-repeat,
repeating-linear-gradient(to right,var(--c1) 0 var(--s),#fff var(--s) calc(var(--s) + var(--gap)));
margin:5px;
animation:change calc(var(--nb)*1s) steps(var(--nb)) infinite;
}
#keyframes change{
to {
background-position:calc(100% + var(--s)) 0,0 0;
}
}
<div class="rect"></div>
<div class="rect" style="--nb:8;--s:50px;--c1:green;--c2:yellow"></div>
<div class="rect" style="--nb:15;--s:10px;--c2:blue"></div>
Use CSS keyframes:
#foo > rect {
height: 32px;
width: 32px;
animation: anim 3s infinite;
}
#foo > rect:nth-of-type(1){
animation-delay: 0s;
}
#foo > rect:nth-of-type(2){
animation-delay: 1s;
}
#foo > rect:nth-of-type(3){
animation-delay: 2s;
}
#keyframes anim{
0% { fill: black; }
50% { fill: red; }
100% { fill: black; }
}
<svg id=foo height=32 width=160>
<rect x=0 y=0 />
<rect x=64 y=0 />
<rect x=128 y=0 />
</svg>

Bounce animation on a scaled object

What is the best way to have an object scale and then perform a bounce animation at that scale factor before going back to the original scale factor. I realize I could do something like scaling it to 2.2, then 1.8, then 2.0, but I'm looking for a way where you just have to perform the bounce animation on the scale factor because my scale factor will change.
Here is my example. Basically I want to combine the two to work like I said but as you can see the bounce animation performs based off the image size prior to scaling.
I need all sides of the image to bounce equally, like the example.
function myFunction() {
var image = document.getElementById('test');
image.style.WebkitTransform = ('scale(2,2)');
image.classList.remove('bounce');
image.offsetWidth = image.offsetWidth;
image.classList.add('bounce') ;
}
div#test {
position:relative;
display: block;
width: 50px;
height: 50px;
background-color: blue;
margin: 50px auto;
transition-duration: 1s;
}
.bounce {
animation: bounce 450ms;
animation-timing-function: linear;
}
#keyframes bounce{
25%{transform: scale(1.15);}
50%{transform: scale(0.9);}
75%{transform: scale(1.1);}
100%{transform: scale(1.0);}
}
<div id='test'> </div>
<button class = 'butt' onclick = 'myFunction()'>FIRST</button>
You can try the use of CSS variable in order to make the scale factor dynamic within the keyframe:
function myFunction(id,s) {
var image = document.querySelectorAll('.test')[id];
image.style.setProperty("--s", s);
image.classList.remove('bounce');
image.offsetWidth = image.offsetWidth;
image.classList.add('bounce');
}
div.test {
display: inline-block;
width: 50px;
height: 50px;
background-color: blue;
margin: 50px;
transform:scale(var(--s,1));
}
.bounce {
animation: bounce 450ms;
animation-timing-function: linear;
}
#keyframes bounce {
25% {
transform: scale(calc(var(--s,1) + 0.2));
}
50% {
transform: scale(calc(var(--s,1) - 0.1));
}
75% {
transform: scale(calc(var(--s,1) + 0.1));
}
100% {
transform: scale(var(--s,1));
}
}
<div class='test'> </div>
<div class='test'> </div>
<div class='test'> </div>
<div>
<button class='butt' onclick='myFunction(0,"2")'>first</button>
<button class='butt' onclick='myFunction(1,"3")'>Second</button>
<button class='butt' onclick='myFunction(2,"0.5")'>third</button>
<button class='butt' onclick='myFunction(1,"1")'>second again</button>
</div>
Dispatch each transform on a different wrapping element.
This way you can achieve several level of transforms, all relative to their parent wrapper.
Then you just need to set your animation to fire after a delay equal to the transition's duration:
btn.onclick = e => {
// in order to have two directions, we need to be a bit verbose in here...
const test = document.querySelector('.test');
const classList = test.classList;
const state = classList.contains('zoomed-in');
// first remove previous
classList.remove('zoomed-' + (state ? 'in' : 'out'));
// force reflow
test.offsetWidth;
// set new one
classList.add('zoomed-' + (state ? 'out' : 'in'));
};
div.test {
position: relative;
display: inline-block;
margin: 50px 50px;
}
div.test div{
width: 100%;
height: 100%;
transition: transform 1s;
}
div.test.zoomed-in .scaler {
transform: scale(2);
}
div.test.zoomed-in .bouncer,
div.test.zoomed-out .bouncer {
animation: bounce .25s 1s;/* transition's duration delay */
}
div.test .inner {
background-color: blue;
width: 50px;
height: 50px;
}
#keyframes bounce {
0% {
transform: scale(1.15);
}
33% {
transform: scale(0.9);
}
66% {
transform: scale(1.1);
}
100% {
transform: scale(1.0);
}
}
<div class="test">
<div class="scaler">
<div class="bouncer">
<div class="inner"></div>
</div>
</div>
</div>
<button id="btn">toggle zoom</button>

Categories