transfrom: translate() vs translate property - html

<!DOCTYPE html>
<html>
<head>
<style>
#container {
position: absolute;
top: calc(50vh - 100px);
left: calc(50vw - 100px);
height: 200px;
width: 200px;
background-color: white;
border-radius: 10px;
}
.ball {
transform-origin: center;
width: 5%;
height: 5%;
margin-top: 0.8%;
border-radius: 100%;
animation: location 1.5s cubic-bezier(0.48, 0, 0.59, 0.99) 0s infinite
alternate,
size 3s linear;
animation-iteration-count: infinite;
--y: 0px;
}
.animateBackward {
animation-direction: alternate-reverse, reverse;
--y: 115%;
}
.line {
width: 10%;
height: 1.3%;
margin-top: -3%;
margin-left: 45%;
animation: lineSpin calc(3s / 4) cubic-bezier(0.48, 0, 0.59, 0.99);
animation-direction: alternate;
animation-iteration-count: infinite;
}
#keyframes location {
0% {
translate: 400% var(--y);
}
100% {
translate: 1500% var(--y);
}
}
#keyframes size {
0% {
}
25% {
transform: scale(1.5);
}
50% {
transform: scale(1);
}
75% {
transform: scale(0.5);
}
100% {
}
}
#keyframes lineSpin {
0% {
transform: scaleX(5.6);
}
100% {
transform: scaleX(0);
}
}
</style>
</head>
<body>
<div id="container"></div>
</body>
<script>
const redJump = 2.5;
const greenJump = 3;
const blueJump = -11;
const container = document.getElementById('container');
[...Array(15)].forEach((_, i) => {
const color = `rgb(${65 + redJump * i}, ${184 + greenJump * i}, ${
212 + blueJump * i
})`;
container.innerHTML += `
<div class="ball" style="animation-delay: -${
250 * i
}ms; background-color: ${color}"></div>
${
i > 0
? `<div class="line" style="animation-delay: -${
250 * i
}ms; background-color: ${color}"></div>`
: ''
}
<div class="ball animateBackward" style="animation-delay: -${
250 * (i + 1)
}ms; background-color: ${color}"></div>`;
});
</script>
</html>
Hey, I'm trying to create DNA animation and I wrote this code (using Chrome 104) and it all works fine. When I tried it in Chrom 90 I found out that the animation of the ball location keyframes is not working. I read that the translate property works only from Chrome 104 so I changed it to transform: translate() which is said in mdn that is exactly the same. But in practice is not.
How can I make my animation works properly in Chrome 90?
Hope you can help me figure out what is the problem and solve it :)
Reading in mdn and find out that the chrome version is the problem

Related

How to change speed of a keyframe without it jumping

I am trying to change the speed of the keyframe by changing animationDuration. but everytime i change the animationDuration, the box that is animated changes positions(jumps). Is there any way to change the speed without of it jumping?
Thank you in advance.
The code is here, im sry for not seperating them to js/css/html files.
var styles;
function togglePlayState(newState) {
document.getElementById("boxx").style.animationPlayState = newState;
}
var sliderSpeed = document.getElementById("MoveSpeed");
sliderSpeed.oninput = function() {
styles = window.getComputedStyle(boxx);
document.getElementById('boxx').style.animationDuration = +sliderSpeed.value.toString() + "s";
console.log(sliderSpeed.value + "s");
console.log(styles);
}
body {
height: 100%;
top: 0px;
left: 0px;
margin-top: 0%;
margin-left: 0%;
}
.parent {
background-color: rgb(0, 0, 0);
position: absolute;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
margin: 0%;
}
.boxx {
background-color: red;
position: relative;
height: 50px;
width: 50px;
animation: left-to-right 3s forwards infinite alternate linear;
}
.start-animation {
animation: left-to-right 3s forwards infinite alternate linear;
}
.paused {
animation-play-state: paused;
}
#keyframes botleft-to-topright {
/*Koumpi katw aristera Panw deksia*/
0% {
left: 0;
top: calc(100% - 50px);
}
100% {
left: calc(100% - 50px);
top: 0;
}
}
#keyframes left-to-right {
0% {
left: 0;
top: 0;
}
100% {
left: calc(100% - 50px)
}
}
<div class="parent">
<div class="boxx" id="boxx"></div>
<button onclick="togglePlayState('Paused');">Pause Animation</button>
<!-- Play Pause Buttons -->
<button onclick="togglePlayState('Running');">Continue Animation</button>
<!-- Play Pause Buttons -->
<div class="slidecontainer">
<input type="range" min="1" max="15" value="1" class="slider" id="MoveSpeed">
</div>
</div>
It is not possible to do that mid animation with pure css animations. In order to do that you would need to use a js animation library like GSAP. See this answer for an example.

CSS: Carousel returning to start after second image

Problem
I've developed a carousel which scrolls through 3 images. When it comes to move from the 2nd to 3rd it appears to quickly snap to the initial image before returning to the 3rd image. Can someone help me point out the mistake I have made?
.carousel-container {
width: 100%;
overflow: hidden;
margin: 0 auto;
}
.carousel {
display: flex;
width: 300%;
animation: sliding 12s infinite;
}
.carousel div {
width: 300%;
height: 100px;
background-size: cover;
background-position: center;
}
.carousel:hover {
animation-play-state: paused;
}
#keyframes sliding {
30% {
transform: translateX(0);
}
35% {
--widthA: 100%;
--widthB: calc(var(--widthA) / 3);
--widthC: calc(var(--widthB) * -1);
transform: translateX(var(--widthC));
}
65% {
--widthA: 100%;
--widthB: calc(var(--widthA) / 3);
--widthC: calc(var(--widthB) * -1);
transform: translateX(var(--widthC));
}
70% {
--widthA: 100%;
--widthB: calc(var(--widthA) / 3);
--widthC: calc(var(--widthB) * 2);
--widthD: calc(var(--widthC) * -1);
transform: translateX(var(--widthD));
}
98% {
--widthA: 100%;
--widthB: calc(var(--widthA) / 3);
--widthC: calc(var(--widthB) * 2);
--widthD: calc(var(--widthC) * -1);
transform: translateX(var(--widthD));
}
100% {
transform: translateX(0);
}
}
<div class="carousel-container">
<div class="carousel">
<div class="image-one" style="background-image: url(https://via.placeholder.com/100/FF0000/000000?Text=Image1);"></div>
<div class="image-two" style="background-image: url(https://via.placeholder.com/100/00FF00/000000?Text=Image2);"></div>
<div class="image-three" style="background-image: url(https://via.placeholder.com/100/0000FF/000000?Text=Image3);"></div>
</div>
</div>

CSS Zoom into specific image point

I have an image which I need to zoom a specific point depending on which input is focused
Here's a fiddle so far
I used the attributes transform and transform-origin. It's working fine on Firefox (notice how it's moving toward the point while zooming at same time).
However on Chrome, the scale/zoom is done first, then it teleports the point. It's actually very confusing
Any idea how to make this work on Chrome ?
I experimented with putting both the transform and the transform-origin into a CSS animation and it seemed to manage to do them both at once, so avoiding the 2 step problem you saw on Chrome (tested on Edge):
#keyframes focusin {
0% {
transform: scale(1);
transform-origin: 0% 0%;
}
100% {
transform: scale(3);
transform-origin: 25% 75%;
}
}
Here's a snippet. I've put the animation time to 10s so you can see the 'journey' the paper takes when focus is on input1. It seems to be smooth, so a bit of an improvement, but it isn't 'direct' on Edge/Chrome which I guess (and it is only a guess) is to do with how the browser animates (or doesn't) transform-origin.
$("#input1").focus(function(e) {
/* $("#image").css({
"transform": "scale(3)",
"transform-origin": "25% 75%"
});*/
document.getElementById('image').style.animationName = 'focusin';
});
$("#input2").focus(function(e) {
$("#image").css({
"transform": "scale(3)",
"transform-origin": "75% 25%"
});
});
$("#input1, #input2").focusout(function(e) {
$("#image").css({
"transform": "scale(1)"
});
});
#wrapper {
width: 400px;
height: 267px;
border: 1px solid black;
overflow: hidden;
position: relative;
}
#image {
background-image: url('http://i.imgur.com/n9q7jhm.jpg');
background-size: 400px 267px;
background-position: center;
/* transition: all 1s ease; */
width: 100%;
height: 100%;
/* transform: scale(1); */
position: relative;
left: 0;
top: 0;
animation-duration: 10s;
animation-iteration-count: 1;
animation-name: none;
animation-fill-mode: forwards;
}
#keyframes focusin {
0% {
transform-origin: 0% 0%;
transform: scale(1);
}
100% {
transform-origin: 25% 75%;
transform: scale(3);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="input1">
<input type="text" id="input2">
<div id='wrapper'>
<div id='image'></div>
</div>

keyframes animation doesn't work for some reason

I have some text in html that I want to animate
<div class="sofa-text inner-text">
<h1>Sofa, we have cool sofas</h1>
</div>
<div class="light-text inner-text">
<h1>our stand light is out-standing</h1>
</div>
and here's CSS
.inner-text {
display: none;
width: 100px;
height: 100px;
background-color: black;
position: absolute;
transition: 1s;
transform: translateY(200%);
animation-name: slide-up;
animation-duration: 2s;
animation-delay: .5s;
}
#keyframes slide-up{
0% {
transform: translateY(200%);
}
100% {
transform: translateY(0);
}
}
and I wanted to display this animation, after the button was clicked
let $sofaText = document.querySelector('.sofa')
let $lightText = document.querySelector('.light')
let showSofa = () => {
$sofaText.style.display = 'flex'
}
let showStand = () => {
$lightText.style.display = 'flex'
}
$sofaBtn.addEventListener('click', showSofa)
$standBtn.addEventListener('click', showStand)
However this doesn't work. I tested step by step and problem was in #keyframes. I even added -webkit but it still didn't work. I have no idea what's wrong with this
It's working you just can't see it because display:none;
function tran(){
let t = document.querySelector('.sofa-text');
t.classList.add("anim");
t.style.display = "flex";
}
.inner-text {
display:none;
width: 100px;
height: 100px;
background-color: black;
position: absolute;
transition: 1s;
transform: translateY(200%);
}
.anim{
animation-name: slide-up;
animation-duration: 2s;
animation-delay: .5s;
}
#keyframes slide-up{
0% {
transform: translateY(200%);
}
100% {
transform: translateY(0);
}
}
<button onclick="tran()">click</button>
<div class="sofa-text inner-text">
<h1>Sofa, we have cool sofas</h1>
</div>
<div class="light-text inner-text">
<h1>our stand light is out-standing</h1>
</div>

How to take a break during a CSS animation to pause at the center point of the transition?

I made a sort of header with an animated information banner (on 3 lines)
starting at each end. (ex: for the 1st and 3rd line, from left to right and for the 2nd line from right to left). What I would like is to take a break of a few seconds when the 3 bands are
all aligned (in the center) then continue the animation.
I would prefer a solution without using javascript but unfortunately I think it seems impossible?
Problem: The 1st and 3rd banner always start to appear before the 2nd and therefore when they are aligned, they are never in the center.
<!DOCTYPE html>
<HTML>
<head>
<title> VIDEO LIBRARY </title>
<meta charset="utf-8"/>
<style type="text/css">
.bandeau
{
height: 120px;
width: 100%;
padding-top: 5px;
border-radius: 25px;
background: rgb(26,133,230);
}
#keyframes defilement {
from {
left: 0;
}
to {
left: 1000px;
}
}
.defil {
margin: 10px;
position: relative;
height: 20px;
background-color: black;
border: 1px solid black;
overflow: hidden;
text-align: center;
}
.defil div {
position: absolute;
top: 0;
left: 0;
width: 250px;
height: 20px;
background-color: blue;
opacity: 1;
}
.ex1 div {
animation: defilement 20s linear infinite;
}
.ex2 div {
top:0;
right:0;
background-color: white;
animation: defilement 20s linear infinite reverse;
}
.ex3 div {
background-color: red;
animation: defilement 20s linear infinite ;
}
</style>
</head>
<body>
<div class="bandeau" >
<div class="defil ex1">
<div>MANAGEMENT</div>
</div>
<div class="defil ex2">
<div>OF MY</div>
</div>
<div class="defil ex3">
<div>VIDEO LIBRARY</div>
</div>
</div>
</body>
</HTML>
Instead of using from and to in your keyframes, you can set steps using percentages.
In the code below, from 0% to 45% of animation, the animation moves from 0 to 500px. Then from 45 - 55% it stays at 500px (i.e. pauses). Then from 55 - 100% it moves from 500 - 1000px:
#keyframes defilement {
0% {left: 0;}
45% {left: 500px;}
55% {left: 500px;}
100% {left: 1000px;}
}
Responsive solution: blocks will stop in the centre an any size screen.
If you do not have fixed width and would like a more responsive way to calculate the midpoint, you can use percentages: Start at 0%, end at 100%, then 50% for the centre.
However if you position the left of the block at the very centre, it will be a bit too far right. The correct position for the left of the block is actually 50% - 125px (half of the width of the div). And we can actually use using the CSS calc function to do this!
Also to make all blocks appear at the same time, we need to change the starting point for -250px so the 3 blocks all start off the screen and then slide in together.
#keyframes defilement {
0% { left: -250px;}
45% { left: calc(50% - 125px); }
55% { left: calc(50% - 125px); }
100% { left: 100%;}
}
Working example:
.bandeau {
height: 120px;
width: 100%;
padding-top: 5px;
border-radius: 25px;
background: rgb(26, 133, 230);
}
#keyframes defilement {
0% { left: -250px; }
45% { left: calc(50% - 125px); }
55% { left: calc(50% - 125px); }
100% { left: 100%; }
}
.defil {
margin: 10px;
position: relative;
height: 20px;
background-color: black;
border: 1px solid black;
overflow: hidden;
text-align: center;
}
.defil div {
position: absolute;
top: 0;
width: 250px;
height: 20px;
background-color: blue;
opacity: 1;
}
.ex1 div {
animation: defilement 20s linear infinite;
}
.ex2 div {
top: 0;
right: 0;
background-color: white;
animation: defilement 20s linear infinite reverse;
}
.ex3 div {
background-color: red;
animation: defilement 20s linear infinite;
}
<div class="bandeau">
<div class="defil ex1">
<div>MANAGEMENT</div>
</div>
<div class="defil ex2">
<div>OF MY</div>
</div>
<div class="defil ex3">
<div>VIDEO LIBRARY</div>
</div>
</div>
For more information on keyframes, take a look at Mozilla MDN Docs for CSS3 Keyframes