How to reset to original values? - javascript

It looks like it keeps adding a new newHeight and a newDistance each time i click, I am trying to save original height with a global var at the top and using data to do that but i get weird results, basically i should be able to reset newDistance and newHeight to first original values as per before to run the lot with a click but it doesn't and i get new added values each time i click breaking my layout as a result:
talents = $(".talenti");
filter = $(".filtra");
genHeight = $("#container").data($("#container").height());
filter.click(function(e) {
e.preventDefault();
if (talents.hasClass("opened")) {
$(".nasco").slideToggle();
$("#wrapNav").slideToggle("10", "linear");
talents.removeClass('opened');
filter.addClass('opened');
$("#container").css("height", genHeight);
} else {
filter.addClass('opened');
};
if (filter.hasClass("opened")) {
$("#wrapNav").slideToggle("10", "linear", function(){
$("#sliding-navigation").slideToggle();
var newHeight = $("#container").height() + $("#wrapNav").outerHeight(true);
var newDistance = newHeight - $("#container").height() + 22;
$("#container").animate({height: newHeight}, 50,function(){
$(".box").animate({top: newDistance});
});
});
}
});
talents.click(function(e) {
e.preventDefault();
if (filter.hasClass("opened")) {
$("#sliding-navigation").slideToggle();
$("#wrapNav").slideToggle("10", "linear");
filter.removeClass('opened');
talents.addClass('opened');
$("#container").css("height", genHeight);
} else {
talens.addClass('opened');
};
if (talents.hasClass("opened")) {
$("#wrapNav").slideToggle("10", "linear", function(){
$(".nasco").slideToggle();
var newHeight = $("#container").height() + $("#wrapNav").outerHeight(true);
var newDistance = newHeight - $("#container").height() + 156;
$("#container").animate({height: newHeight}, 50,function(){
$(".box").animate({top: newDistance});
});
});
}
});
Anyone?

So, based on the code I could download about 20min ago from your test site, I managed to get it working with the following code:
$(document).ready(function(){
// placeholder to contain the original height...
var original_height = 0;
talents = $(".talenti");
filter = $(".filtra");
filter.click(function(e){
e.preventDefault();
if (filter.hasClass('opened')){
filter.removeClass('opened');
// toggle the wrapping, just with a zero top coordinate...
$("#wrapNav").slideToggle("10", "linear", function(){
$("#sliding-navigation").hide();
$(".box").animate({top: '0px'});
});
// reset to the original height...
$("#container").height(original_height);
}
else {
// get the original height if it's not already set...
if (original_height == 0)
original_height = $("#container").height();
filter.addClass('opened');
if (talents.hasClass("opened"))
{
$(".nasco").hide();
$("#wrapNav").slideToggle();
talents.removeClass('opened');
}
// toggle the wrapping with a height of the nav as top coordinate...
$("#wrapNav").slideToggle("10", "linear", function(){
$("#sliding-navigation").slideToggle(true, function(){
// need the height of the nav before we know how far to move the boxes...
var newHeight = $("#wrapNav").outerHeight(true);
$(".box").animate({top: newHeight});
// set the container's new height, much like you had...
$("#container").height(original_height + newHeight);
});
});
}
});
talents.click(function(e) {
e.preventDefault();
if (talents.hasClass('opened')) {
talents.removeClass('opened');
// toggle the wrapping, just with a zero top coordinate...
$("#wrapNav").slideToggle("10", "linear", function(){
$(".nasco").hide();
$(".box").animate({top: '0px'});
});
// reset to the original height...
$("#container").height(original_height);
}
else {
// get the original height if it's not already set...
if (original_height == 0)
original_height = $("#container").height();
talents.addClass('opened');
if (filter.hasClass("opened"))
{
$("#sliding-navigation").hide();
$("#wrapNav").slideToggle();
filter.removeClass('opened');
}
// toggle the wrapping with a height of the nav as top coordinate...
$("#wrapNav").slideToggle("10", "linear", function(){
// need the height of the nav before we know how far to move the boxes...
$(".nasco").slideToggle(true, function(){
var newHeight = $("#wrapNav").outerHeight(true);
$(".box").animate({top: newHeight});
// set the container's new height, much like you had...
$("#container").height(original_height + newHeight);
});
});
}
});
});
A few points adding food for thought:
I simplified the multiple if statements to make it easier to understand and process
I used hide() to avoid messy animation problems if you clicked on FILTER multiple times in a row
I only adjusted the top coordinates of the boxes to achieve this
I would have preferred to contain the boxes in a more general container, allowing for easier animation and management, but I understand that wordpress doesn't always give you the most room to work, so this should get you on your way!
It might not be completely what you're looking for in your animation, but it's a working example of the code you had and should get you 90% of the way...hope this helps! :)

What about using the data collection of the container element rather than a global variable i.e. at the top record the height
$("#container").data('height', $("#container").height());
then to use
$("#container").data('height');
i.e. to reset the height
$("#container").css({height: $("#container").data('height') });
I feel a bit suspicious about how the global variable is working. Worth a try maybe

Related

jQuery animated circular progress bar

I am using a jQuery script for an animated circular progress bar. Right now the progress bar works when the start button is clicked. I want this progress bar to start when the user scrolls to the div id "stats" automatically. How can this be done?
I have made a fiddle to show what I have so far:
https://jsfiddle.net/rpkcw236/9/
jQuery(document).ready(function($){
$('.pie_progress').asPieProgress({
namespace: 'pie_progress',
barsize: '2',
trackcolor: '#ececea',
barcolor: '#e6675f'
});
$('#button_start').on('click', function(){
$('.pie_progress').asPieProgress('start');
});
$('#button_finish').on('click', function(){
$('.pie_progress').asPieProgress('finish');
});
$('#button_go').on('click', function(){
$('.pie_progress').asPieProgress('go',50);
});
$('#button_go_percentage').on('click', function(){
$('.pie_progress').asPieProgress('go','50%');
});
$('#button_stop').on('click', function(){
$('.pie_progress').asPieProgress('stop');
});
$('#button_reset').on('click', function(){
$('.pie_progress').asPieProgress('reset');
});
});
Here is the link to the script I am using:
http://www.jqueryscript.net/loading/Animated-Circle-Progress-Bar-with-jQuery-SVG-asPieProgress.html
You need to break it up into 2 steps:
1) get the distance of the dynamic div from the top.
2) Once you get the top value pass this top value to the code in step2.
Step1: Get the dynamic div position from the top (e.g. #my-dynamic-div)
var $output = $('#output');
$(window).on('scroll', function () {
var scrollTop = $(window).scrollTop(),
elementOffset = $('#my-dynamic-div').offset().top,
distance = (elementOffset - scrollTop);
$output.prepend('<p>' + distance + '</p>');
});
OR
E.G: var distance = $("#MyDiv").offset().top
ref: http://jsfiddle.net/Rxs2m/
Step2: Pass the distance value here instead of the hard coded value 350.
flag=true;
$(window).scroll(function() {
st=$(window).scrollTop();
$('#topscroll').html(st)
if(st>350){
if(flag)
$('.pie_progress').asPieProgress('start');
flag=false;
}
});
Good luck & hope this helps.
Try using .scrollTop() , .offset().top Element.getBoundingClientRect() of #progress element, .off()
$(window).on("scroll", function() {
if ($("#progress")[0].getBoundingClientRect().top < 150) {
$('.pie_progress').asPieProgress('start')
$(this).off("scroll")
}
})
jsfiddle https://jsfiddle.net/rpkcw236/29/

Centering Element using jQuery Position + Variable

I have the following code below, it was modified from (CSS-Tricks Link). It works fine, however the magic line (floating element under navigation) in my site is 40 pixels wide.
I want to permanently center align the bar (whether it falls under hover state or not), at present it is aligned left of the element. As it is using the jQuery .position() to calculate from the left, all my efforts add the 'forceRight' but negate jQuery .position().
The variable 'forceRight', finds the difference either side of the 40px bar. However I need this side gap to be enforced as the menu items are different widths.
var forceRight,
off_hover_left,
$el,
$calcuateForceDistance,
$magicLine_width = 40,
$mainNav = $("#main-navigation"),
$currentPosition = $(".current-menu-item"),
$currentPosition_width = ($currentPosition.outerWidth() - $magicLine_width);
$mainNav.append("<span id='magic-line'></span>");
var $magicLine = $("#magic-line");
$magicLine
.css("left", $(".current-menu-item").position().left)
.data("origLeft", $magicLine.position().left);
$("#main-navigation a").hover(function(){
// current element
$el = $(this),
// Calcuate Distance
$calcuateForceDistance = Math.floor( ( $el.outerWidth() - $magicLine_width ) / 2 );
forceRight = ( $el.position().left + $calcuateForceDistance );
off_hover_left = Math.floor( $currentPosition.position().left + ($currentPosition_width / 2) );
$magicLine.stop().animate({
left: forceRight
});
}, function() {
// On Hover Out - Return to DOM LOAD (.current-menu-item)
$magicLine.stop().animate({
// not selected outerwidth !!! sort out variables above!
left: off_hover_left
});
});
Many thanks!
I have fixed the bug in my code, I also added a doc ready to get the code to run on browser rendering. When the code loads, I also created a delay then added a class to remove the glitch (the left animation between 0 -> needed axis value.
In this case I used opacity 0, as default. and 1, on .addClass('found').
var forceRight,
$el,
$calcuateForceDistance,
$magicLine_width = 40,
$mainNav = $("#main-navigation"),
$currentPosition = $(".current-menu-item"),
$currentPosition_width = ($currentPosition.outerWidth() - $magicLine_width),
$off_hover_left = Math.floor( $currentPosition.position().left + ($currentPosition_width / 2) );
// Create HTML ELEMENT
$mainNav.append("<span id='magic-line'></span>");
// Target -> Variable
var $magicLine = $("#magic-line");
// Apply attr's
$magicLine.css("left", $(".current-menu-item").position().left);
$(document).ready(function(){
// Enforce Code On Load
$magicLine.stop().animate({
// not selected outerwidth !!! sort out variables above!
left: $off_hover_left
}).promise().done(function(){
// Once Positioned - Then add class (changes opacity) !
$(this).addClass('found');
});
$("#main-navigation a").hover(function(){
// current element
$el = $(this),
// Calcuate Distance
$calcuateForceDistance = Math.floor( ( $el.outerWidth() - $magicLine_width ) / 2 );
forceRight = ( $el.position().left + $calcuateForceDistance );
$magicLine.stop().animate({
left: forceRight
});
}, function() {
// On Hover Out - Return to DOM LOAD (.current-menu-item)
$magicLine.stop().animate({
// not selected outerwidth !!! sort out variables above!
left: $off_hover_left
});
});
});
I hope this helps, someone not just me!
In your javascript you only set the left position of your #magic-line. You need to set the width of the line also. Example in the code underneath (Just the rows to modify):
// On the initialization
$magicLine
.css({
"left": $(".current-menu-item").position().left,
"width" : $(".current-menu-item").outerWidth()
});
// On modification
$magicLine.stop().animate({
left: leftPos,
width: $el.outerWidth()
});
This should solve the problem.

Doing something on second click with Snap.svg

I am writing a basic code for an animation on click with Snap.svg. It looks like this:
var s = Snap(500, 500);
var circle = s.rect(100,100,100,100);
circle.click(function(){
var width = circle.attr('width');
var height = circle.attr('height');
circle.animate({
width: width/2,
height :height/2
}, 2000);
});
I make a rectangle in the top left corner of the container and animate it's width on a click. THEN, however, I want to do something different on the second click, return it to its original state for example.
I'd also be glad to learn how do you handle this second click in Javascript in general.
For example: press this button once and the slide navigation opens. Tap it second time and the navigation dissappears.
Thanks in advance!
You can do that by using the event.detail property. In your case, that would be:
circle.click(function(e) {
var width = circle.attr('width');
var height = circle.attr('height');
if (e.detail == 1) {
circle.animate({
width: width/2,
height :height/2
}, 2000);
} else if (e.detail == 2) {
circle.animate({ //example
width:width,
height:height
}, 2000);
}
});
There, the animation to change back to the original sizes plays when the user performs a double click (so 2x fast). If you basically want to toggle the element, instead of reverting it on doubleclick, you can simply check if the element has a width or height style other than its initial width or height:
circle.click(function(e) {
var width = circle.attr('width');
var height = circle.attr('height');
if (parseInt(this.style.width) == parseInt(width) || !this.style.width) {
circle.animate({
width: width/2,
height :height/2
}, 2000);
} else {
circle.animate({ //example
width:width,
height:height
}, 2000);
}
});
Then the if() will return true when either the width attribute is equal to the width style, or when the width style is empty/not defined.
You'd want to store what state of the click.
There are many different ways to go about this, but I'll choose two:
Create a counter variable (say, counter) and increment it each time the click handler runs. Then, each time, to decide what to do, see if the number is even or odd:
var counter = 0;
circle.click(function(){
if(counter % 2 == 0){
//action1
}else{
//action2
}
counter++;
});
Alternatively, you can use a Boolean that changes each time to keep track of which action to perform.
var flag = true;
circle.click(function(){
if(flag){
//action1
flag = false;
}else{
//action2
flag = true;
}
});

Jquery animating width accordion style banner

I built this simple accordion style banner. Here's what it's supposed to do:
Grab <li> containing images from selected <ul>.
Divide them equally within the container (div.banner)
On 'mouseenter', add class .active to the hovered <li>
Shrink the other <li>s widths (half their original width).
Enlarge active <li> to new width (remainder after halving the others)
On 'mouseleave', all return to original widths.
Works fine until you swipe over multiple panes quickly. If you do, the last of the floated <li>'s break to the next line. It appears the total width of the panes is exceeding their container.
Rounding error while animating? Does it have something to do with animate's default 'swing' easing?
Fiddle: http://jsfiddle.net/UNFc4/
var banner = $('.banner');
var list_items = banner.find('li');
var banner_width = $(banner).width();
var num_of_images = $(banner).find('li').length;
var original_width = banner_width / num_of_images;
var half_width = (banner_width / num_of_images) / 2;
var init = function () {
$(list_items).css('width', original_width);
$(list_items).on('mouseenter', function () {
$(this).addClass('active');
doAnimation();
});
$(list_items).on('mouseleave', function () {
resetAnimation();
$(this).removeClass('active');
});
}
var doAnimation = function () {
$(list_items).not(".active").stop().animate({
width: half_width + "px"
}, 500);
$(".active").stop().animate({
width: (original_width + (half_width * (num_of_images - 1))) + "px"
}, 500);
}
var resetAnimation = function () {
$(list_items).stop().animate({
width: original_width + "px"
}, 500);
}
init();
I could fix it by changing this line, slowing the animation of the others, giving things time to equal out. But, I'd rather solve what's going on here, hopefully learning a bit more about how jQuery's animate() works.
$(list_items).not(".active").stop().animate({
width: half_width + "px"
}, 480); // changed 500 to 480
For those interested, I realized I only needed the reset on the banner area. Now it works, as described, without all the jitteriness and the subsequent layout mis-alignments.
New Fiddle: http://jsfiddle.net/UNFc4/1/
$(list_items).on('mouseenter', function () {
$(this).addClass('active');
doAnimation();
});
$(list_items).on('mouseleave', function () {
$(this).removeClass('active');
doAnimation();
});
$(banner).on('mouseleave', function () {
resetAnimation();
});

get height of LI using jQuery so news ticker scrolls up the exact amount needed

I am using a script from
http://www.yourinspirationweb.com/en/jquery-how-to-create-a-news-ticker-with-just-a-few-javascript-lines/
which is a great newsticker, designed to scroll up just one article at a time, then append it again at the end in a continuous loop. But the limitation of this script is that the news items in each have to be the same height as eachother, which isn't always possible.
I have been trying to modify the script so that it will automatically get the outerheight of '#ticker li:first'. and scroll it so that marginTop equals the negative of that outerheight. rather than the default '-120px'. But i've realised it's written as CSS style, i don't know how to rewrite it. Help!
here's the original script:
$(function()
{
var ticker = function()
{
setTimeout(function(){
$('#ticker li:first').animate( {marginTop: '-120px'}, 800, function()
{
$(this).detach().appendTo('ul#ticker').removeAttr('style');
});
ticker();
}, 4000);
};
ticker();
});
This should do the trick. Just put the height into a variable, multiply by -1 (to make the negative number you need), and then drop it into the marginTop property:
$(function() {
var ticker = function() {
setTimeout(function() {
// get the height of the li element, multiply by -1 to be negative
var h = parseInt($("#ticker li:first").outerHeight()) * -1;
$('#ticker li:first').animate( {marginTop: h + 'px'}, 800, function() {
$(this).detach().appendTo('ul#ticker').removeAttr('style');
});
ticker();
}, 4000);
};
ticker();
});
To retrieve the outerHeight (including border, padding, and optionally margin) of an html element using jQuery, do $(element).outerHeight()
To retrieve the innerHeight of an html element using jQuery, do $(element).innerHeight()
$(function()
{
var ticker = function()
{
setTimeout(function(){
var oHeight = $('#ticker li:first').outerHeight();
$('#ticker li:first').animate( {marginTop: -oHeight}, 800, function()
{
$(this).detach().appendTo('ul#ticker').removeAttr('style');
});
ticker();
}, 4000);
};
ticker();
});
The default unit is pixels so you don't have to worry about appending px to the value.

Categories

Resources