Prevent image from flipping during CSS animation - javascript

I'm working on a rock paper scissors game. When I click a button I have it where two images do a "shake" animation to simulate the hand motions done during a real game. This is all fine, however the image on the right flips horizontally during the animation but flips back at the end. I initially have it flipped so both hands face each other.
I'm wondering if it's possible to prevent that second image from flipping during the animation.
Images before the animation
Images during the animation
HTML
<div class="img-container">
<div class="player-container">
<p class="player-1-text">Player Options: </p>
<div class="player-img-container">
<button onclick="animation()"><img src="img/rock.jpg" alt="Rock Sign" width="100" height="100" class="img-space" id="player-img-main"></button>
<button><img src="img/paper.jpg" alt="Rock Sign" width="100" height="100" class="img-space"></button>
<button><img src="img/scissors.jpg" alt="Rock Sign" width="100" height="100" class="img-space"></button>
</div>
</div>
<div class="computer-container">
<div class="computer-img-container">
<img src="img/rock.jpg" alt="Rock Sign" width="100" height="100" class="img-space" id="computer-img-main">
<img src="img/paper.jpg" alt="Rock Sign" width="100" height="100" class="img-space" id="computer-img">
<img src="img/scissors.jpg" alt="Rock Sign" width="100" height="100" class="img-space" id="computer-img">
</div>
<p class="computer-text"> :Computer Options</p>
</div>
</div>
Javascript
function animation() {
const element = document.getElementById('player-img-main');
const element2 = document.getElementById('computer-img-main');
element.classList.remove('shake'); // reset animation
element2.classList.remove('shake'); // reset animation
void element.offsetWidth; // trigger reflow
void element2.offsetWidth; // trigger reflow
element.classList.add('shake'); // start animation
element2.classList.add('shake'); // start animation
}
CSS
#computer-img-main {
transform: scaleX(-1); /* Flip image horizontally */
}
.shake {
animation-name: shake;
animation-iteration-count: 1;
animation-duration: 2s;
animation-fill-mode: both;
}
#keyframes shake {
3%, 21%, 39%, 57%, 74%, 92% { transform: translateY(5px) }
6%, 24%, 42%, 60%, 77%, 95% { transform: translateY(3px) }
9%, 27%, 45%, 63%, 80%, 98% { transform: translateY(-5px) }
}

You can keep the HTML structure as it is, and share the keyframes, but you need to remember what the scaling is (the flipping of the hand image) and make sure that is in any transform that is done.
You could use a CSS variable for this. e.g. here we set --s to 1 for the player side and to -1 for the computer side. And then in the transforms in the keyframes we add in scaleX(var(--s)).
#player-img-main {
--s: 1;
}
#computer-img-main {
transform: scaleX(-1);
--s: -1;
/* Flip image horizontally */
}
.shake {
animation-name: shake;
animation-iteration-count: 1;
animation-duration: 2s;
animation-fill-mode: both;
}
#keyframes shake {
3%,
21%,
39%,
57%,
74%,
92% {
transform: scaleX(var(--s)) translateY(5px)
}
6%,
24%,
42%,
60%,
77%,
95% {
transform: scaleX(var(--s)) translateY(3px)
}
9%,
27%,
45%,
63%,
80%,
98% {
transform: scaleX(var(--s)) translateY(-5px)
}
}

Related

How to animate 2 images when showing one hide other one in css animation?

image link which ı want to create
web page link which i look for
I want to create an animation area in my web page . I have a reference web page above and i want to make same animation area . when one images slide down other one is hidden and wait its turn . i used css keyframes for this but i could not get exactly what i want .
<div class="col-log">
<img src="/img/tuvnord.png" class="resms1" alt="dd">
<img src="/img/ce.png" class="resms2" alt="">
</div>
i have col-log divs like this which fills my card area like showed above image link.
.gelisme2 .resms1 {
position: absolute;
animation-name: pic1;
animation-iteration-count: infinite;
animation-duration: 3s;
}
.gelisme2 .resms2 {
position: absolute;
animation-name: pic2;
animation-iteration-count: infinite;
animation-duration: 3s;
}
#keyframes pic1 {
0% {
opacity: 0;
transform: matrix(1, 0, 0, 1, 0, -50);
}
100% {
opacity: 0;
transform: matrix(1, 0, 0, 1, 0, 50);
}
}
#keyframes pic2 {
0% {
opacity: 0;
transform: matrix(1, 0, 0, 1, 0, 50)
}
100% {
opacity: 1;
transform: matrix(1, 0, 0, 1, 0, 0)
}
}
You are correct that you can do the whole thing with css / keyframes. I've got the basics roughed out for you, but you'll need to tweak the timings. Everything you need to do that is on this page:
https://www.w3schools.com/css/css3_animations.asp
In the below snippet, the outer container (.flex-row) is set to display:flex to show the immediate child containers (.flex-cell) side by side. The flex-cell containers are then set to display:block so that their contents are not side-by-side. Within each flex-cell, the logo divs are in pairs, stacked one above the other (which makes it easier to do the slideUp / slideDown animations).
The snippet uses one #keyframes definition for all "top" logo divs, and one #keyframes definition for all bottom logo divs. You might find it easier to give each logo div (dimg) its own keyframe definition. Whatever is easiest. Get it working first, then streamline it second - it's too easy to get confuzzled when trying to do both at the same time. Start out with just one logo pair, get that couple working the way you want, then add another flex-cell.
Again, the timing isn't quite right with the below example but I'm sure you can manage to tweak it to perfection. (Note that the first one (timing) is different from the other two. I started playing with the timing, to make the top/bottom changes overlap a bit, but decided that you'll be fine from this point forward. That's why the first pair looks quite different.)
.flex-row{display:flex;}
.flex-cell{display:block;padding:5px 20px;max-height:45px;border:1px solid #ddd;}
img{width:70px;height:40px;}
.twoA, .twoB, .twoC{opacity: 0;}
.oneA, .oneB, .oneC{opacity: 1;}
.oneA{
transition: transform .3s;
animation: doOne 6s linear 0s infinite forwards;
}
.oneB{
transition: transform .3s;
animation: doOne 6s linear .5s infinite forwards;
}
.oneC{
transition: transform .3s;
animation: doOne 6s linear 1s infinite forwards;
}
.twoA{
transition: transform .3s;
animation: doTwo 6s linear 2s infinite forwards;
}
.twoB{
transition: transform .3s;
animation: doTwo 6s linear 3.5s infinite forwards;
}
.twoC{
transition: transform .3s;
animation: doTwo 6s linear 4s infinite forwards;
}
#keyframes doOne {
0% {opacity:0; transform: translate(0, -15px);}
15%{opacity:0;transform: translate(0, -15px);}
18%{opacity:1;transform: translate(0, 0px);}
40%{opacity:1;transform: translate(0, 0px);}
45%{opacity:1;transform: translate(0, 0px);}
50%{opacity:0;transform: translate(0, 25px);}
100%{opacity:0;transform: translate(0, 25px);}
}
#keyframes doTwo {
0% {opacity:0; transform: translate(0, 0px);}
15%{opacity:0;transform: translate(0, 0px);}
18%{opacity:1;transform: translate(0, -40px);}
40%{opacity:1;transform: translate(0, -40px);}
45%{opacity:1;transform: translate(0, -40px);}
50%{opacity:0;transform: translate(0, 0px);}
100%{opacity:0;transform: translate(0, 0px);}
}
<div class="flex-row">
<div class="flex-cell">
<div class="dimg oneA"><img src="https://business.exetel.com.au/images/partners/Optus.svg" /></div>
<div class="dimg twoA"><img src="https://business.exetel.com.au/images/partners/AAPT.svg" /></div>
</div><!-- .flex-cell -->
<div class="flex-cell">
<div class="dimg oneB"><img src="https://business.exetel.com.au/images/partners/Megaport.svg" /></div>
<div class="dimg twoB"><img src="https://business.exetel.com.au/images/partners/Cisco.svg" /></div>
</div><!-- .flex-cell -->
<div class="flex-cell">
<div class="dimg oneC"><img src="https://business.exetel.com.au/images/partners/Cirrus.svg" /></div>
<div class="dimg twoC"><img src="https://business.exetel.com.au/images/partners/Opticomm.svg" /></div>
</div><!-- .flex-cell -->
</div>
you could add an "animation-delay" to the correct class you want to keep it waiting if the other animation is done

How do i stop webkit animation through js? + fixing image to the right

I'm trying to build a puzzle game website. I'm using webkit animation to rotate (and translate) two images.
My plan is to have rotating gears attached to the left and right edge of my page, offset in a way that only half of each image is shown at a time.
The animation works fine but
(1) i am unable to pause it, and
(2) depending on window size the images are moved out of view (with an automatic scrollbar popping up) or into full view.
The setup is pretty simple:
I have 3 divs: one bar at the top with 100% width and two divs with 50% width below as containers for my images.
I might need to add more below or in between the two divs down the road but for now a solution for this would be good enough^^
For the animation i have a pseudo button on each side which adds a pause class to my images.
HTML
<div id="div-left">
<p>Hey this is the left div</p>
<img src="images/zahnrad.png" alt="zahnrad" id="image1">
<p id="pausebtn1" onclick="pause1()">pause</p>
</div>
<div id="div-right">
<p>hey this is the right div</p>
<img src="images/zahnrad.png" alt="zahnrad" id="image2">
<p id="pausebtn2" onclick="pause2()">pause</p>
</div>
CSS
#image1{
-webkit-animation: rotation-left 30s infinite linear;
}
#image1.paused1::-webkit-progress-value{
-webkit-animaion-play-state:paused;
animaion-play-state:paused;
}
#image2{
align: right;
-webkit-animation: rotation-right 30s infinite linear;
}
#image2.paused2::-webkit-progress-value{
-webkit-animaion-play-state:paused;
animaion-play-state:paused;
}
/* Animations */
#-webkit-keyframes rotation-left{
from {
-webkit-transform: translate(-50%,0px) rotate(0deg);
}
to{
-webkit-transform: translate(-50%,0px) rotate(359deg);
}
}
#-webkit-keyframes rotation-right{
from {
-webkit-transform:translate(+50%,0px) rotate(0deg);
}
to{
-webkit-transform:translate(+50%,0px) rotate(-359deg);
}
}
Javascript
function pause1() {
console.log("pause img 1");
document.getElementById('image1').classList.toggle("paused1");
}
function pause2() {
console.log("pause img 2");
document.getElementById('image2').classList.toggle("paused2");
}
So to sum it all up:
I have two images in the wrong places. They are animated. My two buttons are working but trying to pause the animation by adding a paused class doesn't function.
Any help would be appreciated and i'll see if i can add images later
You shouldn't be targeting ::-webkit-progress-value, that's for <progress> elements. Just toggle the class onto the element:
button.addEventListener('click', function () {
square.classList.toggle('paused');
});
#square {
animation: rotate 1s infinite;
background: lightblue;
border: 1px solid black;
height: 100px;
left: 50px;
position: absolute;
top: 50px;
width: 100px;
}
#square.paused {
animation-play-state: paused;
}
#keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<button id="button">Pause/Resume</button>
<div id="square">Rotate</div>

Apply Opacity to Sibling Paragraphs One at a Time During Scroll Animation

I have a figure that wraps a few paragraphs as siblings; the code for which is down below. Also, feel free to run the snippet and hover over the area.
I also have the following style rules to scroll the paragraphs up upon figure:hover...
figure p {
opacity:0;
}
figure:hover p {
opacity:1;
-webkit-transition: opacity 0.35s;
transition: opacity 0.35s;
margin: 0;
line-height: 50px;
text-align: center;
-webkit-transform:translateY(100%);
transform:translateY(100%);
-webkit-animation: scroll-up 5s linear infinite;
animation: scroll-up 5s linear infinite;
}
#-webkit-keyframes scroll-up {
0% { -webkit-transform: translateY(100%); }
100% { -webkit-transform: translateY(-100%); }
}
#keyframes scroll-up {
0% {
-webkit-transform: translateY(100%);
transform: translateY(100%);
}
50% {
opacity:1;
}
100% {
-webkit-transform: translateY(-100%);
transform: translateY(-100%);
opacity:0;
}
}
<figure class="fig_a">
<img src="my_url"/>
<figcaption>
<h2>Hover Somewhere Around Here</span></h2>
<p>paragraph</p>
<p>paragraph</p>
<p>paragraph</p>
View more
</figcaption>
</figure>
Note that the opacity style results in all the paragraphs becoming 100% transparent at the same time. As the post title suggests, I'm looking for a different style; one that allows for a more nuanced transition. Specifically:
Question: How can I have each paragraph follow its own opacity transition in tandem with its relative position in the scroll transition? In other words, paragraphs that are higher up on the page are more transparent. Likewise, paragraphs who are lower on the page are more opaque.
CSS, JS solutions are all welcome. However I am not working in a jquery environment, so I must use native JS (if JS is needed at all).

CSS how to animate from the recently applied transform?

I am applying a dynamic transform to an element when dragging, for example:
HTML
<div style="transform: `translateX(${distance}px) translateY(-${distance / 10}px) rotate(-2deg) scale(0.9)`">
Drag Me
</div>
However when a certain distance has been reached I complete the animation by adding a custom class, say completeAnimation and the rules go like this:
#keyframes animation {
0% {
}
50% {
transform: translateX(270px) translateY(-50px) rotate(-15deg) scale(0.8);
}
100% {
transform: translateX(470px) translateY(50px) rotate(-15deg) scale(0.8);
}
}
.completeAnimation {
animation-duration: 1s;
animation-name: swipeRight;
animation-fill-mode: animation;
}
But obviously, when the class completeAnimation is applied to the class attribute it jumps back to its default display and directly complete to 100% in the animation css.
Is there a way to start the animation where the last applied style left off?

How to bounce animation when scroll?

I have this .png that I wanted to make it bounce a little every time it detects a scroll movement but I'm not good in javascript and css. I hope you guys can help me
<div class="arrownav bounce">
<a href="" class="logo">
<img src="{{ asset('assets/img/arrow down.png') }}" height="45">
</a>
</div>
I am now using a css that made the image bounce
this is the code:
.bounce {
-webkit-animation:bounce 1s infinite;
-moz-animation:bounce 1s infinite;
-o-animation:bounce 1s infinite;
animation:bounce 1s infinite;
}
#-webkit-keyframes bounce {
0% { bottom:0px; }
50% { bottom:15px; }
100% {bottom:30;}
}
#-moz-keyframes bounce {
0% { bottom:0px; }
50% { bottom:15px; }
100% {bottom:30;}
}
#-o-keyframes bounce {
0% { bottom:0px; }
50% { bottom:15px; }
100% {bottom:30;}
}
#keyframes bounce {
0% { bottom:0px; }
50% { bottom:15px; }
100% {bottom:30;}
}
The first thing I noticed is the missing unit in all #keyframes, right here:
100% {bottom:30;}
This should be:
100% { bottom:30px; }
You've used the bottom style in you animation, which is perfectly fine, but in order for it to work the element's position needs to be either relative, absolute or fixed (more here).
.bounce {
position: relative;
-webkit-animation: bounce 1s infinite;
-moz-animation: bounce 1s infinite;
-o-animation: bounce 1s infinite;
animation: bounce 1s infinite;
}
Here's a working fiddle.
Bonus
Another way to change the element's position in the animation is the transform style, instead of using bottom. When you use transform, you don't need position: relative;.
#keyframes bounce {
0% {
transform: translateY(0px);
}
50% {
transform: translateY(-15px);
}
100% {
transform: translateY(-30px);
}
}
Fiddle

Categories

Resources