Flickering when the dynamic change width - javascript

I want to dynamically change the width of an element. I've got working code, but it's sometimes flickering. Any idea, why?
JS:
var counter = 0;
setInterval(function() {
counter = (counter + 1) % 100;
$(".xxx").css("width", counter + "%");
}, 40);
CSS:
.xxx {
max-width: 70px;
height: 3px;
width: 0%;
background-color: orange;
}

That is how it is going to look if you try to increment 1% at a time. Rather use jquery animate to get better transition
DEMO: http://plnkr.co/edit/8OsVuRJGCLQsJWfrlzJ4
var counter =0;
setInterval(function() {
counter = (counter + 1) % 100;
$(".xxx").animate({width:counter+'px'});
}, 40);

If you want to reach a 70px width when it gets to 100%, you need to add a div parent to .xxx
like this:
<div class="yyy">
<div class="xxx"></div>
</div>
<p id="text"></p>
css:
.xxx{
height: 3px;
width: 0%;
background-color: orange;
}
.yyy{
width: 70px;
}

Related

How to increase width and height on click of a button

I need to increase height actually to increase bottom and top of div each for 25px also left and right side each for 25px.I don't now is that even possible.
So this is just example but it is similar to my code:
function increaseDiv() {
var myDiv = document.querySelector(".box")
var currWidth = myDiv.clientWidth;
myDiv.style.width = currWidth + 100 + "px";
}
.box {
width: 300px;
height: 200px;
position: absolute;
left: 100px;
background: black;
}
<div class="box"></div>
<button onclick="increaseDiv()">Click</button>
Here is demo https://jsfiddle.net/SutonJ/0pdwm39a/14/
The problem is that position of your div are related to left side and this is why it looks like you increase only the right side; try to add positioning with transform by center or make it by flex(align-items + justify-content)
.box {
width: 300px;
height: 200px;
left: 50%;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
background: black;
}
If I am understanding you correctly, I think if you changed
var currWidth = myDiv.clientWidth;
myDiv.style.width = currWidth + 100 + "px";
to
var currWidth = myDiv.getBoundingClientRect().width;
myDiv.style.width = currWidth + 50 + "px";
and also added
var currHeight = myDiv.getBoundingClientRect().height;
myDiv.style.height = currHeight + 50 + "px";
I also noticed that your div is using absolute positioning, so you may also need to offset the left and top according to the size change. If you are getting an issue with the actual position when the size changes let me know.
What about CSS scale?
That will keep the actual position of the element and expand it in all directions, unless you specify a transform-origin value.
Edited with an ever growing effect...
let myDiv = document.querySelector(".box");
let orgiSize = myDiv.getBoundingClientRect().width;
let increments = 0;
function increaseDiv() {
increments += 50; // That is 25px on both sides...
// Make the math here
var percentage = Math.floor((orgiSize + increments) / orgiSize * 100) / 100
console.log(percentage);
myDiv.style.transform = `scale(${percentage})`; // That is a percentage value
}
.box {
width: 300px;
height: 200px;
position: absolute;
left: 100px;
background: black;
}
/* for the demo */
button {
position: absolute;
z-index: 9999;
}
<div class="box"></div>
<button onclick="increaseDiv()">Click</button>

use jQuery setInterval to decreases the width of element but from only one side (left or right )

here are my codes for decreasing the width of an selected element(class = "life_bar"), but as my attached pictures show, I want it to decrease its width from left or right( let's do left as example), but it always goes from both side, what should I do?
here are jQuery codes
$(function () {
var timmer;
gocount();
function gocount(){
timmer = setInterval(function () {
var life_bar_width = $(".life_bar").width();
life_bar_width -= 100;
$(".life_bar").css( {width: life_bar_width,
left: '-50px'})
},1000);
}
});
here are css codes
.life_bar{
width: 500px;
height: 10px;
background: crimson;
margin: 100px auto;
}
here are html codes
<body>
<div class="life_bar"></div>
</body>
using translate negative on X every interval tick:
$(function () {
var timmer;
gocount();
let counter = 1
function gocount(){
timmer = setInterval(function () {
var life_bar_width = $(".life_bar").width();
life_bar_width -= 100;
$(".life_bar").css({
width: life_bar_width,
left: '-50px',
transform: `translate(${-50*counter}px)`
})
counter++
},1000);
}
});
.life_bar{
width: 500px;
height: 10px;
background: crimson;
margin: 100px auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="life_bar"></div>

animated loads in wrong spot

I have a div that animates up and down which works fine. The issue I'm getting is that every time the page loads the div starts at the very top of the page and then jumps down to where it needs to be after the animation starts.
<body id="body">
<div id="square"></div>
</body>
#body {
background: #000;
}
#square {
background-color: #fff;
margin: 0 auto;
position: relative;
width: 100px;
height: 100px;
}
var box = document.getElementById('square');
TOP = (window.innerHeight - box.offsetHeight)/2;
box.style.top = TOP;
var down = setInterval(animateDown, 15);
var up;
function animateDown()
{
TOP += 3;
box.style.top = TOP + 'px';
if(TOP > 900){
clearInterval(down);
up = setInterval(animateUp, 15);
}
}
function animateUp()
{
TOP -= 3;
box.style.top = TOP + 'px';
if(TOP <= (window.innerHeight - box.offsetHeight)/2){
clearInterval(up);
down = setInterval(animateDown, 15);
}
}
Here is a link to the jsfiddle as well >> https://jsfiddle.net/xgilmore/pLbgvc3L/
thanks in advance
This is sort of a work around, but you can start the box off as hidden, and then once you start animating, set it visible. https://jsfiddle.net/pLbgvc3L/1/
function animateDown()
{
box.style.visibility = 'visible';
#square {
background-color: #fff;
//margin: 0 auto;
position: relative;
width: 100px;
height: 100px;
top: 20%;
visibility: hidden;
}
Oh sorry, I actually know what is going on, it just took a second look to figure it out. top: 20% doesn't do anything because percentages only work if the parent element (body) has an explicit height. Like so https://jsfiddle.net/pLbgvc3L/2/

How make a fade slideshow loop?

I am using javascript to change my css class background image every few seconds. It is working great the problem is it just stops after it shows the last image. Can anyone show me what to add to this code so that it will continuously loop itself?
$(window).load(function() {
$(document).ready(function() {
setInterval(fadeDivs, 5000); //call it every 2 seconds
function fadeDivs() {
var visibleDiv = $('.bckgnd:visible:first'); //find first visible div
visibleDiv.fadeOut(400, function() { //fade out first visible div
var allDivs = visibleDiv.parent().children(); //all divs to fade out / in
var nextDivIndex = (allDivs.index(visibleDiv) + 1) % allDivs.length; //index of next div that comes after visible div
var nextdiv = allDivs.eq(nextDivIndex); //find the next visible div
var lastDiv = $('.backgnd3');
var firstDiv = $('.backgnd1');
if (currentDiv != lastDiv) {
var nextdiv = allDivs.eq(nextDivIndex); //find the next visible div
} else {
var nextdiv = firstDiv; //the next div will be the first div, resulting in a loop
}
nextdiv.fadeIn(400); //fade it in
});
};
});
});
.backgnd1 {
width: 100%;
height: 452px;
background: url ('http://quaaoutlodge.com/sites/all/themes/marinelli/img/backgrounds/backgnd1.jpg');
background-size: cover;
background-repeat: no-repeat;
background-color: #000;
}
.backgnd2 {
width: 100%;
height: 452px;
background-image: url ('http://quaaoutlodge.com/sites/all/themes/marinelli/img/backgrounds/the_lodge.jpg');
background-size: cover;
background-repeat: no-repeat;
background-color: #000;
}
.backgnd3 {
width: 100%;
height: 452px;
background-image: url('http://quaaoutlodge.com/sites/all/themes/marinelli/img/backgrounds/getting_here.jpg');
background-size: cover;
background-repeat: no-repeat;
background-color: #000;
}
.index_roof_background {
background-color: #000;
width: 1600px;
height: 452px;
margin: 0px;
padding-top: 0px;
margin-left: auto;
margin-right: auto;
}
<div class="index_roof_background">
<div style="position:absolute; z-index: 2;display:block; background-color:#000;" class="bckgnd backgnd1"></div>
<div style="position:absolute; z-index: 2;display:none; background-color:#000;" class="bckgnd backgnd2"></div>
<div style="position:absolute; z-index: 2;display:none; background-color:#000;" class="bckgnd backgnd3"></div>
</div>
A better approach:
You don't need all those backgnd2 classes since you have only those DIVs inside a common parent.
Don't use inline styles! Use your stylesheet.
Don't use fixed width (px). Use % for responsive design.
2000*1331px images are
not suited for the web. Specially not for mobile devices. Care about
your user's bandwidth. When setting a background-image to cover you
don't need to worry about it being repeated.
Make your JS more flexible to element's indexes, count your elements using length.
Create a "current index counter", iterate over it increment it and
resetting using % (reminder).
For a better UX, allow the user to pause on hover.
Here's an eample:
jQuery(function($) { // DOM ready. $ alias in scope.
$('.gallery').each(function() {
var $gal = $(this),
$sli = $gal.find(">*"),
tot = $sli.length,
c = 0,
itv = null;
$sli.hide().eq(c).show(); // Hide all but first slide
function anim() {
c = ++c % tot; // increment/reset counter
$sli.fadeOut().eq(c).stop().fadeIn();
}
function play() {
itv = setInterval(anim, 3000);
}
function pause() {
clearInterval(itv);
}
$gal.hover(pause, play); // Pause on hover
play(); // Start loop
});
});
.gallery {
position: relative;
height: 200px;
}
.gallery>* {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: none 50%;
background-size: cover;
}
<div class="gallery">
<div style="background-image:url(http://placehold.it/800x600/0bf?text=1)"></div>
<div style="background-image:url(http://placehold.it/800x600/f0b?text=2)"></div>
<div style="background-image:url(http://placehold.it/800x600/0fb?text=3)"></div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
First put the firstDiv, lastDiv in their own variables.
Then you will need something like this
if (currentDiv != lastDiv) {
var nextdiv = allDivs.eq(nextDivIndex); //find the next visible div
} else {
var nextdiv = firstDiv; //the next div will be the first div, resulting in a loop
}
nextdiv.fadeIn(400); //fade it in
Tell me if you need more help.
You need to use 2 timeouts to make it loop. A timeout only fires once. The FadeOutDivs function counts down, each time setting a timeout to call itself. Then at zero it fades sets a timeout the call fadeInDivs which start the whole cycle over.
I've got this running on codepen.
$(document).ready(function () {
var interval = 2000;
var fadeDuration = 400;
var allImages = $('.bckgnd');
var count = allImages.length - 1;
var imageCount = allImages.length;
setTimeout(fadeOutDivs, interval);
function fadeOutDivs() {
allImages.eq(count).fadeOut(fadeDuration);
console.log(count);
if (count > 1) {
count--;
setTimeout(fadeOutDivs, interval);
} else {
count = allImages.length - 1;
setTimeout(fadeInDivs, interval)
}
}
function fadeInDivs() {
allImages.fadeIn(fadeDuration);
setTimeout(fadeOutDivs, interval);
}
});

Doing a roll-in/roll-out slideshow in jQuery

I am trying to create a roll-in / roll-out slideshow in jQuery/JavaScript.
My problem is, that it needs to be repeated. And right now when it's starting over, the pictures doesnt come from the right side anymore :(
The reason for which I have created the slideLeft function, is that afterwards I need to create 2 functions, where the user can interrupt the slideshow manually pressing a left or right button.
This is what I've got:
<script class="jsbin" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<div style='background: #c4c4c4; border: 1px solid #7b7b7b; height: 220px; overflow: hidden; padding: 5px; position: absolute; width: 590px;'>
<div id='slider-image-1' style='left: 5px; background: red; height: 216px; padding: 2px; position: absolute; top: 5px; width: 586px;'></div>
<div id='slider-image-2' style='left: 600px; background: yellow; height: 216px; padding: 2px; position: absolute; top: 5px; width: 586px;'></div>
<div id='slider-image-3' style='left: 600px; background: green; height: 216px; padding: 2px; position: absolute; top: 5px; width: 586px;'></div>
<div id='slider-image-4' style='left: 600px; background: blue; height: 216px; padding: 2px; position: absolute; top: 5px; width: 586px;'></div>
</div>
<script type='text/javascript'>
$(document).ready(function() {
var amount = 0;
var nextamount = 1;
setInterval(function() {
amount++;
nextamount++;
if (nextamount === 5) nextamount = 1;
if (amount === 5) amount = 1;
slideLeft(amount, nextamount);
}, 2000);
});
function slideLeft(i, j) {
var $theItem = $('#slider-image-' + i);
$theItem.animate({
left: parseInt($theItem.css('left'), 10) == 5 ? -$theItem.outerWidth() : 5
}, 500);
var $theItem = $('#slider-image-' + j);
$theItem.animate({
left: parseInt($theItem.css('left'), 10) == 5 ? $theItem.outerWidth() + 10 : 5
}, 500);
};
</script>
You need to prepare element, which is going to roll in, to be on the right.
function slideLeft(i, j) {
var $theItem = $('#slider-image-' + i);
$theItem.animate({
left: parseInt($theItem.css('left'), 10) == 5 ? -$theItem.outerWidth() : 5
}, 500);
var $theItem = $('#slider-image-' + j);
$theItem.css('left', '600px'); // moves in item to the right before animation
$theItem.animate({
left: parseInt($theItem.css('left'), 10) == 5 ? $theItem.outerWidth() + 10 : 5
}, 500);
};
I think you've tried it with your parseInt, but it doesn't work, so you can get rid of it.
function slideLeft(i, j) {
var $outItem = $('#slider-image-' + i);
$outItem.animate({ left: -$outItem.outerWidth() }, 500);
var $inItem = $('#slider-image-' + j);
$inItem.css('left', '600px');
$inItem.animate({ left: 5 }, 500);
}
I have made something like this before, i dont know if this will help you, what i did was:
Add a copy of the first slide in the end of the collection of images/slides. Then, when you are showing the last "real" image and it will look like you are scrolling to the first image (but that is just a copy of the first image), and then when the animation is done you can position it with the default "left" css value. If you want it to scroll both ways, you can do the same with a copy of the last image/slide before the first image, but then you'll have to start the slider with a offset.
its a bit hard to explain, do you get the point? :)

Categories

Resources