How can I make successive movements with the same div? - javascript

hello I have the following problem, I want to make a series of random movements with the divs and using translate I managed to do only one because when I want to move that element again it returns to its initial position, my question is how can I maintain the position to be able to continue moving it and exchanging positions with other divs?
CSS:
body{
padding: 5rem ;
}
.elem{
width: 100px;
height: 100px;
}
#elem-1{
background-color: aqua;
}
#elem-2{
background-color: red;
}
#elem-3{
background-color: green;
}
#elem-4{
background-color: blue;
}
#elem-5{
background-color: violet;
}
#elem-6{
background-color: yellowgreen;
}
#elem-7{
background-color: gray;
}
#elem-0{
background-color: fuchsia;
}
.contenedor{
width: 400px;
height: 200px;
/* display: grid;
grid-template-columns: repeat(4,1fr); */
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
flex-wrap: wrap;
}
.move-right{
animation-duration: 4s;
animation-name: moving-x-right;
animation-fill-mode: forwards;
}
.move-left{
animation-duration: 4s;
animation-name: moving-x-left;
animation-fill-mode: forwards;
}
.move-down{
animation-duration: 2s;
animation-name: moving-y-down;
animation-fill-mode: forwards;
}
.move-up{
animation-duration: 2s;
animation-name: moving-y-up;
animation-fill-mode: forwards;
}
#keyframes moving-x-right {
from {
}
to {
transform: translateX(100px);
}
}
#keyframes moving-x-left {
from {
}
to {
transform: translateX(-100px);
}
}
#keyframes moving-y-up {
from {
}
to {
transform: translateY(-100px);
}
}
#keyframes moving-y-down {
from {
}
to {
transform: translateY(100px);
}
}
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="contenedor">
<div class="elem" id="elem-0">1</div>
<div class="elem" id="elem-1">2</div>
<div class="elem" id="elem-2">3</div>
<div class="elem" id="elem-3">4</div>
<div class="elem" id="elem-4">5</div>
<div class="elem" id="elem-5">6</div>
<div class="elem" id="elem-6">7</div>
<div class="elem" id="elem-7">8</div>
</div>
<script src="/scripts.js"></script>
</body>
</html>
and JS:
window.onload = moveGridElement
function moveGridElement() {
const elem1 = document.querySelector("#elem-0")
const elem2 = document.querySelector("#elem-1")
const elem3 = document.querySelector("#elem-2")
const elem4 = document.querySelector("#elem-3")
const elem5 = document.querySelector("#elem-4")
const elem6 = document.querySelector("#elem-5")
const elem7 = document.querySelector("#elem-6")
const elem8 = document.querySelector("#elem-7")
elem1.classList.add("move-right")
elem2.classList.add("move-left")
setTimeout(() => {
elem4.classList.add("move-down")
elem8.classList.add("move-up")
}, 1000);
setTimeout(() => {
elem1.classList.add("move-down")
elem6.classList.add("move-up")
}, 3000);
I need that when a div changes places it maintains that position to continue making movements and changing positions with other divs with HTML, CSS and JS only

Related

how can I show or hide buttons slowly with a size animation?

I would like to add an animation to the buttons below.
When displaying the buttons:
the buttons should slowly increase in size until they are fully displayed.
When hiding:
they should slowly get smaller until they are out from the page.
How do i get this this with css?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.btn {
transition: 1s;
/* Continue coding here */
}
</style>
</head>
<body>
<div class="container">
<button class="btn" id="q1" onclick="show()">B1</button>
<button class="btn" id="q2" hidden>B2</button>
<button class="btn" id="q3" hidden>B2</button>
</div>
</body>
</html>
<script>
function show() {
document.getElementById("q1").remove();
document.getElementById("q2").removeAttribute("hidden");
document.getElementById("q3").removeAttribute("hidden");
}
</script>
In order to animate the size, you need to set the beginning and end sizes. I would recommend using a class .hidden instead of the hidden attribute. The class will have a zero size, while the base class .btn has the styles for a non-hidden button. Then you just need to remove the class to trigger the transition.
function show() {
document.getElementById("q1").remove();
document.getElementById("q2").classList.remove("hidden");
document.getElementById("q3").classList.remove("hidden");
}
.btn {
transition: all 1s;
width: 4em;
height: 2.5em;
padding: 0.5em;
/* to hide the text when hidden */
overflow: hidden;
}
.btn.hidden {
width: 0;
height: 0;
padding: 0;
}
<div class="container">
<button class="btn" id="q1" onclick="show()">B1</button>
<button class="btn hidden" id="q2">B2</button>
<button class="btn hidden" id="q3">B3</button>
</div>
Use a keyframe animation that is set in a function that is added or removed when the button is clicked.
example: https://jsfiddle.net/93ah2ej5/1/
(clicking one of the B2 buttons hides them and shows the B1 button)
q1 = document.getElementById("q1")
q2 = document.getElementById("q2")
q3 = document.getElementById("q3")
function show() {
q1.classList.add('hide');
setTimeout(function() {
document.getElementById("q1").hidden = true;
document.getElementById("q2").removeAttribute("hidden");
document.getElementById("q3").removeAttribute("hidden");
q2.classList.remove('hide')
q3.classList.remove('hide')
q2.classList.add('show')
q3.classList.add('show')
}, 3000)
}
function hide() {
q2.classList.add('hide')
q3.classList.add('hide')
setTimeout(function() {
q2.hidden = 'true'
q3.hidden = 'true'
q1.hidden = false
q1.classList.add('show')
q1.classList.remove('hide')
}, 3000)
}
#keyframes show {
0% {
opacity: 0;
width: 10px;
height: 10px
}
100% {
opacity: 1;
width: 32px;
height: 21.5px;
}
}
.show {
animation-name: show;
animation-duration: 3s;
}
#keyframes hide {
0% {
opacity: 1;
width: 32px;
height: 21.5px;
}
100% {
opacity: 0;
width: 10px;
height: 10px
}
}
.hide {
animation-name: hide;
animation-duration: 3s;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="container">
<button class="btn" id="q1" onclick="show()">B1</button>
<button class="btn" id="q2" hidden onclick='hide()'>B2</button>
<button class="btn" id="q3" hidden onclick='hide()'>B2</button>
</div>
</body>
</html>
Here is a way.
const button = document.querySelector(`.button`);
const showHide = document.querySelector(`.show-hide-button`);
let isHidden = true;
showHide.addEventListener(`click`, () =>{
if(isHidden === true)
{
setTimeout(()=>{
button.style.width = `50px`;
}, 100);
setTimeout(()=>{
button.style.display = `none`;
}, 1000);
}
else
{
setTimeout(()=>{
button.style.display = `block`;
}, 100);
setTimeout(()=>{
button.style.width = `150px`;
}, 150);
}
isHidden = !isHidden;
});
.button{
margin-top: 10px;
width: 150px;
display: block;
transition: 1s;
};
<div>
<button class="show-hide-button">ShowHide</button>
<button class="button">Button</button>
</div>
i would like to thank #tices , his/her answer has helped me a lot. but when i add design to "btn", the code doesn't work correctly. because the width and height are hard coded.
so how do i get the button to slowly increase or decrease without hard coding the width and height? I am looking forward to an answer.
q1 = document.getElementById("q1")
q2 = document.getElementById("q2")
q3 = document.getElementById("q3")
function show() {
q1.classList.add('hide');
setTimeout(function() {
document.getElementById("q1").hidden = true;
document.getElementById("q2").removeAttribute("hidden");
document.getElementById("q3").removeAttribute("hidden");
q2.classList.remove('hide')
q3.classList.remove('hide')
q2.classList.add('show')
q3.classList.add('show')
}, 3000)
}
function hide() {
q2.classList.add('hide')
q3.classList.add('hide')
setTimeout(function() {
q2.hidden = 'true'
q3.hidden = 'true'
q1.hidden = false
q1.classList.add('show')
q1.classList.remove('hide')
}, 3000)
}
.btn {
border-style: solid;
border-width: 1px;
background-color: inherit;
padding: 10px 18px;
font-size: 1.125rem;
font-weight: 700;
cursor: pointer;
margin-top: 0;
margin-bottom: 0;
}
#keyframes show {
0% {
opacity: 0;
width: 10px;
height: 10px
}
100% {
opacity: 1;
width: 32px;
height: 21.5px;
}
}
.show {
animation-name: show;
animation-duration: 3s;
}
#keyframes hide {
0% {
opacity: 1;
width: 32px;
height: 21.5px;
}
100% {
opacity: 0;
width: 10px;
height: 10px
}
}
.hide {
animation-name: hide;
animation-duration: 3s;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="container">
<button class="btn" id="q1" onclick="show()">B1</button>
<button class="btn" id="q2" hidden onclick='hide()'>B2</button>
<button class="btn" id="q3" hidden onclick='hide()'>B2</button>
</div>
</body>
</html>

Animation return to initial state after animationend

I encountered a problem when animating slide-in and slide-out.
The number "0" has to move and fade to left and the number "7" has to arrive from right when clicking on "Click" and the inverse when clicking back, indefinitely.
I have used 4 classes : "move-in", "move-out", "move-in-rev" and "move-in-rev" containing the animation with "animationend" that removes it to repeat the animation over and over.
Unfortunally, my skills stop here because the removing of the class removes also the property "animation-fill-mode : towards" which leads to the initial state (opacity = 1 on "0" and not on the "7") and I don't see how to handle it.
Could someone help me please ?
page = 0;
num1 = document.getElementById("num2-1");
num2 = document.getElementById("num2-2");
document
.querySelector("a")
.addEventListener("click", function(event) {
//Go from 0 to 7
if (page == 0) {
//0 go to left and fade
num1.classList.add("move-out");
num1.addEventListener('animationend', function() {
num1.classList.remove("move-out");
});
//7 arrives from right
num2.classList.add("move-in");
num2.addEventListener('animationend', function() {
num2.classList.remove("move-in");
});
page = (++page);
}
//Go from 7 to 0
else {
//0 arrives from left
num1.classList.add("move-out-rev");
num1.addEventListener('animationend', function() {
num1.classList.remove("move-out-rev");
});
//0 go to right and fade
num2.classList.add("move-in-rev");
num2.addEventListener('animationend', function() {
num2.classList.remove("move-in-rev");
});
page = (--page);
};
});
#keyframes slide-in {
from {
transform: translateX(0%);
opacity: 0;
}
to {
transform: translateX(-100%);
opacity: 1;
}
}
#keyframes slide-out {
from {
transform: translateX(0%);
opacity: 1;
}
to {
transform: translateX(-100%);
opacity: 0;
}
}
body,html {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
#nums {
display: flex;
flex-direction: row;
}
#num2-1 {
opacity: 1;
}
#num2-2 {
opacity: 0;
}
a {
text-decoration: none;
cursor: pointer;
user-select: none;
}
a:hover {
color: red;
}
.move-in {
animation : slide-in 0.5s;
animation-fill-mode: forwards;
}
.move-in-rev {
animation : slide-in 0.5s reverse;
animation-fill-mode: forwards;
}
.move-out {
animation : slide-out 0.5s;
animation-fill-mode: forwards;
}
.move-out-rev {
animation : slide-out 0.5s reverse;
animation-fill-mode: forwards;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css" />
<title>transition</title>
</head>
<body>
<div id="nums">
<div id="num1">8</div>
<div id="num2-1">0</div>
<div id="num2-2">7</div>
</div>
<div id="button">
<a id="test">
Click
</a>
</div>
<script src="index.js"></script>
</body>
</html>

slowly scrolling bug, div stay on page but shouldn't

I have three div boxes in a row, and on scroll, they should show slowly from the side, but when I scroll up slowly and a little after they show up, the left and right boxes for some reason stay on the page.
My function showBox3 writes in console "false" and classList where is "show" class, but this class shouldn't be there.
Actually, my code works when I scroll normally but when I stop scrolling slightly above the limit, the left and right boxes stay on page.
And one more problem is when "topBox" is a little below the limit, and I scroll up just a little more, but still below the limit, boxes quickly remove from the page and show up again.
const box21 = document.querySelector(".box21");
const box22 = document.querySelector(".box22");
const box23 = document.querySelector(".box23");
var trigger = window.innerHeight * 0.8;
window.addEventListener("scroll", showBox2);
function showBox2() {
var check;
const topBox = box22.getBoundingClientRect().top;
if (trigger > topBox) {
box22.classList.add("show");
check = true;
} else {
box22.classList.remove("show");
check = false;
}
showBox1(check);
showBox3(check);
}
function showBox1(ch) {
if (ch == true) {
setTimeout(() => {
box21.classList.add("show");
}, 400);
} else {
box21.classList.remove("show");
}
}
function showBox3(ch) {
if (ch == true) {
setTimeout(function () {
box23.classList.add("show");
}, 700);
} else {
box23.classList.remove("show");
console.log(box23.classList);
console.log(ch);
}
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.box1 {
height: 110vh;
background-color: aqua;
display: flex;
align-items: center;
justify-content: center;
}
/* I have a bug in box 2 */
.box2 {
height: 60vh;
width: 100%;
background-color: #ddd;
display: flex;
align-items: center;
justify-content: space-around;
}
.box2>div {
height: 70%;
width: 27%;
background-color: black;
}
.box21 {
transform: translateX(-140%) rotate(-45deg);
transition: transform 1.4s ease;
}
.box21.show {
transform: translateX(0%) rotate(0deg);
}
.box22 {
transform: translateX(340%) rotate(+45deg);
transition: transform 0.8s ease;
}
.box22.show {
transform: translateX(0%) rotate(0deg);
}
.box23 {
transform: translateX(340%) rotate(-45deg);
transition: transform 1.8s ease;
}
.box23.show {
transform: translateX(0%) rotate(0deg);
}
/* this part below is not important */
.box3 {
height: 60vh;
width: 100%;
background-color: cornflowerblue;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css.css" />
</head>
<body>
<div class="box1">
<h1>Scroll down</h1>
</div>
<div class="box2">
<div class="box21"></div>
<div class="box22"></div>
<div class="box23"></div>
</div>
<div class="box3"></div>
</body>
<script src="js.js"></script>
</html>

I want to pause/play CSS animation using one button with Javascript. The sun and sky colors should be controlled with the button

HTML CODE:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset = "utf-8">
<title>Keyframe Animations</title>
<link rel="stylesheet" href="SunLabcss.css" type="text/css"/>
<script src="scriptSun.js"></script>
</head>
<body>
<button id = "sunButton" onclick="sunPausePlayToggle()">PLAY/PAUSE</button
sunPausePlayToggle() is a function in JS which will control the animation .
<div id = "sunSky"
this is a div which i am using as a background sky
<div id = "sun"></div
the upper div is a sun which rise from right and dawn in the left
</div>
</body>
</html>
CSS code:
I am using keyframe animations to animate the sun and sky.
#keyframes risesky {
0% {
top: 100%;
left : 100%;
background-color: red;
}
50% {
left:50%;
top: 10%;
background-color: yellow;
}
100% {
background-color: orangered;
top: 100%;
left: 0%;
}
}
#keyframes sky {
0% , 100% {
background-color: #1c1341;
}
10% {
background-color: darkorange;
}
50% {
background-color: skyblue;
}
80% {
background-color: crimson;
}
}
#sunButton{
animation-play-state: running;
}
#sun {
position: relative;
border-radius: 50%;
width: 80px;
height: 80px;
animation: risesky 11s infinite;
}
#sunSky {
height: 500px;
overflow: hidden;
animation: sky 11s infinite both;
}
Javascript code:
here is the problem I am getting, I can only pause the animation in JS ,but can't play.
function sunPausePlayToggle(){
document.getElementById("sunSky").style.animationPlayState = "paused";
document.getElementById("sun").style.animationPlayState = "running";
}
Turn #sunButton = animation-play-state: "paused"; in css
And this is the js
function sunPausePlayToggle(){
let sunsky = document.getElementById("sunSky")
let sun = document.getElementById("sun")
const sky_sty = sunsky.style.animationPlayState === 'running';
const sun_sty = sun.style.animationPlayState === 'running';
sunsky.style.animationPlayState = sky_sty ? 'paused' : 'running';
sun.style.animationPlayState = sun_sty ? 'paused' : 'running';
}

How to get smooth transitions in pure JavaScript and CSS?

I have div elements with a black background-color that get and loose the class animated that has an css definition for an animated colored background. The animation is working smooth. But the change from the black to the animated state and back are not. I tried some transition rules but I can not figure out how to get a smooth change.
Here is my minimal example:
let randomNumber;
let boxes = document.querySelectorAll(".dark");
let randomNumbers = [];
let milliseconds = 2000;
setInterval(function() {
randomNumber = Math.floor(Math.random() * boxes.length);
randomNumbers.push(randomNumber);
boxes[randomNumber].className = boxes[randomNumber].className.replace(/(?:^|\s)dark(?!\S)/g, " animated");
setTimeout(function() {
boxes[randomNumbers[0]].className = boxes[randomNumbers[0]].className.replace(/(?:^|\s)animated(?!\S)/g, " dark");
randomNumbers.shift();
}, boxes.length * milliseconds);
}, milliseconds);
#keyframes animated_background_color {
0% {
background-color: #e66000;
}
25% {
background-color: #ff9500;
}
50% {
background-color: #ffcb00;
}
75% {
background-color: #ff9500;
}
100% {
background-color: #e66000;
}
}
.box {
height: 20px;
margin-bottom: 4px;
width: 20px;
}
.dark {
background-color: black;
}
.animated {
animation-name: animated_background_color;
animation-duration: 3s;
animation-timing-function: linear;
animation-iteration-count: infinite;
background-color: #e66000;
}
<!DOCTYPE html>
<html>
<head>
<title>Animation</title>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
</head>
<body>
<div class="box dark"></div>
<div class="box dark"></div>
<div class="box dark"></div>
<div class="box dark"></div>
<div class="box dark"></div>
</body>
</html>
Your starting and ending colors are not black, that's one reason why you see a shift. replace your 0% and 100% values by background-color: black;.
Once this problem is fixed, you will have a problem with your milliseconds variable because it's not a divider of your animation time (here 5*2000ms, which means the .animated class remove the class at 10s when your animation cycle is 3s)
Bonus: I have no idea why I cleaned and modified your code but I did it. (I'm tired and it was ugly)
const DARK_SELECTOR = ".dark";
const DARK_CLASS = "dark";
const ANIMATED_CLASS = "animated";
const ANIMATION_CYCLE_TIME = 2000;
const TOTAL_ANIMATION_TIME = 3 * ANIMATION_CYCLE_TIME;
const TIME_BETWEEN_ANIMATIONS = 1.5 * ANIMATION_CYCLE_TIME;
function animateRandomBox(animationTime) {
const darkBoxes = document.querySelectorAll(DARK_SELECTOR);
const numberOfDarkBoxes = darkBoxes.length;
if (numberOfDarkBoxes === 0) {
return;
}
const randomBoxNumber = Math.floor(Math.random() * numberOfDarkBoxes);
const randomBoxClass = darkBoxes[randomBoxNumber].classList;
randomBoxClass.remove('dark');
randomBoxClass.add('animated');
setTimeout(() => {
randomBoxClass.add('dark');
randomBoxClass.remove('animated');
}, animationTime);
}
setInterval(() => animateRandomBox(TOTAL_ANIMATION_TIME), TIME_BETWEEN_ANIMATIONS);
#keyframes animated_background_color {
0% {
background-color: #000;
}
25% {
background-color: #ff9500;
}
50% {
background-color: #ffcb00;
}
75% {
background-color: #ff9500;
}
100% {
background-color: #000;
}
}
body {
display: grid;
grid-auto-rows: min-content;
row-gap: 0.25rem;
}
.box {
height: 1rem;
width: 1rem;
border-radius: 0.5rem;
}
.dark {
background-color: black;
}
.animated {
animation-name: animated_background_color;
animation-duration: 2s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
<!DOCTYPE html>
<html>
<head>
<title>Animation</title>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
</head>
<body>
<div class="box dark"></div>
<div class="box dark"></div>
<div class="box dark"></div>
<div class="box dark"></div>
<div class="box dark"></div>
</body>
</html>
According to the comment of devdgehog, I decided to add more keyframes. Now I switch from the dark state to the animated state and back again with the first and last keyframe setting the dark background and the other keyframes switching from orange to bright orange to yellow to bright orange to orange three times in a row.
const DARK_SELECTOR = ".dark";
const DARK_CLASS = "dark";
const ANIMATED_CLASS = "animated";
const ANIMATION_CYCLE_TIME = 6000;
function animateRandomBox(animationTime) {
const darkBoxes = document.querySelectorAll(DARK_SELECTOR);
const numberOfDarkBoxes = darkBoxes.length;
if (numberOfDarkBoxes === 0) {
return;
}
const randomBoxNumber = Math.floor(Math.random() * numberOfDarkBoxes);
const randomBoxClass = darkBoxes[randomBoxNumber].classList;
randomBoxClass.remove('dark');
randomBoxClass.add('animated');
setTimeout(() => {
randomBoxClass.add('dark');
randomBoxClass.remove('animated');
}, animationTime);
}
setInterval(() => animateRandomBox(ANIMATION_CYCLE_TIME), ANIMATION_CYCLE_TIME);
#keyframes animated_background_color {
0% {
background-color: #000;
}
12% {
background-color: #ff9500;
}
25% {
background-color: #ffcb00;
}
37% {
background-color: #ff9500;
}
50% {
background-color: #ffcb00;
}
62% {
background-color: #ff9500;
}
75% {
background-color: #ffcb00;
}
87% {
background-color: #ff9500;
}
100% {
background-color: #000;
}
}
body {
display: grid;
grid-auto-rows: min-content;
row-gap: 0.25rem;
}
.box {
height: 1rem;
width: 1rem;
border-radius: 0.5rem;
}
.dark {
background-color: black;
}
.animated {
animation-name: animated_background_color;
animation-duration: 6s;
animation-timing-function: linear;
}
<!DOCTYPE html>
<html>
<head>
<title>Animation</title>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
</head>
<body>
<div class="box dark"></div>
<div class="box dark"></div>
<div class="box dark"></div>
<div class="box dark"></div>
<div class="box dark"></div>
</body>
</html>

Categories

Resources