Reputation: 403
I've been implementing some CSS
animations as named classes so I can easily add/remove any associated animation for an element, making it "available" for subsequent or repeat animations.
I'm dipping my toes into using CSS
variables and it's currently throwing me for a loop. I'm trying to allow the user to rotate an active image in 90 degree increments. In the code example below, I'm showing only the positive 90 button click event.
*.scss
:root {
--rotation-degrees: 90;
}
@keyframes rotate {
100% {
transform: rotate(var(--rotation-degrees)+'deg');
}
}
.animation-rotate {
--rotation-degrees: 90;
// NOTE: I suspect the variable does not need to be supplied here, removing does
// not fix the issue, at least in isolation
animation: rotate(var(--rotation-degrees)) 0.2s forwards;
}
*.js
let degrees = 0;
function rotate(degrees_increment) {
degrees += degrees_increment;
// The use of document.documentElement.style.setProperty is something I've seen
// used in many of the articles I've read as a means to "get to" the css variable,
// so I'm simply blindly copying it's use here
document.documentElement.style.setProperty('--rotation-degrees', degrees +'deg');
$('#main-image-slider img').addClass('animation-rotate');
}
$('#rotate-right-button').on('click', function(event) {
event.preventDefault();
rotate(90);
});
Thank you in advance for any insights and help you can give!
Upvotes: 0
Views: 1804
Reputation: 11
I think the highlighted code is not triggering the animation again when adding a class - Existing Code
var angle = 0;
$("#rotate").click(function(e){
angle+= 90;
document.documentElement.style.setProperty('--deg', angle+'deg');
var el = $(".square");
var newone = el.clone(true);
el.before(newone);
$(".square:last").remove();
});
:root {
--deg: 180deg;
}
@keyframes rotate {
100% {transform: rotate(var(--deg));}
}
.animation-rotate {
animation: rotate 0.9s forwards;
}
.square {
background: hsl(300, 90%, 52%);
width: 15vmin;
height: 15vmin;
border-radius: 10%;
margin: 25px;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="square animation-rotate"></div>
<div>
<button class="btn btn-sm btn-success" id="rotate">Rotate</button>
</div>
</div>
Upvotes: 1
Reputation: 22949
I don't think it's possible to concatenate a CSS variable with a string as you were trying in your CSS:
transform: rotate(var(--rotation-degrees)+'deg');
It's better to handle that with JavaScript.
I think the main issue you're having is that the class needs to be removed after the animation has run (in order for it to be able to run again). You can do that with the animationend event listener.
Demo below:
const DIV = $('div');
const BUTTON = $('#rotate-right-button');
const SPAN = $('#variable-value');
const PROPERTY_NAME = '--rotation-degrees';
const DEG = 'deg';
const ROOT = document.documentElement;
const ElementClass = {
ROTATE_ANIMATION: 'animation-rotate'
}
const ROTATION_VALUE = 90;
const Event = {
CLICK: 'click',
ANIMATION_END: 'animationend'
}
let degrees = 0;
function rotate(degrees_increment) {
degrees += degrees_increment;
ROOT.style.setProperty(PROPERTY_NAME, degrees + DEG);
SPAN.html(`${PROPERTY_NAME}: ${degrees + DEG}`);
}
BUTTON.on(Event.CLICK, function() {
DIV.addClass(ElementClass.ROTATE_ANIMATION);
DIV.on(Event.ANIMATION_END, function(event) {
$(this).removeClass(ElementClass.ROTATE_ANIMATION);
});
rotate(ROTATION_VALUE);
});
@keyframes rotate {
100% {
transform: rotate(var(--rotation-degrees));
}
}
.animation-rotate {
animation: rotate 0.2s;
}
div {
background: red;
width: 100px;
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>
<button id="rotate-right-button">rotate</button>
<br>
<span id="variable-value"></span>
Upvotes: 1
Reputation: 1562
I'm not sure I understand your code, but here's my take on it.
When the user clicks, you can either:
- add/remove a CSS class. In that case the values for the rotation are already set in your CSS.
- rotate the element directly in JavaScript, for instance by dynamically setting a CSS rule.
Seems to me like you're doing both at the same time?
Upvotes: 0