How to get width from animated div in jQuery - javascript

Thanks in advance for your support here. I have a simple code here but I wonder why it doesn't work.
This code below was put into a variable "percent"
var percent = $('#div').animate({width:80 + '%'},1000);
and I want to use the variable to become a text or content to a specific div. I tried to do it this way, however it doesn't work.
$('#val').text(percent); or $('#val').html(percent);
I tried to use the parseInt() function from JavaScript, but it doesn't work as well.
$('#web-design').text(parseInt(percent));
Do you have any suggestions or is this possible?

I am not sure if the line code it is correct
var percent = $('#div').animate({width:80 + '%'},1000);
To find the with property for #div I will do something like this
$('#val').text($("#div").css("width"))
or
$('#val').text($("#div").width())

The animate function does not return the changes to the element. To get the width you will have to use .width() but you will get it in pixel and not percentage.
var width = $('#div').width();

You can try this code:
$('#div1').animate({width:80 + '%'},{
duration:1000,
easing:'swing',
step: function() { // called on every step
$('#div1').text(Math.ceil($('#div1').width()/$('#div1').parent().width()*100) + "%");
}
});
This will print the Div-Width % as text in Div at every step of update.

You code is going to animate to 80% width in 1 second (1000 ms). You can increase the percentage width by 1% each iteration and update your #val at the same time until you hit 80. Below is the example based on 10000ms (10 secs), you can change the starting parameters such as duration, endWidth, startWidth to suit.
Demo: http://jsfiddle.net/zthaucda/
HTML:
<div class="my-anim-div"></div>
<button class="start-animating">Start animation</button>
<div id="val">Width will display here</div>
CSS:
.my-anim-div {
width:0%;
height:200px;
background-color:red;
}
Javascript including jQuery library:
var duration = 10000;
var endWidth = 80;
var startWidth = 0;
$('.start-animating').on('click', function () {
// work out the interval to make the animation in `duration`
var interval = duration / (endWidth - startWidth);
console.log(interval);
var myInterval = setInterval(function () {
// Increment the startWidth and update the width of the div and the display
startWidth++
// update div width
$('.my-anim-div').animate({
'width': startWidth + '%'
}, interval);
// update display
$('#val').text(startWidth + '%');
if (startWidth == 80) {
// then exit the interval
clearInterval(myInterval);
}
}, interval);
});

If you mean you want to get the current width of the div you can use clientWidth property:
$('#div')[0].clientWidth

Related

Decrease image size automatically over a certain amount of time

I am looking for a script but I'm not sure what to look for.
I have a webpage that has the body tag with a background image.
body {
background: url(eye.gif)repeat;
background-size:91px 91px;
}
What I am hoping to achieve is when the page loads it shows the background image as 991px then slowly decrease by 10px over a set time until the original size of 91px.
I'm not sure if there is away to do this, or even another way that when the page is loaded it is zoomed in and then zooms out automatically over time.
Basically when the page is loaded you will see the image twice and then over time you will see more and more.
Can anyone point me in the right direction.
if you use background-size your using css3 and so you can use keyframes
no javascript needed.
#-webkit-keyframes bganimation{
0%{background-size:991px 991px;}
100%{background-size:91px 91px;}
}
body{
background: url(eye.gif)repeat;
background-size:91px 91px;
-webkit-animation:bganimation 20s linear; // 20s = 20 seconds
}
for more support you need to add the other specific prefixes (-moz,-ms..)
Here is a sample using JQuery:
http://jsfiddle.net/frUvf/16/
$(document).ready(function(){
$('body').animate({'background-size':'10000px'}, 50000);
})
Using vanilla JS:
var lowerBound = 250,
step = 10,
duration = 1000,
image = document.getElementById('image');
(function resizer () {
if (image.clientWidth > lowerBound) {
image.style.width = image.clientWidth - step + 'px';
var timer = setTimeout(resizer, duration);
} else {
clearTimeout(timer);
}
}());
Just change the lowerBound/step/duration variables to whatever you need them to be.
Fiddle
with jquery:
var body = $('body');
var zoom = 2;
var interval_zoom = 0.5;
var time_interval = 90000;
setInterval(function(){
body.css("zoom", zoom);
zoom = zoom - interval_zoom;
if(zoom<=1)
clearTimeout(this);
}, time_interval )
Zoom and interval must be calculated
You could use Javascript for the animation or could take a look at CSS3 Transformations: http://web.archive.org/web/20180414114433/http://www.pepe-juergens.de/2013/02/css3-transform/

Synchronized scrolling using jQuery?

I am trying to implement synchronized scrolling for two DIV with the following code.
DEMO
$(document).ready(function() {
$("#div1").scroll(function () {
$("#div2").scrollTop($("#div1").scrollTop());
});
$("#div2").scroll(function () {
$("#div1").scrollTop($("#div2").scrollTop());
});
});
#div1 and #div2 is having the very same content but different sizes, say
#div1 {
height : 800px;
width: 600px;
}
#div1 {
height : 400px;
width: 200px;
}
With this code, I am facing two issues.
1) Scrolling is not well synchronized, since the divs are of different sizes. I know, this is because, I am directly setting the scrollTop value. I need to find the percentage of scrolled content and calculate corresponding scrollTop value for the other div. I am not sure, how to find the actual height and current scroll position.
2) This issue is only found in firefox. In firefox, scrolling is not smooth as in other browsers. I think this because the above code is creating a infinite loop of scroll events.
I am not sure, why this is only happening with firefox. Is there any way to find the source of scroll event, so that I can resolve this issue.
Any help would be greatly appreciated.
You can use element.scrollTop / (element.scrollHeight - element.offsetHeight) to get the percentage (it'll be a value between 0 and 1). So you can multiply the other element's (.scrollHeight - .offsetHeight) by this value for proportional scrolling.
To avoid triggering the listeners in a loop you could temporarily unbind the listener, set the scrollTop and rebind again.
var $divs = $('#div1, #div2');
var sync = function(e){
var $other = $divs.not(this).off('scroll'), other = $other.get(0);
var percentage = this.scrollTop / (this.scrollHeight - this.offsetHeight);
other.scrollTop = percentage * (other.scrollHeight - other.offsetHeight);
// Firefox workaround. Rebinding without delay isn't enough.
setTimeout( function(){ $other.on('scroll', sync ); },10);
}
$divs.on( 'scroll', sync);
http://jsfiddle.net/b75KZ/5/
Runs like clockwork (see DEMO)
$(document).ready(function(){
var master = "div1"; // this is id div
var slave = "div2"; // this is other id div
var master_tmp;
var slave_tmp;
var timer;
var sync = function ()
{
if($(this).attr('id') == slave)
{
master_tmp = master;
slave_tmp = slave;
master = slave;
slave = master_tmp;
}
$("#" + slave).unbind("scroll");
var percentage = this.scrollTop / (this.scrollHeight - this.offsetHeight);
var x = percentage * ($("#" + slave).get(0).scrollHeight - $("#" + slave).get(0).offsetHeight);
$("#" + slave).scrollTop(x);
if(typeof(timer) !== 'undefind')
clearTimeout(timer);
timer = setTimeout(function(){ $("#" + slave).scroll(sync) }, 200)
}
$('#' + master + ', #' + slave).scroll(sync);
});
This is what I'm using. Just call the syncScroll(...) function with the two elements you want to synchronize. I found pawel's solution had issues with continuing to slowly scroll after the mouse or trackpad was actually done with the operation.
See working example here.
// Sync up our elements.
syncScroll($('.scroll-elem-1'), $('.scroll-elem-2'));
/***
* Synchronize Scroll
* Synchronizes the vertical scrolling of two elements.
* The elements can have different content heights.
*
* #param $el1 {Object}
* Native DOM element or jQuery selector.
* First element to sync.
* #param $el2 {Object}
* Native DOM element or jQuery selector.
* Second element to sync.
*/
function syncScroll(el1, el2) {
var $el1 = $(el1);
var $el2 = $(el2);
// Lets us know when a scroll is organic
// or forced from the synced element.
var forcedScroll = false;
// Catch our elements' scroll events and
// syncronize the related element.
$el1.scroll(function() { performScroll($el1, $el2); });
$el2.scroll(function() { performScroll($el2, $el1); });
// Perform the scroll of the synced element
// based on the scrolled element.
function performScroll($scrolled, $toScroll) {
if (forcedScroll) return (forcedScroll = false);
var percent = ($scrolled.scrollTop() /
($scrolled[0].scrollHeight - $scrolled.outerHeight())) * 100;
setScrollTopFromPercent($toScroll, percent);
}
// Scroll to a position in the given
// element based on a percent.
function setScrollTopFromPercent($el, percent) {
var scrollTopPos = (percent / 100) *
($el[0].scrollHeight - $el.outerHeight());
forcedScroll = true;
$el.scrollTop(scrollTopPos);
}
}
If the divs are of equal sizes then this code below is a simple way to scroll them synchronously:
scroll_all_blocks: function(e) {
var scrollLeft = $(e.target)[0].scrollLeft;
var len = $('.scroll_class').length;
for (var i = 0; i < len; i++)
{
$('.scroll_class')[i].scrollLeft = scrollLeft;
}
}
Here im using horizontal scroll, but you can use scrollTop here instead. This function is call on scroll event on the div, so the e will have access to the event object.
Secondly, you can simply have the ratio of corresponding sizes of the divs calculated to apply in this line $('.scroll_class')[i].scrollLeft = scrollLeft;
I solved the sync scrolling loop problem by setting the scroll percentage to fixed-point notation: percent.toFixed(0), with 0 as the parameter. This prevents mismatched fractional scrolling heights between the two synced elements, which are constantly trying to "catch up" with each other. This code will let them catch up after at most a single extra step (i.e., the second element may continue to scroll an extra pixel after the user stops scrolling). Not a perfect solution or the most sophisticated, but certainly the simplest I could find.
var left = document.getElementById('left');
var right = document.getElementById('right');
var el2;
var percentage = function(el) { return (el.scrollTop / (el.scrollHeight - el.offsetHeight)) };
function syncScroll(el1) {
el1.getAttribute('id') === 'left' ? el2 = right : el2 = left;
el2.scrollTo( 0, (percentage(el1) * (el2.scrollHeight - el2.offsetHeight)).toFixed(0) ); // toFixed(0) prevents scrolling feedback loop
}
document.getElementById('left').addEventListener('scroll',function() {
syncScroll(this);
});
document.getElementById('right').addEventListener('scroll',function() {
syncScroll(this);
});
I like pawel's clean solution but it lacks something I need and has a strange scrolling bug where it continues to scroll and my plugin will work on multiple containers not just two.
http://www.xtf.dk/2015/12/jquery-plugin-synchronize-scroll.html
Example & demo: http://trunk.xtf.dk/Project/ScrollSync/
Plugin: http://trunk.xtf.dk/Project/ScrollSync/jquery.scrollSync.js
$('.scrollable').scrollSync();
If you don't want proportional scrolling, but rather to scroll an equal amount of pixels on each field, you could add the value of change to the current value of the field you're binding the scroll-event to.
Let's say that #left is the small field, and #right is the bigger field.
var oldRst = 0;
$('#right').on('scroll', function () {
l = $('#left');
var lst = l.scrollTop();
var rst = $(this).scrollTop();
l.scrollTop(lst+(rst-oldRst)); // <-- like this
oldRst = rst;
});
https://jsfiddle.net/vuvgc0a8/1/
By adding the value of change, and not just setting it equal to #right's scrollTop(), you can scroll up or down in the small field, regardless of its scrollTop() being less than the bigger field. An example of this is a user page on Facebook.
This is what I needed when I came here, so I thought I'd share.
From the pawel solution (first answer).
For the horizzontal synchronized scrolling using jQuery this is the solution:
var $divs = $('#div1, #div2'); //only 2 divs
var sync = function(e){
var $other = $divs.not(this).off('scroll');
var other = $other.get(0);
var percentage = this.scrollLeft / (this.scrollWidth - this.offsetWidth);
other.scrollLeft = percentage * (other.scrollWidth - other.offsetWidth);
setTimeout( function(){ $other.on('scroll', sync ); },10);
}
$divs.on('scroll', sync);
JSFiddle
An other solution for multiple horizontally synchronized divs is this, but it works for divs with same width.
var $divs = $('#div1, #div2, #div3'); //multiple divs
var sync = function (e) {
var me = $(this);
var $other = $divs.not(me).off('scroll');
$divs.not(me).each(function (index) {
$(this).scrollLeft(me.scrollLeft());
});
setTimeout(function () {
$other.on('scroll', sync);
}, 10);
}
$divs.on('scroll', sync);
NB: Only for divs with same width
JSFiddle

Javascript: Controlling an image's moving speed

I'm a beginner and currently I can move an image from left to right and I can turn it back to its initial point when moving finishes. What I want to do is also controlling image's speed. In order to do this I tried the codes below:
<script type="text/javascript">
var userWidth = window.screen.width;
function moveRight(speed) {
var pp = document.getElementById("myimage");
var lft = parseInt(pp.style.left);
var tim = setTimeout("moveRight()", speed);
lft = lft + 50;
pp.style.left = lft + "px"
if (lft > (userWidth) + 80) {
document.getElementById("myimage").style.left = 100 + "px";
clearTimeout(tim);
}
}
</script>
And html:
<form>
<input type="button" value="Speed 1" onclick="moveRight(50)" />
<input type="button" value="Speed 2" onclick="moveRight(25)" />
<input type="button" value="Speed 3" onclick="moveRight(10)" />
</form>
My problem: there is no difference when I click any of three buttons. Image is always moving with the same speed and looks like buttons have no control on the speed.
The mistake you did in your orignal code is that when you call the function again you do not pass it the value of speed which means that the only thing that happens is that the first animation is delayed.
Try replacing the call with this line and then your code should work.
var tim = setTimeout("moveRight("+speed+")", speed);
With this you can still do this without using Jquery
Your above code doesn't have any speed logic. The only thing you're doing is delaying the time before the animation start :
var tim = setTimeout("moveRight()", speed);
Making a recursive call to a function waiting for an attribute (speed), is also a nogo.
I setted up a quick fiddle to demonstrate jquery animation speed :
http://jsfiddle.net/yeQtB/
To achieve speed in animation, two possibilities :
• Cycle logic :
You admit that rather than seconds, you can work with cycles, then just create a for loop, that will iterate until animation is over. edit : this is just here for the sake of the explanation
• Time logic
You have a distance and a timeframe (in sec), divide the distance by the timeframe, it gives you step, divide the distance by the step, it will give you the number of steps, then it is just a matter of creating a settimeout firing every second in a loop. edit : if you achieved this and is eager to go for something a bit smoother, i'd advise to have a look at the requestAnimationFrame HTML5 Api :
http://paulirish.com/2011/requestanimationframe-for-smart-animating/
You have to pass the variable speed to moveRight in the setTimeout :
var userWidth = window.screen.width,
tim,
pp = document.getElementById("myimage"); // You should cache your variables
function moveRight(speed) {
var lft = parseInt(pp.style.left) || 0;
tim = setTimeout("moveRight(" + speed + ")"); // Here you have to pass speed as a parameter
lft = lft + speed; // Here I guess it is speed rather than 50
pp.style.left = lft + "px"
if (lft > (userWidth) + 80) {
pp.style.left = 100 + "px";
clearTimeout(tim);
}
}

How to change the left attribute on page resize (jQuery)

I'm having slight troubles with my code. What I'm trying to do is make these element's css property 'left' update according to the difference of it's current left value, and the amount the page resizes. This way, when the page resizes and the background moves over, the elements will move too. Take a look at the code below and I'll describe the issue:
$(window).resize(function() {
var docWidth = $(window).width();
if (docWidth < 1000) {
var difference = 1000-docWidth;
$('#headNav a,#icons div').each(function() {
var left = $(this).position().left;
var newLeft = left - difference;
$(this).css({ 'left' : newLeft });
});
}
});
So the issue that I'm getting is the elements are being given left values of wild numbers, while the value of the variable 'newLeft' is the reasonable, desired value. The each function I think is collecting the sums of these values and running them for each element x amount of times that the elements found exist (so if there's 5 elements it runs 5 times, I mean.) What I want is this code to execute uniquely for each element, but just once each, not each element 10 times! (that's how many elements are in the html).
So my question is, how can this be achieved? I hope I explained myself well enough, this was tough to iterate. Any help is extremely appreciated. Thank you!
Here's a fun trick: Include += in your .css() call:
$(this).css({left: "+=" + difference});
jQuery does the math for you to get the new value.
Try this:
$(window).resize(function() {
var docWidth = $(window).width();
if (docWidth < 1000) {
var difference = 1000-docWidth;
$('#headNav a,#icons div').each(function(iconInst) {
var left = $("#" + iconInst).position().left;
var newLeft = left - difference;
$("#" + iconInst).css({ 'left' : newLeft });
});
}
});

How to show animated image from PNG image using javascript? [ like gmail ]

First of all,check out this image
Gmail uses this image to display the animated emoticon.
How can we show such animation using a png image?
I leave you a rough example so you can get a starting point:
I will use a simple div element, with the width and height that the animated image will have, the png sprite as background-image and background-repeat set to no-repeat
CSS Needed:
#anim {
width: 14px; height: 14px;
background-image: url(https://ssl.gstatic.com/ui/v1/icons/mail/im/emotisprites/wink2.png);
background-repeat: no-repeat;
}
Markup needed:
<div id="anim"></div>
The trick is basically to scroll the background image sprite up, using the background-position CSS property.
We need to know the height of the animated image (to know how much we will scroll up each time) and how many times to scroll (how many frames will have the animation).
JavaScript implementation:
var scrollUp = (function () {
var timerId; // stored timer in case you want to use clearInterval later
return function (height, times, element) {
var i = 0; // a simple counter
timerId = setInterval(function () {
if (i > times) // if the last frame is reached, set counter to zero
i = 0;
element.style.backgroundPosition = "0px -" + i * height + 'px'; //scroll up
i++;
}, 100); // every 100 milliseconds
};
})();
// start animation:
scrollUp(14, 42, document.getElementById('anim'))
EDIT: You can also set the CSS properties programmatically so you don't have to define any style on your page, and make a constructor function from the above example, that will allow you to show multiple sprite animations simultaneously:
Usage:
var wink = new SpriteAnim({
width: 14,
height: 14,
frames: 42,
sprite: "https://ssl.gstatic.com/ui/v1/icons/mail/im/emotisprites/wink2.png",
elementId : "anim1"
});
var monkey = new SpriteAnim({
width: 18,
height: 14,
frames: 90,
sprite: "https://ssl.gstatic.com/ui/v1/icons/mail/im/emotisprites/monkey1.png",
elementId : "anim4"
});
Implementation:
function SpriteAnim (options) {
var timerId, i = 0,
element = document.getElementById(options.elementId);
element.style.width = options.width + "px";
element.style.height = options.height + "px";
element.style.backgroundRepeat = "no-repeat";
element.style.backgroundImage = "url(" + options.sprite + ")";
timerId = setInterval(function () {
if (i >= options.frames) {
i = 0;
}
element.style.backgroundPosition = "0px -" + i * options.height + "px";
i++;
}, 100);
this.stopAnimation = function () {
clearInterval(timerId);
};
}
Notice that I added a stopAnimation method, so you can later stop a specified animation just by calling it, for example:
monkey.stopAnimation();
Check the above example here.
Take a look at this:
http://www.otanistudio.com/swt/sprite_explosions/
and http://www.alistapart.com/articles/sprites
The answer lies within.
CMS's answer is fine, but there's also the APNG (animated PNG) format that you may want to use instead. Of course the first frame (the one displayed even by browsers that don't support APNG) should be the "ending" frame and just specify to skip the first frame in the file.
Set the background image of an element to the first image, then use javascript to change the image by altering the style every x milliseconds.
You can do it with TweenMax and steppedEase easing : http://codepen.io/burnandbass/pen/FfeAa or http://codepen.io/burnandbass/pen/qAhpj whatever you choose :)
CSS #keyframes can be used in this case
#keyframes smile {
0% { background-postiion: 0 -16px;}
5% { background-postiion: 0 -32px;}
10% { background-postiion: 0 -48px;}
/*...etc*/
}

Categories

Resources