I'm trying to move this square to right 100px after clicking on it with js, I've set the transition to 1s, but it doesn't work
window.onload = function(){
var square = document.querySelector(".square");
square.onclick = function(){
square.style.right = "100px";
};
};
.square {
position: absolute;
background-color: red;
width: 500px;
height: 500px;
transition: 1s;
}
<div class="square">
</div>
CSS won't animate things from auto to px.
Since right is not defined, it's defaulting to auto.
window.onload = function(){
var square = document.querySelector(".square");
square.onclick = function(){
square.style.right = "100px";
};
};
.square {
position: absolute;
background-color: red;
width: 500px;
height: 500px;
right: 0;
transition: 1s;
}
<div class="square">
</div>
However, if you want to animate it without setting right at the beginning, you can also use translate.
window.onload = function(){
var square = document.querySelector(".square");
square.onclick = function(){
square.style.transform = "translateX(100px)";
};
};
.square {
position: absolute;
background-color: red;
width: 500px;
height: 500px;
transition: 1s;
}
<div class="square">
</div>
Related
I am creating a little game that should be like a 2d version of "guitar hero" (if you don't know what "guitar hero" is don't worry, it was just to give context). I have a red square creator function called squareCreator that adds each new square created a CSS class of .newMostLeftNote. Afterward, I want each one of those squares to fall down (like gravity) using the function fallingMostLeftNote. The problem is that the margin-top that function adds to the square generated by the squareCreator adds to every single square at the same time (even before the square is created), so a square could be created when the .newMostLeftNote CSS class has a margin-top of 700 and it appears way at the bottom.
How can I make it so that every square that falls, but starts falling after they appear?
Notice that in this image, every margin-top CSS property for every new generated square is exactly the same.
var mostLeftNoteMarginTop = 0;
function squareCreator(){
var newNote = document.createElement("div");
newNote.className = "newMostLeftNote";
document.body.appendChild(newNote);
}
var generationSpeed = setInterval(squareCreator, 300);
function fallingMostLeftNote() {
mostLeftNoteMarginTop += 2;
$(".newMostLeftNote").css({
'margin-top': mostLeftNoteMarginTop + 'px'
});
}
proc = setInterval(fallingMostLeftNote, 5);
.newMostLeftNote {
height: 100px;
width: 100px;
background-color: red;
margin-left: 400px;
position: absolute;
}
.mostLeftNote {
height: 100px;
width: 100px;
background-color: red;
margin-left: 300px;
position: absolute;
}
.middleNote {
height: 100px;
width: 100px;
background-color: blue;
margin-left: 600px;
position: absolute;
}
.mostRightNote {
height: 100px;
width: 100px;
background-color: green;
margin-left: 900px;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Score: 0</h1>
<div class="middleNote"></div>
<div class="mostLeftNote"></div>
<div class="mostRightNote"></div>
<div class="scoreLineTop"></div>
<div class="scoreLineButtom"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="main.js" charset="utf-8"></script>
</body>
Update
var squareQuantity = [];
function squareCreator(){
var newNote = document.createElement("div");
newNote.className = "newMostLeftNote";
document.body.appendChild(newNote);
squareQuantity.push(this.newNote);
}
var generationSpeed = setInterval(squareCreator, 300);
function fallingMostLeftNote() {
mostLeftNoteMarginTop += 2;
squareQuantity[2].css({
'margin-top': mostLeftNoteMarginTop + 'px'
});
}
Instead of using javascript to update your margin-top, you could use CSS animations. Each new square will animate independently.
Here's an example for your use case:
function addSquare() {
var squaresElement = document.getElementById("squares");
var squareElement = document.createElement("div");
squareElement.className = "square";
squaresElement.append(squareElement);
}
#squares {
display: flex;
}
.square {
height: 100px;
width: 100px;
margin-right: 10px;
background-color: red;
animation-name: fall;
animation-duration: 4s;
animation-timing-function: linear;
}
/* The animation code */
#keyframes fall {
from {margin-top: 0px;}
to {margin-top: 300px;}
}
<button onclick="addSquare()">Add square</button>
<div id="squares"></div>
My approach is giving a css variable while creating divs for transform delay. If you need more complex movements, you can use the same logic for animation instead of transform.
<div class="parent"></div>
.parent {
display: flex;
flex-direction: row;
align-items: flex-start;
}
.lets-try {
flex: 1;
background: #000;
height: 60px;
margin-right: 5px;
margin-left: 5px;
transition: all 0.5s ease-in-out var(--delay);
}
.lets-try.is-falling {
margin-top: 100px;
}
let parent = document.querySelector(".parent");
let numOfSquares = 12;
for (let i = 0; i < numOfSquares ; i++) {
let delay = i * 0.2;
let div = document.createElement('div');
div.setAttribute('class', 'lets-try');
div.setAttribute('style', `--delay:${delay}s`);
parent.appendChild(div);
}
setTimeout(() => {
let items = document.querySelectorAll(".lets-try");
[...items].forEach(item => {
item.classList.add("is-falling")
})
}, 1)
I want to make the 'box' in the code move to the right and then go back to the left. I tried to use 2 setInterval but it didn't works (or maybe i don't know how to use 2 setInterval).
var box = document.getElementById("box");
var pos = 0;
var toRight = setInterval(move, 10);
function move() {
if (pos >= 150) {
clearInterval(toRight);
} else {
pos++;
box.style.left = pos + "px";
}
}
#container {
width: 200px;
height: 200px;
background-color: red;
position: relative;
}
#box {
width: 50px;
height: 50px;
background-color: blue;
position: absolute;
}
<div id="container">
<div id="box"></div>
</div>
<p id="demo"></p>
I tried so many ways and the code still doesn't run, can some one show me the way to make the 'box' move back from the right side. Thank you.
Your code was a good start, and #j08691's comment is the right direction to take it.
Use 1 interval function but keep track of which direction the box is moving and toggle it when desired.
let box = document.getElementById("box");
let pos = 0, right = true;
setInterval(() => {
pos += right * 2 - 1;
if (pos === 0 || pos === 150)
right = !right;
box.style.left = pos + "px";
}, 10);
#container {
width: 200px;
height: 200px;
background-color: red;
position: relative;
}
#box {
width: 50px;
height: 50px;
background-color: blue;
position: absolute;
}
<div id="container">
<div id="box"></div>
</div>
As an alternative you could also use css animations and skip the javascript part entirely:
#keyframes move {
from { left: 0; }
to { left: calc(100% - 50px); }
}
#container {
width: 200px;
height: 200px;
background-color: red;
position: relative;
}
#box {
width: 50px;
height: 50px;
background-color: blue;
position: absolute;
animation: move 2s linear alternate infinite;
}
<div id="container">
<div id="box"></div>
</div>
<p id="demo"></p>
I have these 2 divs and when I click on div 1 I want it to go over the second div, and if I click on Div 1 again I want it to go back to its original position (I want Div 1 to increase its width so it goes over the second Div). Here is my code where I have my 2 divs next to each other. Can anyone point me in the right direction on how to accomplish this? Thanks a lot in advance!
NOTE:
- No jQuery please. I'm trying to accomplish this with javascript and css.
#parent {
display: flex;
}
#narrow {
width: 200px;
background: lightblue;
}
#wide {
flex: 1;
background: lightgreen;
}
<div id="parent">
<div id="wide">Div 1</div>
<div id="narrow">Div 2</div>
</div>
If you're willing to ditch flex, you can use a combination of float , postion:absolute and transition so that the main div "slides over" the other div
document.querySelector("#wide").onclick = toggleWidth;
function toggleWidth() {
this.classList.toggle("active");
}
#parent {
position: relative;
}
#narrow {
width: 200px;
background: lightblue;
float: right;
}
#wide {
position: absolute;
background: lightgreen;
width: calc(100% - 200px);
transition: width 2s;
}
#wide.active {
width: 100%;
opacity: 0.9;
}
<div id="parent">
<div id="wide">Div 1</div>
<div id="narrow">Div 2</div>
</div>
Note: Changing the opacity is purely optional, I've only done it to further illustrate the "slide over" effect.
Try this
#parent {
display: flex;
}
#narrow {
width: 20vw;
position: absolute;
left: calc(80vw - 10px);
background: lightblue;
z-index: 1;
margin: 0;
}
#wide {
width: calc(80vw - 10px);
background: lightgreen;
transition: all 0.3s ease-out;
}
.wider {
width: 100vw!important;
z-index: 2;
}
<div id="parent">
<div id="wide" onclick="myFunction()">Div 1</div>
<div id="narrow">Div 2</div>
</div>
<script>
function myFunction() {
var element = document.getElementById("wide");
element.classList.toggle("wider");
}
</script>
You can try it using JavaScript.
First, you prepare your CSS:
#narrow {
width: 200px;
transition: 0.32s;
overflow: hidden;
}
#wide.fullwidth ~ #narrow {
width: 0;
opacity: 0;
}
Then, the JavaScript, like this:
document.querySelector("#wide").onclick = changeDivWidth;
var wideFull = false;
function changeDivWidth () {
if (!wideFull) {
this.classList.add("fullwidth");
wideFull = true;
return; // if variable wideFull is false, function stops here
}
wideFull = false;
this.classList.remove("fullwidth");
}
Shorter approach using toggle();
document.querySelector("#wide").onclick = changeDivWidth;
function changeDivWidth () {
this.classList.toggle("fullwidth");
}
Are you looking for something like this : JSFiddle ?
JavaScript (Pure) :
function HideDivOne(){
var wide = document.getElementById("wide");
var narrow = document.getElementById("narrow");
if (wide.style.width == "70%"){
wide.style.width = "100%";
narrow.style.width = "0%";
narrow.style.opacity = "0";
}
else{
wide.style.width = "70%";
narrow.style.width = "30%";
narrow.style.opacity = "1";
}
}
CSS
#parent {
display: flex;
}
#narrow {
width: 30%;
background: lightblue;
height: 20px;
transition: 0.2s;
}
#wide {
width: 70%;
flex: 1;
background: lightgreen;
height: 20px;
transition: 0.2s;
}
HTML
<div id="parent">
<div id="wide" onclick="HideDivOne()">Div1</div>
<div id="narrow" onclick="HideDivTwo()">Div2</div>
</div>
You can change the z-index of the divs based on your desired effect. My suggestion is using jQuery. On click on div 1 add a class to the div that modify the zindex, that is, if the class is not already added, if so, remove it.
Here's a function:
function rollImgOnSwipe(direction) {
changeDirection(direction);
rollImage(direction);
}
The first called function (changeDirection(direction);) is supposed to place a div in either the left or right side of the screen, depending on the value of its argument. The second one (rollImage(direction);) is to make the div move from left to right or from right to left, depending on where the first function placed it.
Well, it seems like it first calls rollImage and then changeDirection because it takes rollImgOnSwipe to be called more than once in order for the div to be placed on the other side.
The best way to explain this to you is to show you - run the code snippet and try switching between the divs with the prev and next buttons and see how they behave.
var nextBtn = document.getElementById('next'),
prevBtn = document.getElementById('prev'),
shown = document.getElementsByClassName('shown')[0],
hidden = document.getElementsByClassName('hidden')[0];
function rollImage(direction) {
shown.classList.remove("shown");
shown.classList.add("hidden");
hidden.classList.remove("hidden");
hidden.classList.add("shown");
shown = document.getElementsByClassName('shown')[0];
hidden = document.getElementsByClassName('hidden')[0];
changeDirection(direction);
}
function rollImgOnSwipe(direction) {
changeDirection(direction);
rollImage(direction);
}
function changeDirection(direction) {
hidden.style.left = (105 * direction) + "%";
shown.style.left = 0;
}
nextBtn.addEventListener('click', function () { rollImgOnSwipe(1); });
prevBtn.addEventListener('click', function () { rollImgOnSwipe(-1); });
.img {
position: absolute;
display: block;
width: 80px;
height: 30px;
border-style: solid;
border-color: red;
border-width: 5px;
}
.shown{
left: 0;
transition: left .6s ease, transform .6s ease;
}
.hidden{
left: 105%;
}
.img-wrapper{
position: relative;
width: 80px;
height: 30px;
padding: 30px;
white-space: nowrap;
overflow: hidden;
}
<button id="prev">prev</button>
<div class="img-wrapper">
<div class="img shown"></div>
<div class="img hidden"></div>
</div>
<button id="next">next</button>
To fix this, i make the compiler wait for a bit before calling rollImage by using the setTimeout function in rollImgOnSwipe.
And now the program works as expected:
var nextBtn = document.getElementById('next'),
prevBtn = document.getElementById('prev'),
shown = document.getElementsByClassName('shown')[0],
hidden = document.getElementsByClassName('hidden')[0];
function rollImage(direction) {
shown.classList.remove("shown");
shown.classList.add("hidden");
hidden.classList.remove("hidden");
hidden.classList.add("shown");
shown = document.getElementsByClassName('shown')[0];
hidden = document.getElementsByClassName('hidden')[0];
changeDirection(direction);
}
function rollImgOnSwipe(direction) {
changeDirection(direction);
setTimeout(function() { rollImage(direction); }, 50);
}
function changeDirection(direction) {
hidden.style.left = (105 * direction) + "%";
shown.style.left = 0;
}
nextBtn.addEventListener('click', function(){ rollImgOnSwipe(1); });
prevBtn.addEventListener('click', function(){ rollImgOnSwipe(-1); });
.img {
position: absolute;
display: block;
width: 80px;
height: 30px;
border-style: solid;
border-color: red;
border-width: 5px;
}
.shown{
left: 0;
transition: left .6s ease, transform .6s ease;
}
.hidden{
left: 105%;
}
.img-wrapper{
position: relative;
width: 80px;
height: 30px;
padding: 30px;
white-space: nowrap;
overflow: hidden;
}
<button id="prev">prev</button>
<div class="img-wrapper">
<div class="img shown"></div>
<div class="img hidden"></div>
</div>
<button id="next">next</button>
My question is:
What is the problem and why is it fixed by making the compiler wait?
My sidebar.css :
body
{
margin: 0;
padding: 0;
}
#header
{
background-color: #577481;
float: left;
height: 50px;
width: 100%;
}
#sidebar
{
background-color: #4ea9d1;
float: left;
height: 100%;
left: -200px;
position: absolute;
top: 50px;
width: 200px;
}
#wrapper
{
float: left;
height: 100%;
width: 100%;
}
#content
{
background-color: #d6b141;
float: left;
height: 500px;
width: 100%;
}
#sideBarButton
{
background-image: url('SideBarButton.png');
background-position: center;
background-repeat: no-repeat;
background-size: 70% 70%;
border-radius: 25px;
height: 50px;
margin-left: 30px;
width: 50px;
}
My index.html:
<<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="sidebar.css">
<script>
function slideIn(element1, element2, element3) {
var elem = document.getElementById(element1);
var elem2 = document.getElementById(element2);
var elem3 = document.getElementById(element3);
elem.style.transition = "left 0.5s ease-in 0s";
elem.style.left = "0px";
elem2.style.transition = "marginLeft 0.5s ease-in 0s";
elem2.style.marginLeft = "200px";
elem2.style.opacity = 0.75;
elem3.style.backgroundImage = 'url(SideBarButtonHover.png)';
elem3.style.backgroundColor = '#3f545d';
}
function slideOut(element1, element2, element3) {
var elem = document.getElementById(element1);
var elem2 = document.getElementById(element2);
var elem3 = document.getElementById(element3);
elem.style.transition = "left 0.5s ease-out 0s";
elem.style.left = "-200px";
elem2.style.transition = "marginLeft 0.5s ease-out 0s";
elem2.style.marginLeft = "0px";
elem2.style.opacity = 1;
elem3.style.backgroundImage = 'url(SideBarButton.png)';
elem3.style.backgroundColor = '#577481';
}
</script>
</head>
<body>
<div id="header">
<div id="sideBarButton" onMouseOver="slideIn('sidebar', 'content', 'sideBarButton');" onMouseOut="slideOut('sidebar', 'content', 'sideBarButton');"></div>
</div>
<div id="wrapper">
<div id="sidebar">
<ul>
<li>Hallo
</li>
</ul>
</div>
<div id="content">Ich bin der Content</div>
</div>
</body>
</html>
The transition with the first element(sidebar) works but not with the second one(content). It should work like this when you hover over the sidebarbutton, the sidebar will come out and the content will move at the same time to the right. My question is why doesn't the content transition work? Thanks for your help guys!
The transition with the first element(sidebar) works but not with the second one(content).
It should work like this when you hover over the sidebarbutton, the sidebar will come out and the content will move at the same time to the right. My question is why doesn't the content transition work?
Thanks for your help guys!
When setting a style value in javascript your style name should be camelCase'd, but if setting a value with a CSS property within it you should use the CSS property syntax. Correctly being:
elem2.style.transition = "margin-left 0.5s ease-in 0s";
elem2.style.marginLeft = "200px";