Reputation: 2513
I have five image elements each containing a feather picture. I want to add them to the DOM, where some are randomly flipped right or left, with a random rotation angle.
I want each feather to animate so that they align with the X axis (ie back to 0deg), while also maintaining the scaleX
. In my code below, the realignment works but for the flipped feathers, they also twist back the original "un-flipped" appearance during the animation.
How can I prevent this from happening? I know I could achieve this by using a <div>
as a wrapper around each feather, but is there a better solution?
Javascript
function feathersPuff() {
for (let i = 0; i < 5; i++) {
let feather = document.createElement("img");
feather.src = "imgs/feather" + i + ".svg";
document.body.appendChild(feather);
let plusOrMinus = Math.random() < 0.5 ? -1 : 1;
feather.style.transform = "scaleX(" + plusOrMinus + ") rotate(" + getRandomInt(50) * plusOrMinus + "deg)"
feather.classList.add("feather");
}
}
CSS
.feather {
display: block;
height: 2%;
position: absolute;
animation: realign;
animation-iteration-count: 1;
animation-direction: linear;
animation-timing-function: ease-in-out;
animation-duration: 500ms;
animation-delay: 0;
animation-fill-mode: forwards;
}
@keyframes realign {
100% { transform: rotate(0deg) }
}
Upvotes: 1
Views: 236
Reputation: 30390
If I understand your question correctly, then a solution might be to define two animations, where one has it's final transform pre-multiplied with a negative scaleX
for the negated feather (to ensure that it doesn't produce the undesirable "flip"/twist during the animation):
/*
Define flipped feather animation with positive scale (redundant)
*/
@keyframes regular {
100% {
transform: scaleX(1) rotate(0deg)
}
}
/*
Define flipped feather animation with negated scale. Assuming the
starting transform has scaleX(-1), this animation will stop the
twisting effect from happening
*/
@keyframes flipped {
100% {
transform: scaleX(-1) rotate(0deg)
}
}
With these two animations defined, you can also define corresponding modifier classes to select and apply these randomly to feather elements:
function getRandomInt() {
return Math.random() * 180;
}
function feathersPuff() {
for (let i = 0; i < 10; i++) {
let feather = document.createElement("img");
/* Placeholder image - replace this with your svg */
feather.src = "https://pngriver.com/wp-content/uploads/2017/12/download-free-birds-feather-png-transparent-images-transparent-backgrounds-feather_PNG12958-300x160.png";
document.body.appendChild(feather);
/* Randomly orrientate feather */
if (Math.random() < 0.5) {
/* If regular orrientation, then apply regular modifier class which
will use the "regular" animation (without scaling) */
feather.classList.add("regular");
feather.style.transform =
"rotate(" + getRandomInt(50) + "deg)";
} else {
/* If flipped orrientation, then apply flipped modifier class which
will apply the "flipped" animation (with negated scaling factored in) */
feather.classList.add("flipped");
feather.style.transform =
"scaleX(-1) rotate(" + getRandomInt(50) + "deg)"
}
feather.classList.add("feather");
}
}
feathersPuff();
/* Define flipped feather animation with positive scale (redundant)*/
@keyframes regular {
100% {
transform: scaleX(1) rotate(0deg)
}
}
/* Define flipped feather animation with negated scale */
@keyframes flipped {
100% {
transform: scaleX(-1) rotate(0deg)
}
}
/* Modifier class which animates feathers of the "regular orientation" */
.feather.regular {
animation-name: regular;
}
/* Modifier class which animates feathers of the "flipped orientation" */
.feather.flipped {
animation-name: flipped;
}
.feather {
height: 30px;
display: block;
/* position: absolute; Removed this to prevent feathers overlapping to better
demonstrate the techniques final result */
animation-iteration-count: 1;
animation-direction: linear;
animation-timing-function: ease-in-out;
animation-duration: 2500ms;
animation-fill-mode: forwards;
}
Upvotes: 1