How do I roll a image like this in js/css - javascript

I wanna zoom in & roll(left to right one by one) an image like this:
(The image is to large to upload)
https://i.imgur.com/sQG1chQ.png
It is for a coinflip system & I want it to go vertically instead of horizontal:)
& you will need to zoom in to see the coins.

Pure CSS:
You could do this with keyframes rule using CSS. Animations will take multiple parameters by dividing them with a comma, so you could make an animation for the flip and another for the move.
For the flip a transform: rotateX will do the trick, for the move a position of relative with a top position starting before top pages fold something like negative height of the image -2rem in my case, and moving to a calculated vh view-height off the bottom fold calc(100vw + 2rem).
EDIT:
I have added a new image and adjusted the position of both images to absolute, adjusting their left positions to be the same and then did some tweaking to the #keyframes tween for both image elements. Basically we toggle opacity # 90 degree flip points of each image within the tween, also adjust the rotation to show both images right side up on their respective flips. This is done by starting out on the second image tween 0% to rotate(180deg), then we increment through each 25% by 90deg.
#cont {
height: calc(100vh - 1rem);
overflow-y: hidden;
display: flex;
justify-content: center;
position: relative;
}
#img {
border: 1px black solid;
border-radius: 50%;
height: 2rem;
width: 2rem;
transition: all 1s linear;
perspective: 1000;
transform-style: preserve-3d;
animation: front 1200ms linear infinite,
move 5000ms linear infinite;
position: absolute; /* changed from relative to absolute */
left: calc(50vw - 1rem); /* center 50vw minus half the width of image */
}
/* Added a second image and adjusted rotate degrees in animation
keyframes tween to be exactly 180 degrees offset from 0
so second image looks like it is face up on turn,
Also added a opacity toggle when between the two images at 90deg and 277deg
when they are horizontally aligned on the z axis with top and bottom */
#img2 {
border-radius: 50%;
border: 1px black solid;
height: 2rem;
width: 2rem;
transition: all 1s linear;
perspective: 1000;
transform-style: preserve-3d;
animation: back 1200ms linear infinite,
move 5000ms linear infinite;
position: absolute; /* changed from relative to absolute */
left: calc(50vw - 1rem); /* center 50vw minus half the width of image */
}
#keyframes front {
0% {
transform: rotateX(0deg);
opacity: 1; /* added opacity starting at 1 0% on first image */
}
24% {
opacity: 1;
}
/* switch opacity to 0 here as neither image will be seen as it is 90deg */
25% {
transform: rotateX(90deg);
opacity: 0; /* opacity 0 here */
}
50% {
transform: rotateX(180deg); /* continue rotation */
}
74% {
opacity: 0; /* opacity 0 here */
}
/* switch opacity back on here */
75% {
transform: rotateX(270deg);
opacity: 1;
}
100% {
transform: rotateX(360deg);
opacity: 1;
}
}
#keyframes back {
0% {
/* start # 180deg so image is show face up on flip at this
point it will be upside down on the x axis */
transform: rotateX(180deg);
opacity: 0; /* start with opacity 0 */
}
24% {
opacity: 0;
}
/* switch this image to opacity 1 and continue rotation */
25% {
transform: rotateX(277deg);
opacity: 1;
}
50% {
transform: rotateX(360deg);
}
74% {
opacity: 1;
}
/* turn this images opacity to 0 here */
/* keep flipping image on same rotation, do not go back to 0
just increment by 90deg with each tween as 360 % 4 = 9 and 100 divided by four = 25
so every 25% of tween we hit a 90deg rotation*/
75% {
transform: rotateX(450deg);
opacity: 0;
}
100% {
transform: rotateX(540deg);
opacity: 0;
}
}
#keyframes move {
from {
top: -2rem;
}
to {
top: calc(100vh + 2rem);
}
}
<div id="cont">
<img id="img" src="https://cdn.pixabay.com/photo/2018/02/02/13/51/bitcoin-3125488_640.png">
<img id="img2" src="https://cdn.pixabay.com/photo/2017/07/27/21/37/bitcoin-2546854_960_720.png">
</div>

You can try rotating the image and animating the margin-left:
setTimeout(function() {
document.querySelector('img').style.marginLeft = "-10000px";
}, 1000);
.container {
overflow: hidden;
width: 50px;
transform: rotate(90deg);
}
img {
margin-left: 0px;
transition: 60s linear;
}
<div class="container">
<img src="https://i.imgur.com/sQG1chQ.png" height="50">
</div>

Related

Increasing animation speed (CSS) of transform animation

I'm trying to find a way to speed up the transform (flip about the y axis) in 0.05 seconds. Basically, the image flips in 0.05 seconds. The flip animation however does not change despite what I did in CSS. Please help
CSS
<style>
.a {
width: 50px;
height: 50px;
position: relative;
animation-name: box;
animation-duration: 10s;
transition: transform 0.05s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
#keyframes box {
0% { left: var(--rando0); top: var(--rando1); transform: rotateY(180deg);}
25% { transform: rotateY(180deg) left: var(--rando2); top: var(--rando3);}
50% { left: var(--rando4); top: var(--rando5); transform: rotateY(180deg);}
75% { transform: rotateY(180deg) left: var(--rando6); top: var(--rando7);}
100% { left: var(--rando8); top: var(--rando9); transform: rotateY(180deg);}
}
HTML
<img src="image.gif" alt="prgm" class='a left' class='character'>
JS
<script>
const root = document.querySelector(":root"); // we first get the root element
for(let i = 0; i < 10; i++) {
root.style.setProperty(`--rando${i}`, `${Math.floor(Math.random() * 200) + 1}px`);
}
</script>
Thanks
You can have two animations running at the same time. This snippet keeps the left/top animation at 10s and introduces a rotate animation at 0.5s. (At 0.05s the rotation gives very flashing result which didn't seem to be likely what you wanted).
const root = document.querySelector(":root"); // we first get the root element
for (let i = 0; i < 10; i++) {
root.style.setProperty(`--rando${i}`, `${Math.floor(Math.random() * 200) + 1}px`);
}
.a {
width: 50px;
height: 50px;
position: relative;
animation-name: box, rotate;
animation-duration: 10s, 0.5s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
#keyframes rotate {
0%,
49.99%,
100% {
transform: rotateY(0);
}
50%,
99.99% {
transform: rotateY(180deg);
}
}
#keyframes box {
0% {
left: var(--rando0);
top: var(--rando1);
}
25% {
left: var(--rando2);
top: var(--rando3);
}
50% {
left: var(--rando4);
top: var(--rando5);
}
75% {
left: var(--rando6);
top: var(--rando7);
}
100% {
left: var(--rando8);
top: var(--rando9);
}
}
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRzhbV48pXypX9otxEVYrZ1etEOZqym7693twATGzSGqg&s" alt="prgm" class='a left' class='character'>
UPDATE: the requirement was clarified - the image is to flip instantaneously but every half second goes back to its initial orientation.
The keyframes named rotate have been changed so that it stays at 0degrees rotation for half the animation time, flips 180degrees and stays at that for the second half.

Image won't stay visible for hover effect

Hello and thank you in advance for reading my question.
GOAL: Set image so that once it's scrolled into view it transitions smoothly into a set position - but still reacts to :hover. Using #keyframes and a little JavaScript, I set the image to opacity: 0 and it's final opacity to opacity: .85. Then I added a hover effect in CSS to make it's opacity: 1
The issue is once it's finished with it's transition - it disappears - reverting to it's original opacity which is zero. I managed to make it freeze at .85 with animation-fill-mode: forwards, rather than animation-fill-mode: none, but then it won't respond to :hover
And here's a test snippet of the problem in action:
let observer_img = new IntersectionObserver(updates => {
updates.forEach(update => {
if (update.isIntersecting) {
update.target.classList.add('shift_frame_center_img');
} else {
update.target.classList.remove('shift_frame_center_img');
}
});
}, { threshold: 0 });
[...document.querySelectorAll('.features-img-wrapper img')].forEach(element => observer_img.observe(element));
body {
width: 100%;
height: 100vh;
background-color: lightgrey;
}
/* CHILD */
.features-img-wrapper img {
width: 10rem;
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 8rem;
opacity: 0;
transition: all .5s;
}
/* APPEND-CHILD */
.shift_frame_center_img {
animation: center_img 1s 0.5s none;
}
/* CHILD ON HOVER */
.features-img-wrapper img:hover {
opacity: 1;
transform: scale(1.035);
}
/* KEYFRAMES */
#keyframes center_img {
0% {
transform: translateY(20rem);
}
100% {
transform: translateY(0);
opacity: .85;
}
}
<body>
<div class="features-img-wrapper">
<img src="https://synapse.it/wp-content/uploads/2020/12/test.png">
</div>
</body>
If I could get a hand with this that would be wonderful, I'm a bit of a beginner and have already spent a few hours on this, all feedback welcome. Thank you very much.
Solution 1
To understand why the hover effect was not working with the animation-fill-mode: forwards, read this answer.
You can fix that by adding !important property to the hover styles:
.features-img-wrapper img:hover {
opacity: 1 !important;
transform: scale(1.035) !important;
}
The problem, in this case, is that the transition will not work for hover.
Solution 2
You could remove the animation entirely and add the final state styles to the shift_frame_center_img class.
But you would still need to use the !important property because of the CSS Specificity.
let observer_img = new IntersectionObserver(updates => {
updates.forEach(update => {
if (update.isIntersecting) {
update.target.classList.add('shift_frame_center_img');
} else {
update.target.classList.remove('shift_frame_center_img');
}
});
}, { threshold: 0 });
[...document.querySelectorAll('.features-img-wrapper img')].forEach(element => observer_img.observe(element));
body {
width: 100%;
height: 100vh;
background-color: lightgrey;
}
/* CHILD */
.features-img-wrapper img {
width: 10rem;
transform: translateY(20rem);
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 8rem;
opacity: 0;
transition: all .5s;
}
/* APPEND-CHILD */
.shift_frame_center_img {
transform: none !important;
opacity: .85 !important;
}
/* CHILD ON HOVER */
.features-img-wrapper img:hover {
opacity: 1 !important;
transform: scale(1.035) !important;
}
<body>
<div class="features-img-wrapper">
<img src="https://synapse.it/wp-content/uploads/2020/12/test.png">
</div>
</body>
This snippet removes the need for fill-mode forwards by setting the img to have opacity 1 as its initial state so it will revert to that at the end of the animation.
The animation itself is altered to take 1.5s rather than 1s with the first third simply setting the img opacity to 0 so it can't be seen. This gives the delay effect.
let observer_img = new IntersectionObserver(updates => {
updates.forEach(update => {
if (update.isIntersecting) {
update.target.classList.add('shift_frame_center_img');
} else {
update.target.classList.remove('shift_frame_center_img');
}
});
}, { threshold: 0 });
[...document.querySelectorAll('.features-img-wrapper img')].forEach(element => observer_img.observe(element));
body {
width: 100%;
height: 100vh;
background-color: lightgrey;
}
/* CHILD */
.features-img-wrapper img {
width: 10rem;
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 8rem;
opacity: 0;
transition: all .5s;
opacity: 1;
}
/* APPEND-CHILD */
.features-img-wrapper img {
animation: center_img 1.5s 0s none;
}
/* CHILD ON HOVER */
.shift_frame_center_img:hover {
opacity: 1;
transform: translateY(0) scale(1.035);
}
/* KEYFRAMES */
#keyframes center_img {
0% {
transform: translateY(20rem) scale(1);
opacity: 0;
}
33.33% {
transform: translateY(20rem) scale(1);
opacity: 0;
}
100% {
transform: translateY(0) scale(1);
opacity: .85;
}
}
<body>
<div class="features-img-wrapper">
<img src="https://synapse.it/wp-content/uploads/2020/12/test.png">
</div>
</body>
Note: as each transform setting will reset anything that isn't included both tranlateY and scale are included in each setting.
Outside the SO snippet system it was possible to leave the animation settings untouched by chaining another animation to the front which ran for 0.5s and just set the img to opacity: 0. This did not work in the snippet system (it got into a loop of flashing on and off) hence the introduction of one but extended animation.

How to rotate an image with CSS or JavaScript with pause in between every rotation? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I have a picture that I want to rotate from 0 to 90 stop 2s then continue from 90 to 180 then stop 2s to the 360 degrees any ideas thanks.
You can do that with CSS animations:
div {
width: 80px;
height: 80px;
background: linear-gradient(#e66465, #9198e5);;
animation: rotate-stop 10s infinite linear;
transform: rotate();
}
#keyframes rotate-stop{
0%{
transform: rotate(0deg);
}
5%, 25%{
transform: rotate(90deg);
}
30%, 50%{
transform: rotate(180deg);
}
55%, 75%{
transform: rotate(270deg);
}
80%, 100%{
transform: rotate(360deg);
}
}
<div></div>
You could use setTimeout and setInterval appropriately:
const rotate = (image, degrees) => {
image.style.transform = `rotate(${+degrees}deg)`;
}
const img = document.getElementById('js-logo');
const oneLoop = () => {
setTimeout(() => rotate(img, 90), 2000);
setTimeout(() => rotate(img, 180), 4000);
setTimeout(() => rotate(img, 360), 6000);
}
oneLoop();
setInterval(() => oneLoop(), 6000);
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/JavaScript-logo.png/240px-JavaScript-logo.png" alt="JS Logo" width="120" height="120" id="js-logo">
An example for javascript.
window.onload = function() {
var box = document.querySelector('.box');
setInterval(function() {
box.classList.toggle('rotate');
}, 2000);
}
.box {
width: 200px;
height: 200px;
background-color: green;
}
.rotate {
animation: rotate 1s;
}
#keyframes rotate {
from {
transform: rotate(0);
}
to {
transform: rotate(90deg);
}
}
<div class="box"></div>
Here is pure css example using animation keyframes.
If you calculate the time for each rotation animation, and each pause time, you can use css animate keyframe percentages to perform a sequence of desired css.
Here is an example below, see comments in css...
/* any kind of html elem, img, div etc */
DIV {
background: magenta;
color: white;
position: absolute;
top: 50%;
left: 50%;
padding: .5rem .75rem;
transform: translate(-50%);
transform-origin: center;
/* 4 rotations */
/* 4 2sec pauses */
/* 8 keyframes total */
/* 2sec rotation time example */
/* 8*2sec is 16s for complete sequence */
animation: rotate-pause 16s infinite;
}
/* rotate and pause key frames */
#keyframes rotate-pause {
/* 0 seconds */
0% {
transform: translate(-50%) rotate(0deg);
}
/* 2 seconds */
12.5% {
transform: translate(-50%) rotate(90deg);
}
/* 4 seconds */
25% {
transform: translate(-50%) rotate(90deg);
}
/* 6 seconds */
37.5% {
transform: translate(-50%) rotate(180deg);
}
/* 8 seconds */
50% {
transform: translate(-50%) rotate(180deg);
}
/* 10 seconds */
62.5% {
transform: translate(-50%) rotate(270deg);
}
/* 12 seconds */
75% {
transform: translate(-50%) rotate(270deg);
}
/* 14 seconds */
87.5% {
transform: translate(-50%) rotate(360deg);
}
/* 16 seconds */
100% {
transform: translate(-50%) rotate(360deg);
}
/* reloop if animate set to infinite */
}
/* demo reset css */
HTML {
width: 100%;
height: 100%;
min-height: 100%;
}
BODY {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
min-height: 100%;
overflow: hidden;
position: relative;
}
<div>Any kind of html elem: img, div...</div>

How to apply CSS transform if i had a transform on hover?

I have made a group of elements and set a hover for their class
.cards:hover {
transition: 0.2s;
transform: translate( 0px, -50px);
height: 180px;
width: 120px;
background-size: 120px 180px;
}
There are 10 elements in the class and i have a JS file that onclick singles out the element and i want it to spin so i write the JS and i tell it to add a transform after the click like
document.getElementById(idTag).style.transition = "3s ease";
document.getElementById(idTag).style.transform = "rotate(270deg)";
but it doesn't rotate it. Instead it goes directly to 270 degrees in the shortest possible path. If i remove the transform from the hover then it rotates like normal but if i have a transform on hover it doesn't work. Is there a conflict or something with the hover effect ?
In order to transition vertical displacement (translate) and rotation separately you should probably use a different way of moving the element upwards. Using the top property and a relative position. Then you could have the following css code...
.cards {
position: relative;
transition: top 0.2s, transform 3s ease;
height: 180px;
width: 120px;
background-size: 120px 180px;
top: 0px;
transform: rotate(0deg);
}
.cards:hover {
top: -50px;
}
.cards.rotate {
transform: rotate(270deg);
}
And the following code within your click listener to add the rotate class for rotation after the click.
document.getElementById(idTag).classList.add('rotate')
Now the cards should move up on hover, but rotate on click with separate speeds.
function drawCard() {
var Deck = document.getElementsByClassName("cards");
var idTag = this.id;
document.getElementById(idTag).classList.remove("cards");
document.getElementById(idTag).classList.add("draw-card");
for (i = 0; i < Deck.length; i++) {
Deck[i].style.display = "none";
}
document.getElementById(idTag).style.transition = "2s";
document.getElementById(idTag).style.left = "100px";
document.getElementById(idTag).style.animation = "rotate 2s linear forwards";
on click I separate the picked card by changing the class and then cycle through the rest of the class to make the rest of the cards dissapear. After that I add the rotate animation with the key frames in CSS
#keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

Highlight element using jQuery with scaled transparent element

I'm trying to create the following effect for any element using only jQuery/plugins:
In particular it should use a transform for the scale rather than width and height animation and be usable on any DOM element.
Is there a plugin available for jQuery which will achieve this effect? It should be quite simple: duplicate the dom object with clone(), reposition the clone over the original absolutely then animate a scale transform and opacity on the new element. However, I suspect it's not as simple as this.
Any ideas?
You don't need jQuery to accomplish that animation. You can use CSS3 animations and transform properties. Check out the following example I created:
http://jsbin.com/purik/1/
HTML:
<div class="logos">
<div class="logo"></div>
<div class="logo animated"></div>
</div>
CSS:
.logos {
position: relative;
}
.logo {
width: 100px;
height: 70px;
background: #CC0000 url(http://www.w3schools.com/images/w3logo.png) 50% 50% no-repeat;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.logo.animated {
position: absolute;
left: 0;
top: 0;
animation: scale-fadeout 2s infinite;
-webkit-animation: scale-fadeout 2s infinite;
}
#keyframes scale-fadeout {
0% {
transform: scale(1);
opacity: 1;
}
5% {
opacity: 1;
transform: scale(1.05);
}
100% {
opacity: 0;
transform: scale(1.35);
}
}
#-webkit-keyframes scale-fadeout {
0% {
-webkit-transform: scale(1);
opacity: 1;
}
5% {
opacity: 1;
-webkit-transform: scale(1.05);
}
100% {
opacity: 0;
-webkit-transform: scale(1.35);
}
}
This works if the parent element is position: relative, and the element itself is position: absolute.
Clones the element and then animates it to change the size, change the values of left and top, and the set opacity: 0.
Fiddle: http://jsfiddle.net/Ej38P/1/

Categories

Resources