Reload page, If there are more than three div [duplicate] - javascript

This question already has an answer here:
Reload page, If there are more than three div
(1 answer)
Closed 11 months ago.
I have a page where circles are created and appear in random places.
When you click on the circle, it hides.
I want to make it so that when there are more than 3 circles on the page at the same time, then alerts appear, and when you click on ok, the page reloads.
I tried to add this piece to the end of the code, but nothing works:
if(i > 3) {
alert('Alert For your User!');
window.location.reload();
}
//create circle
var widthHeight = 35;
var margin = 25;
var delta = widthHeight + margin;
let clicks = 0;
function createDiv(id, color) {
let div = document.createElement('div');
var currentTop = 0;
var documentHeight = document.documentElement.clientHeight;
var documentWidth = document.documentElement.clientWidth;
div.setAttribute('class', id);
if (color === undefined) {
let colors = ['#35def2', '#35f242', '#b2f235', '#f2ad35', '#f24735', '#3554f2', '#8535f2', '#eb35f2', '#f2359b', '#f23547'];
div.style.borderColor = colors[Math.floor(Math.random() * colors.length)];
}
else {
div.style.borderColor = color;
}
div.classList.add("circle");
div.classList.add("animation");
currentTop = Math.floor(Math.random() * documentHeight) - delta;
currentLeft = Math.floor(Math.random() * documentWidth) - delta;
var limitedTop = Math.max(margin * -1, currentTop);
var limitedLeft = Math.max(margin * -1, currentLeft);
div.style.top = limitedTop + "px";
div.style.left = limitedLeft + "px";
const nodes = document.querySelectorAll('.animation');
for(let i = 0; i < nodes.length; i++) {
nodes[i].addEventListener('click', (event) => {
event.target.style.animation = 'Animation 200ms linear';
setTimeout(() => {
event.target.style.animation = '';
}, 220); });
}
$(div).click(function() {
$('#clicks').text(++clicks);
$(this).fadeOut();
});
document.body.appendChild(div);
}
let i = 0;
const oneSecond = 600;
setInterval(() => {
i += 1;
createDiv(`circle${i}`);
}, oneSecond);
.circle {
width: 30px;
height: 30px;
border-radius: 30px;
background-color: #ffffff;
border: 3px solid #000;
margin: 20px;
position: absolute;
}
#keyframes Animation {
0% {
transform: scale(1);
}
50% {
transform: scale(.8);
}
100% {
transform: scale(1);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Create a new variable circleCnt. When creating a new circle, assign +1, when clicking -1.
You can then do your own validation with this variable.
//create circle
var widthHeight = 35;
var margin = 25;
var delta = widthHeight + margin;
let clicks = 0;
let circleCnt = 0;
function createDiv(id, color) {
let div = document.createElement('div');
var currentTop = 0;
var documentHeight = document.documentElement.clientHeight;
var documentWidth = document.documentElement.clientWidth;
div.setAttribute('class', id);
if (color === undefined) {
let colors = ['#35def2', '#35f242', '#b2f235', '#f2ad35', '#f24735', '#3554f2', '#8535f2', '#eb35f2', '#f2359b', '#f23547'];
div.style.borderColor = colors[Math.floor(Math.random() * colors.length)];
}
else {
div.style.borderColor = color;
}
div.classList.add("circle");
div.classList.add("animation");
currentTop = Math.floor(Math.random() * documentHeight) - delta;
currentLeft = Math.floor(Math.random() * documentWidth) - delta;
var limitedTop = Math.max(margin * -1, currentTop);
var limitedLeft = Math.max(margin * -1, currentLeft);
div.style.top = limitedTop + "px";
div.style.left = limitedLeft + "px";
const nodes = document.querySelectorAll('.animation');
for(let i = 0; i < nodes.length; i++) {
nodes[i].addEventListener('click', (event) => {
event.target.style.animation = 'Animation 200ms linear';
setTimeout(() => {
event.target.style.animation = '';
}, 220); });
}
$(div).click(function() {
--circleCnt;
$('#clicks').text(++clicks);
$(this).fadeOut();
});
if(circleCnt > 3) {
alert('Alert For your User!');
window.location.reload();
}
document.body.appendChild(div);
}
let i = 0;
const oneSecond = 600;
setInterval(() => {
i += 1;
++circleCnt;
createDiv(`circle${i}`);
}, oneSecond);
.circle {
width: 30px;
height: 30px;
border-radius: 30px;
background-color: #ffffff;
border: 3px solid #000;
margin: 20px;
position: absolute;
}
#keyframes Animation {
0% {
transform: scale(1);
}
50% {
transform: scale(.8);
}
100% {
transform: scale(1);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Related

Only the first window is draggable

I created a code, where a window pops up. This window is draggable and resizable. I added a function in JavaScript, which adds two new windows when the first one is closed and adds more when the others are closed, but I also want them to be draggable as well.
I tried almost everything I know, but I don't seem to understand the issue.
const windowElement = document.querySelector("#window");
const header = document.querySelector("#header2");
const resizeContainer = document.querySelector("#resize-container");
let isDragging = false;
let currentX;
let currentY;
let xOffset = 0;
let yOffset = 0;
let isResizing = false;
let initialX;
let initialY;
let initialWidth;
let initialHeight;
let currentWidth;
let currentHeight;
const minimumWidth = 150;
const minimumHeight = 150;
header.addEventListener("mousedown", dragStart);
header.addEventListener("mouseup", dragEnd);
header.addEventListener("mousemove", drag);
resizeContainer.addEventListener("mousedown", resizeStart);
resizeContainer.addEventListener("mouseup", resizeEnd);
resizeContainer.addEventListener("mousemove", resize);
function dragStart(e) {
initialX = e.clientX - xOffset;
initialY = e.clientY - yOffset;
isDragging = true;
}
function dragEnd(e) {
isDragging = false;
}
function drag(e) {
e.preventDefault();
if (isDragging) {
currentX = e.clientX - initialX;
currentY = e.clientY - initialY;
xOffset = currentX;
yOffset = currentY;
setTranslate(currentX, currentY, windowElement);
}
}
function setTranslate(xPos, yPos, el) {
el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)";
}
function resizeStart(e) {
initialX = e.clientX;
initialY = e.clientY;
initialWidth = windowElement.offsetWidth;
initialHeight = windowElement.offsetHeight;
isResizing = true;
}
function resizeEnd(e) {
isResizing = false;
}
function resize(e) {
if (isResizing) {
currentWidth = initialWidth + (e.clientX - initialX);
currentHeight = initialHeight + (e.clientY - initialY);
if (currentWidth >= minimumWidth) {
windowElement.style.width = currentWidth + "px";
}
if (currentHeight >= minimumHeight) {
windowElement.style.height = currentHeight + "px";
}
}
}
function closeWindow() {
const parentElement = document.querySelector("#parent");
const windowElement = document.querySelector("#window");
windowElement.style.display = "none";
setTimeout(() => {
const newWindow1 = windowElement.cloneNode(true);
const newWindow2 = windowElement.cloneNode(true);
const xPos1 = Math.floor(Math.random() * (parentElement.offsetWidth - newWindow1.offsetWidth));
const yPos1 = Math.floor(Math.random() * (parentElement.offsetHeight - newWindow1.offsetHeight));
const xPos2 = Math.floor(Math.random() * (parentElement.offsetWidth - newWindow2.offsetWidth));
const yPos2 = Math.floor(Math.random() * (parentElement.offsetHeight - newWindow2.offsetHeight));
newWindow1.style.display = "";
newWindow2.style.display = "";
setTranslate(xPos1, yPos1, newWindow1);
setTranslate(xPos2, yPos2, newWindow2);
parentElement.appendChild(newWindow1);
parentElement.appendChild(newWindow2);
}, 500);
}
function createWindow() {
const parentElement = document.querySelector("#parent");
const windowElement = document.createElement("div");
let isDragging = false;
let currentX;
let currentY;
let initialX;
let initialY;
let xOffset = 0;
let yOffset = 0;
function dragStart(e) {
initialX = e.clientX - xOffset;
initialY = e.clientY - yOffset;
isDragging = true;
}
function dragEnd(e) {
isDragging = false;
}
function drag(e) {
if (isDragging) {
e.preventDefault();
currentX = e.clientX - initialX;
currentY = e.clientY - initialY;
xOffset = currentX;
yOffset = currentY;
setTranslate(currentX, currentY, this.parentNode);
}
}
function setTranslate(xPos, yPos, el) {
el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)";
}
windowElement.classList.add("old-computer-window");
windowElement.style.left = Math.floor(Math.random() * (parentElement.offsetWidth - 300)) + "px";
windowElement.style.top = Math.floor(Math.random() * (parentElement.offsetHeight - 300)) + "px";
windowElement.setAttribute("data-aos", "zoom-in");
windowElement.setAttribute("data-aos-delay", "300");
const header = document.createElement("div");
header.classList.add("header2");
header.innerHTML = '<p>DANIEL.JPG</p><div class="close" onclick="closeWindow(this)">โœ•</div>';
const imageContainer = document.createElement("div");
imageContainer.classList.add("image-container");
const resizeContainer = document.createElement("div");
resizeContainer.classList.add("resize-container");
windowElement.appendChild(header);
windowElement.appendChild(imageContainer);
windowElement.appendChild(resizeContainer);
parentElement.appendChild(windowElement);
header.addEventListener("mousedown", dragStart);
header.addEventListener("mouseup", dragEnd);
header.addEventListener("mousemove", drag);
resizeContainer.addEventListener("mousedown", resizeStart);
resizeContainer.addEventListener("mouseup", resizeEnd);
resizeContainer.addEventListener("mousemove", resize);
}
#computer-window {
width: 100%;
height: 300px;
background-color: #ddd;
border-style: solid;
border-width: 2px;
border-left-color: white;
border-top-color: white;
border-bottom-color: darkred;
border-right-color: darkred;
}
#header2 {
background-color: black;
color: #fff;
padding: 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
#title {
font-size: 20px;
font-weight: bold;
}
#close-btn {
border-style: solid;
border-width: 2px;
border-left-color: white;
border-top-color: white;
border-bottom-color: darkred;
border-right-color: darkred;
padding: 5px 10px;
border-radius: 5px;
cursor: pointer;
}
#parent {
position: relative;
width: 800px;
height: 600px;
border: orange;
}
#window {
position: absolute;
width: 100%;
max-height: 1080px;
background-color: white;
border-style: solid;
border-width: 2px;
border-left-color: #191919;
border-top-color: #191919;
border-bottom-color: darkred;
border-right-color: darkred;
user-select: none;
overflow: hidden;
<div data-aos="zoom-in" data-aos-delay="300" id="parent">
<div class="old-computer-window" id="window">
<div class="header2" id="header2">
<p>DANIEL.JPG</p>
<div class="close" id="close" onclick="closeWindow()">โœ•</div>
</div>
<div class="image-container"></div>
<div class="resize-container" id="resize-container"></div>
</div>
</div>

Reload page, If there are more than three div

I have a page where circles are created and appear in random places.
When you click on the circle, it hides.
I want to make it so that when there are more than 3 circles on the page at the same time, then alerts appear, and when you click on ok, the page reloads.
I added a new variable, when creating a circle we get +1, when we click on the circle -1. Then I added a condition
let circleCount = 0;
++circleCount;
--circleCount;
if(circleCount > 3) {
alert('Alert For your User!');
window.location.reload();
}
Everything works as it should, only when we click OK in the alert, reloading the page does not work correctly, sometimes you need to click several times to reload. What could be the problem?
//create circle
var widthHeight = 35;
var margin = 25;
var delta = widthHeight + margin;
let clicks = 0;
let circleCount = 0;
function createDiv(id, color) {
let div = document.createElement('div');
var currentTop = 0;
var documentHeight = document.documentElement.clientHeight;
var documentWidth = document.documentElement.clientWidth;
div.setAttribute('class', id);
if (color === undefined) {
let colors = ['#35def2', '#35f242', '#b2f235', '#f2ad35', '#f24735', '#3554f2', '#8535f2', '#eb35f2', '#f2359b', '#f23547'];
div.style.borderColor = colors[Math.floor(Math.random() * colors.length)];
}
else {
div.style.borderColor = color;
}
div.classList.add("circle");
div.classList.add("animation");
currentTop = Math.floor(Math.random() * documentHeight) - delta;
currentLeft = Math.floor(Math.random() * documentWidth) - delta;
var limitedTop = Math.max(margin * -1, currentTop);
var limitedLeft = Math.max(margin * -1, currentLeft);
div.style.top = limitedTop + "px";
div.style.left = limitedLeft + "px";
const nodes = document.querySelectorAll('.animation');
for(let i = 0; i < nodes.length; i++) {
nodes[i].addEventListener('click', (event) => {
event.target.style.animation = 'Animation 200ms linear';
setTimeout(() => {
event.target.style.animation = '';
}, 220); });
}
$(div).click(function() {
$('#clicks').text(++clicks);
--circleCount;
$(this).fadeOut();
});
if (circleCount > 3) {
alert('Alert For your User!');
window.location.reload();
}
document.body.appendChild(div);
}
let i = 0;
const oneSecond = 600;
setInterval(() => {
i += 1;
++circleCount;
createDiv(`circle${i}`);
}, oneSecond);
.circle {
width: 30px;
height: 30px;
border-radius: 30px;
background-color: #ffffff;
border: 3px solid #000;
margin: 20px;
position: absolute;
}
#keyframes Animation {
0% {
transform: scale(1);
}
50% {
transform: scale(.8);
}
100% {
transform: scale(1);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I think only you need to else part at the end of reloading, just see
if (circleCount > 3) {
alert('Alert For your User!');
window.location.reload();
}
else
document.body.appendChild(div);
So run below code and check is it fixed or not
let circleCount = 0;
++circleCount;
--circleCount;
if(circleCount > 3) {
alert('Alert For your User!');
window.location.reload();
}
Everything works as it should, only when we click OK in the alert, reloading the page does not work correctly, sometimes you need to click several times to reload. What could be the problem?
//create circle
var widthHeight = 35;
var margin = 25;
var delta = widthHeight + margin;
let clicks = 0;
let circleCount = 0;
function createDiv(id, color) {
let div = document.createElement('div');
var currentTop = 0;
var documentHeight = document.documentElement.clientHeight;
var documentWidth = document.documentElement.clientWidth;
div.setAttribute('class', id);
if (color === undefined) {
let colors = ['#35def2', '#35f242', '#b2f235', '#f2ad35', '#f24735', '#3554f2', '#8535f2', '#eb35f2', '#f2359b', '#f23547'];
div.style.borderColor = colors[Math.floor(Math.random() * colors.length)];
}
else {
div.style.borderColor = color;
}
div.classList.add("circle");
div.classList.add("animation");
currentTop = Math.floor(Math.random() * documentHeight) - delta;
currentLeft = Math.floor(Math.random() * documentWidth) - delta;
var limitedTop = Math.max(margin * -1, currentTop);
var limitedLeft = Math.max(margin * -1, currentLeft);
div.style.top = limitedTop + "px";
div.style.left = limitedLeft + "px";
const nodes = document.querySelectorAll('.animation');
for(let i = 0; i < nodes.length; i++) {
nodes[i].addEventListener('click', (event) => {
event.target.style.animation = 'Animation 200ms linear';
setTimeout(() => {
event.target.style.animation = '';
}, 220); });
}
$(div).click(function() {
$('#clicks').text(++clicks);
--circleCount;
$(this).fadeOut();
});
if (circleCount > 3) {
console.log(circleCount);//alert('Alert For your User!');
window.location.reload();
}
else
document.body.appendChild(div);
}
let i = 0;
const oneSecond = 600;
setInterval(() => {
i += 1;
++circleCount;
createDiv(`circle${i}`);
}, oneSecond);
.circle {
width: 30px;
height: 30px;
border-radius: 30px;
background-color: #ffffff;
border: 3px solid #000;
margin: 20px;
position: absolute;
}
#keyframes Animation {
0% {
transform: scale(1);
}
50% {
transform: scale(.8);
}
100% {
transform: scale(1);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Counting the number of clicks on the circles created by the script

I have a function that creates divs with a circle. Now they are all created and appear at the beginning of the page and go further in order. Next, I need each circle to appear in a random place. I did this. Now I want to add a count of clicks on these circles
To do this, I added to the code
let clicks = 0;
And in the click function itself
clicks += 1;
document.getElementById("clicks").innerHTML = clicks;
But in the end, after clicking, the value does not exceed 1. How can this be fixed?
//create circle
var widthHeight = 45;
var margin = 25;
var delta = widthHeight + margin;
function createDiv(id, color) {
let div = document.createElement('div');
var currentTop = 0;
var documentHeight = document.documentElement.clientHeight;
var documentWidth = document.documentElement.clientWidth;
div.setAttribute('class', id);
if (color === undefined) {
let colors = ['#35def2', '#35f242', '#b2f235', '#f2ad35', '#f24735', '#3554f2', '#8535f2', '#eb35f2', '#f2359b', '#f23547'];
div.style.borderColor = colors[Math.floor(Math.random() * colors.length)];
} else {
div.style.borderColor = color;
}
div.classList.add("circle");
`enter code here`
div.classList.add("animation");
currentTop = Math.floor(Math.random() * documentHeight) - delta;
currentLeft = Math.floor(Math.random() * documentWidth) - delta;
var limitedTop = Math.max(margin * -1, currentTop);
var limitedLeft = Math.max(margin * -1, currentLeft);
div.style.top = limitedTop + "px";
div.style.left = limitedLeft + "px";
const nodes = document.querySelectorAll('.animation');
for (let i = 0; i < nodes.length; i++) {
nodes[i].addEventListener('click', (event) => {
event.target.style.animation = 'Animation 200ms linear';
setTimeout(() => {
event.target.style.animation = '';
}, 220);
});
}
let clicks = 0;
$("div").click(function() {
clicks += 1;
document.getElementById("clicks").innerHTML = clicks;
$(this).fadeOut("slow");
});
document.body.appendChild(div);
}
let i = 0;
const oneSecond = 1000;
setInterval(() => {
i += 1;
createDiv(`circle${i}`)
}, oneSecond);
.circle {
width: 35px;
height: 35px;
border-radius: 35px;
background-color: #ffffff;
border: 3px solid #000;
margin: 20px;
position: absolute;
}
#keyframes Animation {
0% {
transform: scale(1);
}
50% {
transform: scale(.8);
}
100% {
transform: scale(1);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p><a id="clicks">0</a></p>
the issue come from let clicks = 0;each time method createDiv is called it reinit the value of click to 0
one way can be to get the content of #clicks and parse it to int before increment by one
one other think you already use jquery in that case to update text of #clicks you just have to use $('#clicks').text('your wanted text')
$(div).click(function() {
$('#clicks').text(parseInt($('#clicks').text()) + 1);
$(this).fadeOut("slclicksow");
});
//create circle
var widthHeight = 45;
var margin = 25;
var delta = widthHeight + margin;
function createDiv(id, color) {
let div = document.createElement('div');
var currentTop = 0;
var documentHeight = document.documentElement.clientHeight;
var documentWidth = document.documentElement.clientWidth;
div.setAttribute('class', id);
if (color === undefined) {
let colors = ['#35def2', '#35f242', '#b2f235', '#f2ad35', '#f24735', '#3554f2', '#8535f2', '#eb35f2', '#f2359b', '#f23547'];
div.style.borderColor = colors[Math.floor(Math.random() * colors.length)];
} else {
div.style.borderColor = color;
}
div.classList.add("circle");
div.classList.add("animation");
currentTop = Math.floor(Math.random() * documentHeight) - delta;
currentLeft = Math.floor(Math.random() * documentWidth) - delta;
var limitedTop = Math.max(margin * -1, currentTop);
var limitedLeft = Math.max(margin * -1, currentLeft);
div.style.top = limitedTop + "px";
div.style.left = limitedLeft + "px";
const nodes = document.querySelectorAll('.animation');
for (let i = 0; i < nodes.length; i++) {
nodes[i].addEventListener('click', (event) => {
event.target.style.animation = 'Animation 200ms linear';
setTimeout(() => {
event.target.style.animation = '';
}, 220);
});
}
let clicks = 0;
$(div).click(function() {
$('#clicks').text(parseInt($('#clicks').text()) + 1);
$(this).fadeOut("slclicksow");
});
document.body.appendChild(div);
}
let i = 0;
const oneSecond = 1000;
setInterval(() => {
i += 1;
createDiv(`circle${i}`)
}, oneSecond);
.circle {
width: 35px;
height: 35px;
border-radius: 35px;
background-color: #ffffff;
border: 3px solid #000;
margin: 20px;
position: absolute;
}
#keyframes Animation {
0% {
transform: scale(1);
}
50% {
transform: scale(.8);
}
100% {
transform: scale(1);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p><a id="clicks">0</a></p>
It happens because you have let clicks = 0 inside the function that creates divs. So when a new div appears it resets to 0;
To fix it just move the variable outside the function:
//create circle
var widthHeight = 45;
var margin = 25;
var delta = widthHeight + margin;
// Move here
let clicks = 0;
function createDiv(id, color) {
let div = document.createElement('div');
var currentTop = 0;
var documentHeight = document.documentElement.clientHeight;
var documentWidth = document.documentElement.clientWidth;
div.setAttribute('class', id);
if (color === undefined) {
let colors = ['#35def2', '#35f242', '#b2f235', '#f2ad35', '#f24735', '#3554f2', '#8535f2', '#eb35f2', '#f2359b', '#f23547'];
div.style.borderColor = colors[Math.floor(Math.random() * colors.length)];
} else {
div.style.borderColor = color;
}
div.classList.add("circle");
`enter code here`
div.classList.add("animation");
currentTop = Math.floor(Math.random() * documentHeight) - delta;
currentLeft = Math.floor(Math.random() * documentWidth) - delta;
var limitedTop = Math.max(margin * -1, currentTop);
var limitedLeft = Math.max(margin * -1, currentLeft);
div.style.top = limitedTop + "px";
div.style.left = limitedLeft + "px";
const nodes = document.querySelectorAll('.animation');
for (let i = 0; i < nodes.length; i++) {
nodes[i].addEventListener('click', (event) => {
event.target.style.animation = 'Animation 200ms linear';
setTimeout(() => {
event.target.style.animation = '';
}, 220);
});
}
$("div").click(function() {
clicks += 1;
document.getElementById("clicks").innerHTML = clicks;
$(this).fadeOut("slow");
});
document.body.appendChild(div);
}
let i = 0;
const oneSecond = 1000;
setInterval(() => {
i += 1;
createDiv(`circle${i}`)
}, oneSecond);
.circle {
width: 35px;
height: 35px;
border-radius: 35px;
background-color: #ffffff;
border: 3px solid #000;
margin: 20px;
position: absolute;
}
#keyframes Animation {
0% {
transform: scale(1);
}
50% {
transform: scale(.8);
}
100% {
transform: scale(1);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p><a id="clicks">0</a></p>

Different scroll speeds for elements in array

I have different randomly-styled stars in an array and I would like them to each have different scroll speeds between -.2 and -.8. The idea is to have them do a parallax effect, and it'd be cool to have everything a little random.
This was the original scroll speed code using images:
var starsOne = document.querySelector("#starsOne");
function setTranslate(xPos, yPos, el) {
el.style.transform = "translate3d(" + xPos + ", " + yPos + "px, 0)";
}
var xScrollPosition;
var yScrollPosition;
function scrollLoop() {
xScrollPosition = window.scrollX;
yScrollPosition = window.scrollY;
setTranslate(0, yScrollPosition * -0.6, starsOne);
requestAnimationFrame(scrollLoop);
}
window.addEventListener("load", scrollLoop, false);
I've been trying to integrate the above code somehow for the array:
let starScrollMin = 2;
let starScrollMax = 8;
var starScrollSpeed = -Math.abs((Math.floor(Math.random() * (starScrollMax - starScrollMin + 1)) + starScrollMin) / 10);
function starScroll() {
for (i = 0; i < starDivvyArr.length; i++) {
yScrollPos = window.scrollY;
starDivvyArr[i].style.transform = "translate3d(" + 0 + "px, " + yScrollPos * starScrollSpeed + "px, 0)";
}
requestAnimationFrame(starScroll);
}
window.addEventListener("load", starScroll, false);
If starScrollSpeed is global, then all the stars move in a big chunk. If it's within the starScroll() function, the values are at least different per star, but it gets crazy as it keeps randomizing and multiplying.
Any ideas on how to randomize the scroll speed for each star so it looks like a parallax effect, without them moving in one single chunk or going crazy? Or is it a safer bet to make a bunch of css lines and then randomly assign classes?
jsfiddle
It's a bit unclear what exactly you're after.
If you're trying to set a random scroll speed for each star, and not change it every time the startScroll triggers.
you could set a speed for each start separately inside the loop and use that in the startScroll function instead:
...
starDivvyArr[i].starScrollSpeed = -Math.abs((Math.floor(Math.random() * (starScrollMax - starScrollMin + 1)) + starScrollMin) / 10);
...
starDivvyArr[i].style.transform = "translate3d(" + 0 + "px, " + yScrollPos * starDivvyArr[i].starScrollSpeed + "px, 0)";
var starCount = 25;
let starContain = document.getElementById('starContain');
/*Create star divs*/
for (var i = 0; i < starCount; i++) {
var starDiv = document.createElement("div");
starDiv.className = 'star';
starContain.append(starDiv);
}
/*Make an array from the star divs*/
var starDivvy = document.querySelectorAll(".star");
var starDivvyArr = Array.from(starDivvy);
/*Create some possible styles*/
var starColor = ['yellow', 'blue', 'white'];
var starSizeMin = 5;
var starSizeMax = 25;
let starContainWidth = starContain.offsetWidth;
let starContainHeight = starContain.offsetHeight;
let starScrollMin = 2;
let starScrollMax = 8;
/*Give the star array some different styles*/
for (i = 0; i < starDivvyArr.length; i++) {
/*Change star color*/
starDivvyArr[i].style.backgroundColor = starColor[Math.floor(Math.random() * starColor.length)];
/*Change star position within container*/
starDivvyArr[i].style.left = Math.floor((Math.random() * starContainWidth) + 1) + "px";
starDivvyArr[i].style.top = Math.floor((Math.random() * starContainHeight) + 1) + "px";
/*Change star size*/
starDivvyArr[i].style.width = Math.floor(Math.random() * (starSizeMax - starSizeMin + 1)) + starSizeMin + "px";
starDivvyArr[i].style.height = starDivvyArr[i].style.width;
starDivvyArr[i].starScrollSpeed = -Math.abs((Math.floor(Math.random() * (starScrollMax - starScrollMin + 1)) + starScrollMin) / 10);
}
/*>>>>>>>POINT OF CONFUSION<<<<<<<*/
/*Randomize scroll speed between -0.2 and -0.8*/
/*Give the stars a scrolling function*/
function starScroll() {
for (i = 0; i < starDivvyArr.length; i++) {
yScrollPos = window.scrollY;
starDivvyArr[i].style.transform = "translate3d(" + 0 + "px, " + yScrollPos * starDivvyArr[i].starScrollSpeed + "px, 0)";
}
requestAnimationFrame(starScroll);
}
window.addEventListener("load", starScroll, false);
*{
margin:0 auto;
}
section{
width:100vw;
height:150vh;
}
.section1{
background-color:#000;
}
.section2{
background-color:#202;
}
h2{
text-align:center;
color:#ccc;
}
#starContain{
width:100vw;
height:500px;
position:absolute;
top:50vh;
z-index:2;
background-color:rgba(255,255,255,0.2);
}
.star{
background-color:green;
position:absolute;
z-index:100;
border-radius:50%;
}
<main>
<section class="section1">
<h2>
Section 1
</h2>
</section>
<div id="starContain">
</div>
<section class="section2">
<h2>
Section 2
</h2>
</section>
</main>
You could create an array for the randomly created numbers and push a value from a function that returns the randomly created speed into that array with in the loop and then use that array to get a random value for each element.
var starCount = 25;
let starContain = document.getElementById('starContain');
/*Create star divs*/
for (var i = 0; i < starCount; i++) {
var starDiv = document.createElement("div");
starDiv.className = 'star';
starContain.append(starDiv);
}
/*Make an array from the star divs*/
var starDivvy = document.querySelectorAll(".star");
var starDivvyArr = Array.from(starDivvy);
/*Create some possible styles*/
var starColor = ['yellow', 'blue', 'white'];
var starSizeMin = 5;
var starSizeMax = 25;
let starContainWidth = starContain.offsetWidth;
let starContainHeight = starContain.offsetHeight;
/*Give the star array some different styles*/
for (i = 0; i < starDivvyArr.length; i++) {
/*Change star color*/
starDivvyArr[i].style.backgroundColor = starColor[Math.floor(Math.random() * starColor.length)];
/*Change star position within container*/
starDivvyArr[i].style.left = Math.floor((Math.random() * starContainWidth) + 1) + "px";
starDivvyArr[i].style.top = Math.floor((Math.random() * starContainHeight) + 1) + "px";
/*Change star size*/
starDivvyArr[i].style.width = Math.floor(Math.random() * (starSizeMax - starSizeMin + 1)) + starSizeMin + "px";
starDivvyArr[i].style.height = starDivvyArr[i].style.width;
}
/*>>>>>>>POINT OF CONFUSION<<<<<<<*/
/*Randomize scroll speed between -0.2 and -0.8*/
let starScrollMin = 2;
let starScrollMax = 8;
//function for creating random scroll speed
const starScrollSpeed = (min,max) => {
return -Math.abs((Math.floor(Math.random() * (min - max + 1)) + min) / 10);
}
//==> added array
const starArray = [];
/*Give the stars a scrolling function*/
function starScroll() {
for (i = 0; i < starDivvyArr.length; i++) {
// array to hold randomly created scroll speeds
starArray.push(starScrollSpeed(starScrollMin,starScrollMax))
yScrollPos = window.scrollY;
starDivvyArr[i].style.transform = "translate3d(" + 0 + "px, " + yScrollPos * starArray[i] + "px, 0)";
}
requestAnimationFrame(starScroll);
}
window.addEventListener("load", starScroll, false);
* {
margin: 0 auto;
}
section {
width: 100vw;
height: 150vh;
}
.section1 {
background-color: #000;
}
.section2 {
background-color: #202;
}
h2 {
text-align: center;
color: #ccc;
}
#starContain {
width: 100vw;
height: 500px;
position: absolute;
top: 50vh;
z-index: 2;
background-color: rgba(255, 255, 255, 0.2);
}
.star {
background-color: green;
position: absolute;
z-index: 100;
border-radius: 50%;
}
<main>
<section class="section1">
<h2>
Section 1
</h2>
</section>
<div id="starContain">
</div>
<section class="section2">
<h2>
Section 2
</h2>
</section>
</main>

Cannot read properties of null (reading 'animate') error chrome JS animation

I am new to webdev and I am trying to use this CodePen to animate my buttons:
https://codepen.io/Mamboleoo/pen/JjdXPgR
However, I am still getting this error on chrome when trying to run the code:
Uncaught TypeError: Cannot read properties of null (reading 'animate')
I tried replacing the last JS line to: if ( document.getElementByID("aaa").animate ){} but no success.enter code here
Can anyone help me please ?
HTML
<div class="contianer">
<div class="wrapper" id="aaa">
<button data-type="square">Square particles</button>
<button data-type="emoji">Emoji particles</button>
<button data-type="mario">Mario particles</button>
<button data-type="shadow">Shadow particles</button>
<button data-type="line">Line particles</button>
</div>
<span class="preloader"></span>
</div>
CSS
particle {
position: fixed;
top: 0;
left: 0;
opacity: 0;
pointer-events: none;
background-repeat: no-repeat;
background-size: contain;
}
.wrapper {
position: absolute;
}
.wrapper button {
padding: 20px;
margin: 10px;
align-self: center;
}
.preloader {
position: absolute;
background: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/127738/mario-face.png);
}
JS:
function pop (e) {
let amount = 30;
switch (e.target.dataset.type) {
case 'shadow':
case 'line':
amount = 60;
break;
}
// Quick check if user clicked the button using a keyboard
if (e.clientX === 0 && e.clientY === 0) {
const bbox = e.target.getBoundingClientRect();
const x = bbox.left + bbox.width / 2;
const y = bbox.top + bbox.height / 2;
for (let i = 0; i < 30; i++) {
// We call the function createParticle 30 times
// We pass the coordinates of the button for x & y values
createParticle(x, y, e.target.dataset.type);
}
} else {
for (let i = 0; i < amount; i++) {
createParticle(e.clientX, e.clientY + window.scrollY, e.target.dataset.type);
}
}
}
function createParticle (x, y, type) {
const particle = document.createElement('particle');
document.body.appendChild(particle);
let width = Math.floor(Math.random() * 30 + 8);
let height = width;
let destinationX = (Math.random() - 0.5) * 300;
let destinationY = (Math.random() - 0.5) * 300;
let rotation = Math.random() * 520;
let delay = Math.random() * 200;
switch (type) {
case 'square':
particle.style.background = `hsl(${Math.random() * 90 + 270}, 70%, 60%)`;
particle.style.border = '1px solid white';
break;
case 'emoji':
particle.innerHTML = ['โค','๐Ÿงก','๐Ÿ’›','๐Ÿ’š','๐Ÿ’™','๐Ÿ’œ','๐ŸคŽ'][Math.floor(Math.random() * 7)];
particle.style.fontSize = `${Math.random() * 24 + 10}px`;
width = height = 'auto';
break;
case 'mario':
particle.style.backgroundImage = 'url(https://s3-us-west-
2.amazonaws.com/s.cdpn.io/127738/mario-face.png)';
break;
case 'shadow':
var color = `hsl(${Math.random() * 90 + 90}, 70%, 50%)`;
particle.style.boxShadow = `0 0 ${Math.floor(Math.random() * 10 + 10)}px ${color}`;
particle.style.background = color;
particle.style.borderRadius = '50%';
width = height = Math.random() * 5 + 4;
break;
case 'line':
var color = `hsl(${Math.random() * 90 + 90}, 70%, 50%)`;
particle.style.background = 'black';
height = 1;
rotation += 1000;
delay = Math.random() * 1000;
break;
}
particle.style.width = `${width}px`;
particle.style.height = `${height}px`;
const animation = particle.animate([
{
transform: `translate(-50%, -50%) translate(${x}px, ${y}px) rotate(0deg)`,
opacity: 1
},
{
transform: `translate(-50%, -50%) translate(${x + destinationX}px, ${y + destinationY}px)
rotate(${rotation}deg)`,
opacity: 0
}
], {
duration: Math.random() * 1000 + 5000,
easing: 'cubic-bezier(0, .9, .57, 1)',
delay: delay
});
animation.onfinish = removeParticle;
}
function removeParticle (e) {
e.srcElement.effect.target.remove();
}
if (document.body.animate) {
document.querySelectorAll('button').forEach(button => button.addEventListener('click', pop));
}

Categories

Resources