Stop auto type at last array [closed] - javascript

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I'm trying to stop erasing my "auto typed text" when the last array is reached.
I've been searching so for on Google but I can't find any solution.
const typedTextSpan = document.querySelector(".typed-text");
const cursorSpan = document.querySelector(".cursor");
const textArray = ["reconnaitre un talent ?", "détécter une opportunité ?"];
const typingDelay = 170;
const erasingDelay = 100;
const newTextDelay = 2000;
let textArrayIndex = 0;
let charIndex = 0;
function type() {
if (charIndex < textArray[textArrayIndex].length) {
if (cursorSpan.classList.contains("typing")) cursorSpan.classList.add("typing");
typedTextSpan.textContent += textArray[textArrayIndex].charAt(charIndex);
charIndex++;
setTimeout(type, typingDelay);
} else {
cursorSpan.classList.remove("typing");
setTimeout(erase, newTextDelay);
}
}
function erase() {
if (charIndex > 0) {
if (!cursorSpan.classList.contains("typing")) cursorSpan.classList.add("typing");
typedTextSpan.textContent = textArray[textArrayIndex].substring(0, charIndex - 1);
charIndex--;
setTimeout(erase, erasingDelay);
} else {
cursorSpan.classList.remove("typing");
textArrayIndex++;
if (textArrayIndex >= textArray.length) textArrayIndex = 0;
setTimeout(type, typingDelay + 1100);
}
}
document.addEventListener("DOMContentLoaded", function() {
if (textArray.length) setTimeout(type, newTextDelay + 250);
});
<div class="container" id="container">
<h1>Savez-vous <span class="typed-text" id="typed-text"></span><span class="cursor" id="cursor"> </span></h1>
</div>

Currently your functions keep calling each other without any signal to stop somewhere. You already keep track of where your index currently is in the textArray with textArrayIndex. Use that to see if the end has been reached in the else statement of your type function.
if (textArrayIndex < textArray.length - 1) {
setTimeout(erase, newTextDelay);
}
Here it checks if the current index is lower than the last index of the array. If it is, it will continue to call the erase function and increment textArrayIndex with 1 there. Otherwise when the index is not lower than the last index, meaning it's the last one, it will simply do nothing, thus breaking the loop.
const typedTextSpan = document.querySelector(".typed-text");
const cursorSpan = document.querySelector(".cursor");
const textArray = ["reconnaitre un talent ?", "détécter une opportunité ?"];
const typingDelay = 170;
const erasingDelay = 100;
const newTextDelay = 2000;
let textArrayIndex = 0;
let charIndex = 0;
function type() {
if (charIndex < textArray[textArrayIndex].length) {
if (cursorSpan.classList.contains("typing")) cursorSpan.classList.add("typing");
typedTextSpan.textContent += textArray[textArrayIndex].charAt(charIndex);
charIndex++;
setTimeout(type, typingDelay);
} else {
cursorSpan.classList.remove("typing");
// Erase if the end has not yet been reached.
if (textArrayIndex < textArray.length - 1) {
setTimeout(erase, newTextDelay);
}
}
}
function erase() {
if (charIndex > 0) {
if (!cursorSpan.classList.contains("typing")) cursorSpan.classList.add("typing");
typedTextSpan.textContent = textArray[textArrayIndex].substring(0, charIndex - 1);
charIndex--;
setTimeout(erase, erasingDelay);
} else {
cursorSpan.classList.remove("typing");
textArrayIndex++;
setTimeout(type, typingDelay + 1100);
}
}
document.addEventListener("DOMContentLoaded", function() {
if (textArray.length) setTimeout(type, newTextDelay + 250);
});
<div class="container" id="container">
<h1>Savez-vous <span class="typed-text" id="typed-text"></span><span class="cursor" id="cursor"> </span></h1>
</div>

You need to compare the textArrayIndex with the textArray length in erase function. Please check below code for this.
const typedTextSpan = document.querySelector(".typed-text");
const cursorSpan = document.querySelector(".cursor");
const textArray = ["reconnaitre un talent ?", "détécter une opportunité ?"];
const typingDelay = 170;
const erasingDelay = 100;
const newTextDelay = 2000;
let textArrayIndex = 0;
let charIndex = 0;
function type() {
if (charIndex < textArray[textArrayIndex].length) {
if (cursorSpan.classList.contains("typing")) cursorSpan.classList.add("typing");
typedTextSpan.textContent += textArray[textArrayIndex].charAt(charIndex);
charIndex++;
setTimeout(type, typingDelay);
} else {
cursorSpan.classList.remove("typing");
setTimeout(erase, newTextDelay);
}
}
function erase() {
// Check index
if(textArrayIndex == textArray.length - 1) {
// Stop Erase
return false;
}
if (charIndex > 0) {
if (!cursorSpan.classList.contains("typing")) cursorSpan.classList.add("typing");
typedTextSpan.textContent = textArray[textArrayIndex].substring(0, charIndex - 1);
charIndex--;
setTimeout(erase, erasingDelay);
} else {
cursorSpan.classList.remove("typing");
textArrayIndex++;
if (textArrayIndex >= textArray.length) textArrayIndex = 0;
setTimeout(type, typingDelay + 1100);
}
}
document.addEventListener("DOMContentLoaded", function() {
if (textArray.length) setTimeout(type, newTextDelay + 250);
});
<div class="container" id="container">
<h1>Savez-vous <span class="typed-text" id="typed-text"></span><span class="cursor" id="cursor"> </span></h1>
</div>

Related

Reuse button to trigger another function

So I'm still practicing and learning and I'm creating a number guessing game and I was planning on re-using a existing button to trigger the reset of the game however for some reason it will reset however upon doing so-- resetGame() will reset variables but not start the checkGuess() like it's suppose to and only continue to randomize the randomNumber when 'submit' button is clicked..
I'm assuming that this must be bad practice and figure I shouldn't do this but wanted to ask why this wasn't re-starting the game as it should... what am I missing?
let randomNumber = Math.floor(Math.random() * 10) + 1;
let guessField = document.getElementById('guessField');
let enterButton = document.getElementById('userSubmit');
let lastResult = document.querySelector('.lastResult');
let lowOrHigh = document.querySelector('.lowOrHigh');
let guesses = document.querySelector('.guesses');
let guessRemaining = 5;
enterButton.addEventListener('click', checkGuess);
// function log() {
// console.log(Number(document.getElementById('guessField').value));
// }
function checkGuess() {
let userGuess = Number(guessField.value);
if (guessRemaining === 5) {
guesses.textContent = 'Previous guesses: ';
}
guesses.textContent += userGuess + ' ';
if (userGuess === randomNumber) {
lastResult.textContent = 'Congratulations! You got it right!';
lastResult.style.background = 'green';
gameOver();
} else if (guessRemaining < 1) {
lastResult.textContent = 'GAME OVER!';
gameOver();
} else {
lastResult.textContent = 'Wrong answer!';
lastResult.style.background = 'red';
lastResult.style.color = 'white';
if (userGuess < randomNumber) {
lowOrHigh.textContent = 'Too low!';
} else if (userGuess > randomNumber) {
lowOrHigh.textContent = 'Too high!';
}
}
guessRemaining--;
guessField.value = '';
guessField.focus();
}
function gameOver() {
guessField.disabled = true;
enterButton.setAttribute('value', 'Replay');
enterButton.addEventListener('click', resetGame);
}
function resetGame() {
randomNumber = Math.floor(Math.random() * 10) + 1;
// document.getElementById('userGuess').value = '';
lastResult.textContent = '';
guesses.textContent = '';
lowOrHigh.textContent = '';
guessField.disabled = false;
enterButton.setAttribute('value', 'Submit');
guessRemaining = 5;
}
The problem is that after you finish the game the resetGame callback is added as event listener and is triggered every time you click the userSubmit button. There are few possibilities how to solve this problem:
1. Check if the game is running
In this solution, you don't add the resetGame callback, but you call it within the checkGuess callback. To make this solution work you have to add a variable which represents if the game is running or not. This way if the game is still running the checkGuess callback will call the default behaviour, but after the gameOver is called, checkGuess will reset the game.
let randomNumber = Math.floor(Math.random() * 10) + 1;
let guessField = document.getElementById('guessField');
let enterButton = document.getElementById('userSubmit');
let lastResult = document.querySelector('.lastResult');
let lowOrHigh = document.querySelector('.lowOrHigh');
let guesses = document.querySelector('.guesses');
let guessRemaining = 5;
let isRunning = true;
enterButton.addEventListener('click', checkGuess);
function checkGuess() {
if (isRunning) { // Check if the game is running
let userGuess = Number(guessField.value);
if (guessRemaining === 5) {
guesses.textContent = 'Previous guesses: ';
}
guesses.textContent += userGuess + ' ';
if (userGuess === randomNumber) {
lastResult.textContent = 'Congratulations! You got it right!';
lastResult.style.background = 'green';
gameOver();
} else if (guessRemaining < 1) {
lastResult.textContent = 'GAME OVER!';
gameOver();
} else {
lastResult.textContent = 'Wrong answer!';
lastResult.style.background = 'red';
lastResult.style.color = 'white';
if (userGuess < randomNumber) {
lowOrHigh.textContent = 'Too low!';
} else if (userGuess > randomNumber) {
lowOrHigh.textContent = 'Too high!';
}
}
guessRemaining--;
guessField.value = '';
guessField.focus();
} else {
resetGame();
}
}
function gameOver() {
guessField.disabled = true;
enterButton.setAttribute('value', 'Replay');
isRunning = false;
// enterButton.addEventListener('click', resetGame); Move this line to the beggining
}
function resetGame() {
randomNumber = Math.floor(Math.random() * 10) + 1;
lastResult.textContent = '';
guesses.textContent = '';
lowOrHigh.textContent = '';
guessField.disabled = false;
enterButton.setAttribute('value', 'Submit');
guessRemaining = 5;
isRunning = true;
}
2. Remove the resetGame callback after reseting
Here you just remove the resetGame callback after it is called. First you add the resetGame (just like you have it now) after the game is finished, but remove the checkGuess as well so it doesn't trigger your logic. Next you remove the resetGame and add the guessCheck callbacks after the resetGame is called (you can see two lines at the end of resetGame function).
let randomNumber = Math.floor(Math.random() * 10) + 1;
let guessField = document.getElementById('guessField');
let enterButton = document.getElementById('userSubmit');
let lastResult = document.querySelector('.lastResult');
let lowOrHigh = document.querySelector('.lowOrHigh');
let guesses = document.querySelector('.guesses');
let guessRemaining = 5;
enterButton.addEventListener('click', checkGuess);
function checkGuess() {
let userGuess = Number(guessField.value);
if (guessRemaining === 5) {
guesses.textContent = 'Previous guesses: ';
}
guesses.textContent += userGuess + ' ';
if (userGuess === randomNumber) {
lastResult.textContent = 'Congratulations! You got it right!';
lastResult.style.background = 'green';
gameOver();
} else if (guessRemaining < 1) {
lastResult.textContent = 'GAME OVER!';
gameOver();
} else {
lastResult.textContent = 'Wrong answer!';
lastResult.style.background = 'red';
lastResult.style.color = 'white';
if (userGuess < randomNumber) {
lowOrHigh.textContent = 'Too low!';
} else if (userGuess > randomNumber) {
lowOrHigh.textContent = 'Too high!';
}
}
guessRemaining--;
guessField.value = '';
guessField.focus();
}
function gameOver() {
guessField.disabled = true;
enterButton.setAttribute('value', 'Replay');
enterButton.removeEventListener('click', checkGuess); // Remove checkGuess and add resetGame
enterButton.addEventListener('click', resetGame);
}
function resetGame() {
randomNumber = Math.floor(Math.random() * 10) + 1;
lastResult.textContent = '';
guesses.textContent = '';
lowOrHigh.textContent = '';
guessField.disabled = false;
enterButton.setAttribute('value', 'Submit');
guessRemaining = 5;
enterButton.removeEventListener('click', resetGame); // Remove resetGame and add checkGuess
enterButton.addEventListener('click', checkGuess);
}
How about a slightly improved approach?
You define a boolean variable named gameIsOver. When the game is over, you set the value to true and when you reset, set the value to false.
Then you update your enterButton's click event listener. If game is over, you call the resetGame() function, else you call checkGuess function.
let gameIsOver = false; // keep track if the game is over, initially its false
enterButton.addEventListener("click", function (e) {
if (gameIsOver) {
resetGame();
} else {
checkGuess();
}
});
function gameOver() {
/* your existing code */
gameIsOver = true;
}
function resetGame() {
/* your existing code */
gameIsOver = false;
}

I do not know how to limit the time in between calling my function

//let screenWidth = window.screen.width;
//let screenHeight = window.screen.height;
let screenWidth = 800;
let screenHeight = 600;
let assets = {};
let frames = 60;
let score = 0;
let lives = 3;
let player;
// let enemie;
//let enemies;
let bullet;
//let bullets;
let powerup = 0;
let gameOver = true;
function drawScoreBoard() {
textSize(20);
fill('white');
text(`Score: ${score} / Lives: ${lives}`, 20, 40);
}
function preload() {
assets.player = loadImage('assets/Player.png');
assets.enemie = loadImage('assets/Enemie.png');
assets.bulletRight = loadImage('assets/Bullet_Right.png');
assets.bulletLeft = loadImage('assets/Bullet_Left.png');
assets.bulletUp = loadImage('assets/Bullet_Up.png');
assets.bulletDown = loadImage('assets/Bullet_Down.png');
}
function setup() {
bullets = createGroup();
enemies = createGroup();
assets.player.resize(30, 30);
assets.enemie.resize(30, 30);
assets.bulletRight.resize(30, 30);
assets.bulletLeft.resize(30, 30);
assets.bulletUp.resize(30, 30);
assets.bulletDown.resize(30, 30);
createCanvas(screenWidth, screenHeight);
}
function createBullet(){
let numList = [0, 90, 180, 270, 360];
let bulletDirection = [assets.bulletLeft, assets.bulletUp, assets.bulletRight, assets.bulletDown];
let randomdirection = numList[Math.floor(Math.random() * numList.length)];
let bullet = createSprite(bulletDirection[(Math.round(player.getDirection()/90))]);
enemie.centerX = random(0, screenWidth);
enemie.setSpeed(random(1,10));
enemie.setDirection(randomdirection);
enemie.setCollider("circle");
bullets.add(bullet);
}
function createPlayer(){
player = createSprite(assets.player);
player.bottom = screenHeight - 20;
player.centerX = screenWidth / 2;
}
function shoot(amountofbulletstobeshot) {
let bulletDirection = [assets.bulletLeft, assets.bulletUp, assets.bulletRight, assets.bulletDown];
let bullet = createSprite(bulletDirection[Math.abs(((Math.round(player.getDirection()/90))))]);
bullets.add(bullet);
// bullet.direction = player.direction;
bullet.centerX = player.centerX;
bullet.centerY = player.centerY;
bullet.setVelocity(11, player.getDirection());
// console.log('The players current direction right now is: ' + player.getDirection());
}
function shooting() {
if (keyIsDown(KEY.SPACE)) {
if (powerup === 1) {
shoot(3);
}
else {
shoot(1);
}
}
if (bullet) {
if (bullet.centerX[1] === screenWidth) {
bullets.remove(bullet);
}
}
}
function updateplayer() {
//movement
if (keyIsDown) {
if (keyIsDown(KEY.RIGHT_ARROW)) {
player.setVelocity(6, 0);
}
if (keyIsDown(KEY.LEFT_ARROW)) {
player.setVelocity(6, 180);
}
if (keyIsDown(KEY.UP_ARROW)) {
player.setVelocity(6, 270);
}
if (keyIsDown(KEY.DOWN_ARROW)) {
player.setVelocity(6, 90);
}
}
//dont go offscreen
if (player.left < 0) {
player.left = 0;
}
if (player.right > screenWidth) {
player.right = screenWidth;
}
if (player.top < 0) {
player.top = 0;
}
if (player.bottom > screenHeight) {
player.bottom = screenHeight;
}
enemies.overlap(player, HandlePlayerEnemieCollision);
//end up updateplayer
}
function updateEnemie() {
if (frameCount % 1 === 0) {
let directions = ["LEFT", "RIGHT", "UP", "DOWN"];
let direction = random(directions);
if (direction === "LEFT" && enemie.left > 0) {
enemie.centerX -= 5;
}
if (direction === "RIGHT" && enemie.right < screenWidth) {
enemie.centerX += 5;
}
if (direction === "UP" && enemie.top > 0) {
enemie.centerY -= 5;
}
if (direction === "DOWN" && enemie.bottom < screenHeight) {
enemie.centerY += 5;
}
}
}
function createEnemie() {
let directions = [270, 180, 0, 90];
direction = directions[(Math.floor(Math.random() * 5))];
enemies.overlap(bullets, HandleEnemieBulletCollision);
if (frameCount % 60 === 0) {
enemie = createSprite(assets.enemie);
enemie.centerX = Math.floor(Math.random() * 300) + 100;
enemie.centerY = Math.floor(Math.random() * 300) + 100;
enemie.setVelocity(Math.floor(Math.random() * 5) + 1, direction);
enemies.add(enemie);
}
}
function HandleEnemieEdgeCollision(enemie, edge) {
if (enemie.centerY === screenWidth) {
enemie.remove();
}
}
function HandleEnemieBulletCollision(enemie, bullet) {
enemie.remove();
bullet.remove();
score++;
}
function HandlePlayerEnemieCollision(player, enemie) {
enemie.remove();
player.remove();
lives--;
if (lives === 0) {
gameOver = true;
}
createPlayer();
}
/*
function updateEnemie() {
player.setVelocity(7, player.direction);
}
*/
function cheat() {
score = (score + 1000000);
lives = (lives + 1000000);
cheats = 'on';
if (cheats === 'on') {
textSize(50);
fill('yellow');
text('CHEATS ACTIVATED', 400, 300);
}
}
/*
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds) {
break;
}
}
}
*/
function drawGameOverScreen() {
background("black");
textAlign(CENTER);
fill("white");
textSize(40);
text("WELCOME", screenWidth/2, screenHeight/2);
textSize(20);
text("Press SPACE to play!", screenWidth/2, screenHeight/2 + 100);
if (keyWentDown(KEY.SPACE)){
resetGame();
gameOver = false;
}
}
function resetGame(){
score = 0;
lives = 3;
createPlayer();
}
function drawGame() {
background('lightgreen');
drawScoreBoard();
updateplayer();
drawSprites();
shooting();
// updateEnemie();
createEnemie();
}
function draw() {
if (gameOver === true) {
drawGameOverScreen();
} else {
drawGame();
}
}
There is my code, I want to add a time limit for how many seconds it takes until you can shoot again, right now you can just spam and make all of the bullets go in a straight line I need to wait before I let the player shoot again, Thanks! This will help out allot and i neede this in as few minutes as possible.
Use a flag to know when shooting is enabled and disabled. After each shot disable the ability to shoot. Then use a setTimeout to enable the shooting after a certain amount of time.
let shootingEnabled = true;
function tempDisableShooting(duration) {
shootingEnabled = false;
setTimeout(() => {
shootingEnabled = true;
}, duration);
}
function shooting() {
if (shootingEnabled && keyIsDown(KEY.SPACE)) {
if (powerup === 1) {
shoot(3);
} else {
shoot(1);
}
tempDisableShooting(1000); // Disable shooting for 1 second.
}
if (bullet) {
if (bullet.centerX[1] === screenWidth) {
bullets.remove(bullet);
}
}
}
Add property to track the disabled state of the shooting and a constant for the delay time in milliseconds.
let shootDisabled = false;
const shootDelayMS = 300;
Update your shoot function to only shoot if shootDisabled == false, update the shootDisabled to true after each shot, and to triggers a setTimeout which waits shootDelayMS milliseconds before setting shootDisabled to false again.
function shoot(amountofbulletstobeshot) {
if (shootDisabled == false) {
let bulletDirection = [assets.bulletLeft, assets.bulletUp, assets.bulletRight, assets.bulletDown];
let bullet = createSprite(bulletDirection[Math.abs(((Math.round(player.getDirection()/90))))]);
bullets.add(bullet);
bullet.centerX = player.centerX;
bullet.centerY = player.centerY;
bullet.setVelocity(11, player.getDirection());
shootDisabled = true;
setTimeout(() => shootDisabled = false, shootDelayMS );
}
}
one way is the hold the data in two variables: is_shooting, shot_reset.
if(is_shooting){
if(shot_reset>=x){ //x is frame count till able to shoot again)
shot_reset==0;
is_shooting=false;
}else{
shot_reset++
}
}

I need whole type writing text to stay on the page for a while before disappearing for the second loop

1. I need whole type writing text to stay on the display once it is completely written before the second loop. Please apply the solution on my code.
2. Secondly, in my text string when I use "b" or "strong" tags for making specific text bold, '<' sign shows in display for some milliseconds during typing, same thing happens with all other tags. I don't know what's wrong with my code.
Below is my code.
for (let i = 0; i < 10; i++) {
task(i);
}
function task(i) {
setTimeout(function() {
// Add tasks to do
var typeString = ['• I m Mr.Frits.\n• and I <b>love </b> Pakistan...:)'];
var i = 0;
var count = 0
var selectedText = '';
var text = '';
(function type() {
if (count == typeString.length) {
count = 0;
}
selectedText = typeString[count];
text = selectedText.slice(0, ++i);
document.getElementById('typing').innerHTML = text.fontsize(6);
document.getElementById('typing').style.fontFamily = "monospace";
document.getElementById("typing").style.color = "black";
document.getElementById("typing").style.fontWeight = "normal";
if (text.length === selectedText.length) {
count++;
i = 0;
}
/* SOLUTION : wait two seconds when new line */
if (typeString[0][i - 1] == '\n') {
setTimeout(type, 1000);
} else {
setTimeout(type, 100);
}
}());
}, 1000);
}
<pre id="typing"></pre>
As count is set to 1 once the length of the end of the string is reached, you can add conditional and increase the timeout if this is met:
/* SOLUTION : wait two seconds when new line */
if (typeString[0][i - 1] == '\n') {
setTimeout(type, 1000);
} else if (count === 1) {
setTimeout(type, 3000);
} else {
setTimeout(type, 100);
}
With the <br />'s, the browser doesn't register it as valid HTML until the tag is completed. So, for a second, all that's rendered is < before the rest of the tag completes and it understands what that tag is.
for (let i = 0; i < 10; i++) {
task(i);
}
function task(i) {
setTimeout(function() {
// Add tasks to do
var typeString = ['• I m Mr.Frits.\n• and I love Pakistan...:)'];
var i = 0;
var count = 0;
var selectedText = '';
var text = '';
var typing = document.getElementById('typing');
(function type() {
if (count == typeString.length) {
count = 0;
};
selectedText = typeString[count];
text = selectedText.slice(0, ++i);
typing.innerHTML = text.fontsize(6);
typing.style.fontFamily = "monospace";
typing.style.color = "black";
typing.style.fontWeight = "normal";
if (text.length === selectedText.length) {
count++;
i = 0;
}
/* SOLUTION : wait two seconds when new line */
if (typeString[0][i - 1] == '\n') {
setTimeout(type, 1000);
} else if (count === 1) {
setTimeout(type, 3000);
} else {
setTimeout(type, 100);
}
}());
}, 1000);
}
<pre id="typing"></pre>

Self-writed slider

I've got problem. I created slider in vanilla js and mix jquery a little and it's works perfectly. I have two arrows to get next or prev slide, and it's updated by setInterval. Could guess that not optimized at all.
And questions is : how can I update my controls before click without setInterval. Thanks
function initSlider(elem,controlNext,controlPrev) {
let courses = $(elem);
let minSlides = 0;
let maxSlides = 2;
let next = document.querySelector(controlNext);
let prev = document.querySelector(controlPrev);
if($(window).width() < 1100) {
minSlides = 1;
}
for(let course of courses) {
fadeOut(course);
}
for(let i = minSlides; i < maxSlides; i++) {
fadeIn(courses[i]);
}
next.addEventListener("click", () => {
if(maxSlides === courses.length || maxSlides === courses.length + 1) {
next.style.opacity = "0.24";
next.setAttribute("disable","true")
} else {
maxSlides+=2;
minSlides+=2;
for(let course of courses) {
fadeOut(course);
}
for(let i = minSlides; i < maxSlides; i++) {
fadeIn(courses[i])
}
}
})
prev.addEventListener("click", () => {
if(minSlides === 0 ) {
prev.style.opacity = "0.24";
prev.setAttribute("disable","true")
} else {
maxSlides-=2;
minSlides-=2;
for(let course of courses) {
fadeOut(course);
}
for(let i = minSlides; i < maxSlides; i++) {
fadeIn(courses[i]);
}
}
})
setInterval(() => {
if(minSlides === 0) {
next.style.opacity = "1";
next.removeAttribute("disable")
prev.style.opacity = "0.24";
prev.setAttribute("disable","true")
} else if(maxSlides === courses.length || maxSlides === courses.length + 1) {
next.style.opacity = "0.24";
next.setAttribute("disable","true")
prev.style.opacity = "1";
prev.removeAttribute("disable")
} else if(minSlides !== 0 && maxSlides !== courses){
prev.style.opacity = "1";
prev.removeAttribute("disable")
next.style.opacity = "1";
next.removeAttribute("disable")
}
}, 100);
}
p.s sry for bad eng
Assuming from your code that you want to update the buttons according to the slides display, you can put the code in your interval in a named function and call it after slides are changed.
NOTE that if there is extra code not shown here to switch slides automatically with another interval, you should also add the function call in it too:
function initSlider(elem,controlNext,controlPrev) {
let courses = $(elem);
let minSlides = 0;
let maxSlides = 2;
let next = document.querySelector(controlNext);
let prev = document.querySelector(controlPrev);
if($(window).width() < 1100) {
minSlides = 1;
}
for(let course of courses) {
fadeOut(course);
}
for(let i = minSlides; i < maxSlides; i++) {
fadeIn(courses[i]);
}
function updateButtons() {
if(minSlides === 0) {
next.style.opacity = "1";
next.removeAttribute("disable")
prev.style.opacity = "0.24";
prev.setAttribute("disable","true")
} else if(maxSlides === courses.length || maxSlides === courses.length + 1) {
next.style.opacity = "0.24";
next.setAttribute("disable","true")
prev.style.opacity = "1";
prev.removeAttribute("disable")
} else if(minSlides !== 0 && maxSlides !== courses){
prev.style.opacity = "1";
prev.removeAttribute("disable")
next.style.opacity = "1";
next.removeAttribute("disable")
}
}
next.addEventListener("click", () => {
if(maxSlides === courses.length || maxSlides === courses.length + 1) {
next.style.opacity = "0.24";
next.setAttribute("disable","true")
} else {
maxSlides+=2;
minSlides+=2;
for(let course of courses) {
fadeOut(course);
}
for(let i = minSlides; i < maxSlides; i++) {
fadeIn(courses[i])
}
}
updateButtons(); //call it at the end
});
prev.addEventListener("click", () => {
if(minSlides === 0 ) {
prev.style.opacity = "0.24";
prev.setAttribute("disable","true")
} else {
maxSlides-=2;
minSlides-=2;
for(let course of courses) {
fadeOut(course);
}
for(let i = minSlides; i < maxSlides; i++) {
fadeIn(courses[i]);
}
}
updateButtons(); //call it at the end
});
}

Change the Click Function to just Play

i have this 2 codes and want change the JS file.
Currently that's how it works:
--> the animation starts only when you click in the navigation.
I want play the animation if my site is loaded but i don't finde the function to change the code.
you can find the animation here: https://tympanus.net/Development/ShapeOverlays/index3.html
Thank you so much.
html:
<div class="animation">
<svg class="shape-overlays" viewBox="0 0 100 100" preserveAspectRatio="none">
<path class="shape-overlays__path"></path>
<path class="shape-overlays__path"></path>
<path class="shape-overlays__path"></path>
</svg>
</div>
JS-File:
setTimeout(() => document.body.classList.add('render'), 60);
class ShapeOverlays {
constructor(elm) {
this.elm = elm;
this.path = elm.querySelectorAll('path');
this.numPoints = 2;
this.duration = 600;
this.delayPointsArray = [];
this.delayPointsMax = 0;
this.delayPerPath = 200;
this.timeStart = Date.now();
this.isOpened = false;
this.isAnimating = false;
}
toggle() {
this.isAnimating = true;
for (var i = 0; i < this.numPoints; i++) {
this.delayPointsArray[i] = 0;
}
if (this.isOpened === false) {
this.open();
} else {
this.close();
}
}
open() {
this.isOpened = true;
this.elm.classList.add('is-opened');
this.timeStart = Date.now();
this.renderLoop();
}
close() {
this.isOpened = false;
this.elm.classList.remove('is-opened');
this.timeStart = Date.now();
this.renderLoop();
}
*/
updatePath(time) {
const points = [];
for (var i = 0; i < this.numPoints; i++) {
const thisEase = this.isOpened ?
(i == 1) ? ease.cubicOut : ease.cubicInOut:
(i == 1) ? ease.cubicInOut : ease.cubicOut;
points[i] = thisEase(Math.min(Math.max(time - this.delayPointsArray[i], 0) / this.duration, 1)) * 100
}
let str = '';
str += (this.isOpened) ? `M 0 0 V ${points[0]} ` : `M 0 ${points[0]} `;
for (var i = 0; i < this.numPoints - 1; i++) {
const p = (i + 1) / (this.numPoints - 1) * 100;
const cp = p - (1 / (this.numPoints - 1) * 100) / 2;
str += `C ${cp} ${points[i]} ${cp} ${points[i + 1]} ${p} ${points[i + 1]} `;
}
str += (this.isOpened) ? `V 0 H 0` : `V 100 H 0`;
return str;
}
render() {
if (this.isOpened) {
for (var i = 0; i < this.path.length; i++) {
this.path[i].setAttribute('d', this.updatePath(Date.now() - (this.timeStart + this.delayPerPath * i)));
}
} else {
for (var i = 0; i < this.path.length; i++) {
this.path[i].setAttribute('d', this.updatePath(Date.now() - (this.timeStart + this.delayPerPath * (this.path.length - i - 1))));
}
}
}
renderLoop() {
this.render();
if (Date.now() - this.timeStart < this.duration + this.delayPerPath * (this.path.length - 1) + this.delayPointsMax) {
requestAnimationFrame(() => {
this.renderLoop();
});
}
else {
this.isAnimating = false;
}
}
}
Well, you missed last part
(function() {
const elmHamburger = document.querySelector('.hamburger');
const gNavItems = document.querySelectorAll('.global-menu__item');
const elmOverlay = document.querySelector('.shape-overlays');
const overlay = new ShapeOverlays(elmOverlay);
elmHamburger.addEventListener('click', () => {
if (overlay.isAnimating) {
return false;
}
overlay.toggle();
if (overlay.isOpened === true) {
elmHamburger.classList.add('is-opened-navi');
for (var i = 0; i < gNavItems.length; i++) {
gNavItems[i].classList.add('is-opened');
}
} else {
elmHamburger.classList.remove('is-opened-navi');
for (var i = 0; i < gNavItems.length; i++) {
gNavItems[i].classList.remove('is-opened');
}
}
});
}());
There is event listener click attached to button elmHamburger, That is executing anonymous arrow function. If you want to run that animation on load, you need to replace click event with load.
That is:
elmHamburger.addEventListener('click', () => {...};
with
window.document.addEventListener('load', () => {...};
If you want to start animation on load and keep button event, then
(function() {
const elmHamburger = document.querySelector('.hamburger');
const gNavItems = document.querySelectorAll('.global-menu__item');
const elmOverlay = document.querySelector('.shape-overlays');
const overlay = new ShapeOverlays(elmOverlay);
const func = () => {
if (overlay.isAnimating) {
return false;
}
overlay.toggle();
if (overlay.isOpened === true) {
elmHamburger.classList.add('is-opened-navi');
for (var i = 0; i < gNavItems.length; i++) {
gNavItems[i].classList.add('is-opened');
}
} else {
elmHamburger.classList.remove('is-opened-navi');
for (var i = 0; i < gNavItems.length; i++) {
gNavItems[i].classList.remove('is-opened');
}
}
}
elmHamburger.addEventListener('click', func);
window.addEventListener('load', func);
}());

Categories