animate every char of an html element text using jquery? - javascript

i want to animate a string of text taken from an html element using jquery:
<h1>Animate</h1>
for the jquery part:
$(document).ready(function() {
$( "h1" ).animate({ fontSize: "90px" }, 1500 )
.animate({ fontSize: "50px" }, 1500 );
});
this animates the whole h1 text value, however i want to animate each character in the h1 text.
the second jquery part:
$(document).ready(function () {
var animateChar = $("h1").text();
for(i=0; i<animateChar.length; i++) {
//alert(i + ': ' + animateChar.charAt(i));
// for every animateChar.charAt[i] want to run this
//jquery animation.
//$( "h1" ).animate({ fontSize: "90px" }, 1500 )
//.animate({ fontSize: "50px" }, 1500 );
}
});
this is the bit where im stuck. thanks

You can use jQuery functions on DOM elements. Not on characters apart. You should use different DOM elements for each character:
<span>A</span><span>N</span><span>I</span>...
with something like this must do the trick
$('span').each(function() {
var that = $(this);
setTimeout(function() {
that.animate({ fontSize: "90px" }, 1500 )
.animate({ fontSize: "50px" }, 1500 );
},that.index()*100);
});​
-edit-
working jSFIDDLE
-edit 2-
without messy HTML JSFIDDLE(well it's still messy, but javascript makes it messy ;) )

If you want to keep your HTML clean, I'd add the following method to wrap your characters in span tags. Execute this onLoad using wrapCharacters($("h1")) before you animate anything, then animate characters returned by $(".animate").
function wrapCharacters(obj)
{
var html = '';
var text = obj.text();
for (var i = 0; i < text.length; i++)
{
html += '<span class="animate">' + text[i] + '</span>';
}
obj.html(html);
}

<span class="animate">A</span><span class="animate">n</span><span class="animate">i</span><span class="animate">m</span><span class="animate">a</span><span class="animate">t</span><span class="animate">e</span>
$(document).ready(function() {
var count = 0;
function animation(elm) {
if(count == $(".animate").length)
{
clearInterval(id);
return;
}
$( elm ).animate({ fontSize: "90px" }, 1500 )
.animate({ fontSize: "50px" }, 1500 );
count++;
}
var id = setInterval(animation($(".animate")[count]), 3200);//Give time for animation to run.
});
This will animate each character.

Related

tooltip is shown after the 2nd hover

I have a problem, I'm trying to add a tooltip to some already rendered elements. The code that I have makes the tooltip appear after the 2nd hover which is kind of normal because on the first one is not set yet, do you know what can I do to have it displayed from the first hover?
Thanks in advance!
I have the following code:
$(".checkWidth").live("mouseenter",function() {
var size = measureText($(this).text(), 12, 'Tahoma')
var limit = $('#my_container').width() - 67;
if( size.width > limit){
$(this).attr('title', $(this).text());
$('#tiptip_content').css('font-size', '13px');
$(this).tipTip({
maxWidth: "auto",
defaultPosition: "right",
fadeIn: 100,
fadeIn: 100,
attribute: "title"
});
}
});
Calling $(this).tipTip({...}); sets up the tooltip, it doesn't show it. So you don't actually set up the tooltip until you mouseover the element, and the tooltip is shown the next time you mouse over (handled by the plugin).
You'll need to call that on DOM ready. I think you may need something like this:
$(document).ready(function () {
$('#tiptip_content').css('font-size', '13px');
var limit = $('#my_container').width() - 67;
$('.checkWidth').each(function () {
var size = measureText($(this).text(), 12, 'Tahoma');
if (size.width > limit) {
$(this).attr('title', $(this).text());
$(this).tipTip({
maxWidth: "auto",
defaultPosition: "right",
fadeIn: 100,
fadeIn: 100,
attribute: "title"
});
}
});
});
Edit another possibility:
$('#tiptip_content').css('font-size', '13px'); //this should be able to be done elsewhere...
$("document").on("mouseenter", '.checkWidth', function () {
var $this = $(this);
if ($this.data('tipInit') === true) { return; }
$this.data('tipInit', true);
var size = measureText($(this).text(), 12, 'Tahoma')
var limit = $('#my_container').width() - 67;
if (size.width > limit) {
$this.attr('title', $this.text());
$this.tipTip({
maxWidth: "auto",
defaultPosition: "right",
fadeIn: 100,
fadeIn: 100,
attribute: "title"
});
$this.trigger('mouseenter');
}
});
it depends on your code structure. But I will try the following:
Try changing the .live() to .on()
I would try to change the function to .on('hover', function)
I would also try to use mousenter and mouseleave

JQuery animate .css() rather then using .anmiate()?

I want to aniamte the change of the margin-top of a div.
Normally I would so this as such:
$("#mydiv").animate({ marginTop: '+='+myvar}, 200);
But this always adds (or subtracts) the value. I want a way to simply aniamte the change in value.
For example: if the div starts of with a margin top of 100 and myvar value is 50 I want to animate the div so it shrinks back to 50. Likewise if the myvar value is 200 I want to animate the change so grows to 200.
I can achieve this somewhat but resetting the CSS, eg:
$("#mydiv").css("margin-top", "0px");
$("#mydiv").animate({ marginTop: '+='+myvar}, 200);
each time but that makes it a bit clunky.
Does anyone know of a may to achieve this?
(Ps: without using CSS transitions)
EDIT: Added my code below
$("#info1tab").click(function() {
$(".textbox").slideUp('200');
$("#info1").delay(300).slideDown('200');
var itemheight = $("#info1").css("height");
var itemheightint = parseInt(itemheight);
$("#photobox").animate({ marginTop: itemheightint }, 200);
});
$("#info2tab").click(function() {
$(".textbox").slideUp('200');
$("#info2").delay(300).slideDown('200');
var itemheight = $("#info2").css("height");
var itemheightint = parseInt(itemheight);
$("#photobox").animate({ marginTop: itemheightint }, 200);
});
what is wrong with $('#mydiv').animate({marginTop: myvar});?
http://jsfiddle.net/muVsE/
Create additional CSS classes that has the CSS properties you want and then do:
$("#mydiv").addClass("classname", 1000);
OR
$("#mydiv").removeClass("classname", 1000);
Try this code:
$("#mydiv").css("margin-top", "0px");
$("#mydiv").animate({ marginTop: topMargin+myvar}, 200);
I hope this helps JSFiddle
$('#left-bg, #right-bg').click(
function(){
$(this).animate({'width': '100%'},600).siblings().animate({'width':'0'},600);
});
Or you can use this JSfiddle
$('#left-bg, #right-bg').click(
function(){
$(this).animate({'width': '100%'},600).siblings().animate({'width':'0'},600);
$('<button class="show">Show all</button>')
.appendTo('#wrapper');
});
$('.show').live('click',
function(){
$('#left-bg').animate(
{
'width': '50%'
},600);
$('#right-bg').animate(
{
'width': '50%'
},600);
$(this).remove();
});
Or you can use this to expand one div and shrink other at the same time:
$('.cell')
.on('mouseenter', function(){
$(this).animate ({width:"75%"},"slow").siblings('.cell').animate({'width': '15%'}, "slow");
})
.on('mouseleave', function(){
$(this).add($(this).siblings('.cell')).animate ({width:"45%"},"slow");
});
Regards.

How to use queue in jQuery animate?

I want to increase/decrease the font of and element, then the next element of that class and so forth, for a set of elements as <div class="test"></div> <div class="test"></div> ..... I mean
step 1: enlarging the first element and returning to normal size
step 2: enlarging the second element and returning to normal size
....
My basic code is
$(document).ready(function() {
$('.test').animate({
left:50,
fontSize: "2em"},
"slow")
.animate({
left:-50,
fontSize: "1em"},
"slow");
This will affect all the elements at once. How can I make a queue to make the changes one by one. Having one enlarged element at a time.
You could do it with
$('.test').each(function(idx){
var duration = 1200; // duration for all animations (2 x slow)
$(this)
.delay(duration*idx)
.animate({ left:50, fontSize: "2em" }, 'slow')
.animate({ left:-50, fontSize: "1em" }, 'slow');
});
Demo at http://jsfiddle.net/gaby/rz5Es/
For more precise control and more freedom on queuing look at my answer at a similar question:
A non-nested animation sequence in jQuery?
You need to use callbacks and an array of the elements you want to sequentially animate...
function animateSequence(elements){
var element = $(elements).first();
var originalSize = $(element).css('font-size');
elements = $(elements).not($(element));
$(element).animate(
{ fontSize: "2em" },
"slow",
function(){
$(this).animate(
{ fontSize: originalSize },
"slow",
function(){
if(elements.length > 0)
animateSequence(elements);
}
)
}
);
}
animateSequence($('.test'));
If you want to play with it: http://jsfiddle.net/xS7X7/
You will need to loop thru all elements and execute animate on each of them sequentially, here is sample code to do that recursively
function animate_sequential(elems, css, delay, index){
if(index===undefined) index = 0;
if(index >= elems.length) return;
$(elems[index]).animate(css, delay, function(){
animate_sequential(elems, css, delay, index+1)
})
}
animate_sequential($('div'), {'font-size':'30px'}, 500)
animate_sequential($('div'), {'font-size':'15px'}, 500)
See it in action http://jsfiddle.net/anuraguniyal/QJc9L/
It can be easily converted to a jQuery plugin, so that you can do $('div').animate_sequential and keep same interface as jQuery animate, you can also further enhance it so that it brings back to original css by passing the original css or getting it from element.
As I understand you are trying to do something like this,
$(document).ready(function() {
(function mycallback(i) {
var elems = $('.test');
elems.eq(i).animate({
left:50,
fontSize: "2em"}, function () {
mycallback(i + 1 < elems.length ? i + 1 : 0);
});
}(0));
});
​DEMO
UPDATE:
It was an example code, you can change it like this if you want to reverse effects,
$(document).ready(function() {
(function mycallback(i) {
var elems = $('.test');
elems.eq(i).animate({
left:50,
fontSize: "2em"}, function () {
$(this).animate({
left:-50,
fontSize: "1em"},
"slow");
if (i + 1 < elems.length)
mycallback(i+1);
});
}(0));
});
​UPDATED DEMO
So much simpler, readable, and scalable with Frame.js:
$('.test').each(function(i){
var element = $(this);
var originalSize = element.css('font-size');
Frame(function(next){
element.animate({ fontSize: "2em" }, "slow", next);
});
Frame(function(next){
element.animate({ fontSize: originalSize }, "slow", next);
});
});
Frame(function(next){
// add a callback after all the animations have finished
next();
});
Frame.start();

Jquery UI slider how to make a box follow the handler?

I am trying to create a div that should follow the handler as it is seen here:
http://m1.dk/Priser/#tab:#calc,#abb
My JSfiddle: http://jsfiddle.net/z3xV3/2/
I also want to make a calculation on the UI value that should appear in the box.
Here is a illustration what I want to achieve:
HTML:
<div id="slider"></div>
<input id="sliderValue" />
Jquery:
$(document).ready(function() {
// Pris slider
$("#slider").slider({value:'',min: 0,max: 150,step: 1, range: 'min',
slide: function( event, ui ) {
$( "#amount" ).html( ui.value + ' timer');
}
});
$( "#amount" ).val( "$" + $( "#slider" ).slider( "value" ) );
});
I hope that's the effect you're looking for: http://jsfiddle.net/z3xV3/11/
JS
$(document).ready(function() {
$("#slider").slider({value:'', min: 0, max: 150, step: 1, range: 'min'});
var thumb = $($('#slider').children('.ui-slider-handle'));
setLabelPosition();
$('#slider').bind('slide', function () {
$('#sliderValue').val($('#slider').slider('value'));
setLabelPosition();
});
function setLabelPosition() {
var label = $('#sliderValue');
label.css('top', thumb.offset().top + label.outerHeight(true));
label.css('left', thumb.offset().left - (label.width() - thumb.width())/ 2);
}
});
HTML
<div id="slider"></div>
<input id="sliderValue" />
CSS
#sliderValue {
position:absolute;
width: 50px;
}
Best regards!
I have modifiered your jsfiddle example: http://jsfiddle.net/Dr5UR/
$("#amount").val("$" + $("#slider").slider({
slide: function(event, ui) {
$('#sliderValue').css('left', event.clientX).val(ui.value);
}
}));
I make use of the slide event of the slider.
The slide event got two arguments:
event
This object contains several informations about the event itself. The time of triggering, the key which has been pressed or the coordinates of the mouse at the moment of triggering. The clientX property contains the position we need to set to the moving object.
ui
The ui object comes from jQuery UI itself. It basicly just contains the value. Additionally it contains the anchor which is used for dragging too. But you can't use its position, cause the slide event takes effect before the anchor takes its new position.
The #slideValue input needs to have position: absolute;, cause I work with the left position attribute in CSS. You could also set the margin-left value, without need to set the position to absolute.
It's actually quite easy (and very useful) to turn this into a simple jQuery plugin. Like so:
JSFiddle: http://jsfiddle.net/PPvG/huYRL/
Note that I've added support for moving the slider by entering a value into the #sliderValue.
[ Code sample removed ]
You could also choose to remove #sliderValue from the HTML and let the plugin create it for you. In that case, you would rewrite the plugin so it would be called on the slider, instead of on #sliderValue. In my opinion, that would be a much neater solution.
Update
Based on your comments (and re-reading your question), I've rewritten the plugin example.
If I understand correctly, you want to do some calculations based on the value of the slider and display the result of those calculations in the label below the slider handle. The following should make that really easy.
JSFiddle: http://jsfiddle.net/PPvG/q5qg7/
HTML
<div id="slider"></div>
Plugin
(function($) {
$.fn.sliderLabel = function(options) {
var settings = $.extend({
marginTop: 2,
// Margin between the slider handle and the label (in pixels)
callback: function(value) {
return 'Value: ' + value;
}
}, options);
return this.each(function() { // <- maintains chainability
var slider = $(this);
var handle = slider.children('.ui-slider-handle');
var data = slider.data('sliderLabel');
if (handle.length === 0) {
// $(this) isn't a slider (it has no handle)
console.log('[SliderLabel] Error: sliderLabel() can only be called on a slider.');
return;
}
if (data === undefined) {
// First time sliderLabel() is called on this slider
data = {
label: $('<div class="ui-slider-label" />').css('position', 'absolute'),
callback: settings.callback
};
data.label.insertAfter(slider);
function updateLabel() {
var value = slider.slider('value');
var labelText = data.callback(value);
data.label.html(labelText);
data.label.css('top', handle.offset().top + handle.outerHeight() + settings.marginTop);
data.label.css('left', handle.offset().left - ((data.label.width() - handle.width()) / 2));
}
updateLabel();
slider.bind('slide', updateLabel);
} else {
// sliderLabel() was called before; just update the callback:
data.callback = settings.callback;
updateLabel();
}
// Save (or update) the data inside the slider:
slider.data('sliderLabel', data);
});
}
})(jQuery);
Usage
$("#slider").slider();
$("#slider").sliderLabel({
callback: function(value) {
return value + '%';
}
});
As you can see, the plugin is now called on the slider itself. You can now provide the plugin with a callback, which allows you to do some calculations and return a correctly formatted label (HTML is allowed).
In the example above, the callback simply takes the value that is passed to the callbackand appends '%'.
Here is a working example for a slider with two handles
$('#slider').slider({
range: true,
min: 500,
max: 10000,
step: 100,
values: [1000, 2000],
slide: function( event, ui ) {
$('#min-price').html('$' + ui.values[0]);
$('#min_budget').val(ui.values[0]);
$('#max-price').html('$' + ui.values[1]);
$('#max_budget').val(ui.values[1]);
}
//move labels when handles are moved
moveValueLabels();
}
});
//move the value labels directly under the handles
function moveValueLabels() {
var pos_first_handle = $('.ui-slider-handle:first').position();
var pos_last_handle = $('.ui-slider-handle:last').position();
$('#min-price').css('left', (pos_first_handle.left - ($('#min-price').width()/2)));
$('#max-price').css('left', (pos_last_handle.left - ($('#max-price').width()/2)));
}
//set initial positioning of labels when page is loaded
moveValueLabels();
CSS:
#slider {
overflow: visible;
#min-price {
position:absolute;
top:20px;
font-weight: bold;
padding:0;
}
#max-price {
position:absolute;
top:20px;
font-weight: bold;
padding:0;
}
}
HTML:
<div id="slider"></div>
CSS:
#slider {
width: 200px;
}
#sliderValue {
position: absolute;
left: 0;
bottom: -30px;
width: 40px;
}
jQuery:
$("#slider").slider({
value: '',
min: 0,
max: 100,
range: 'min',
create: function (event, ui) {
$('.ui-slider-handle').append('<input id="sliderValue" />');
},
slide: function (event, ui) {
$("#sliderValue").val(ui.value);
}
});
http://jsfiddle.net/yBfTy/4/
It would be nice to take a look at alternative solutions with jQuery plugins such as:
http://craigsworks.com/projects/qtip2/demos/#ui-slider
http://www.filamentgroup.com/lab/update_jquery_ui_slider_from_a_select_element_now_with_aria_support/
Taking your jsfiddle.
HTML:
<div id="slider"></div>
<input id="sliderValue" />
CSS:
#sliderValue{width:50px;}
Jquery:
$(document).ready(function() {
// Pris slider
$("#slider").slider({value:'',min: 0,max: 150,step: 1, range: 'min',
slide: function( event, ui ) {
$( "#sliderValue" ).val( ui.value + ' timer');
var offset = $(this).find('a').css("left");
$("#sliderValue").css("margin-left", offset);
}
});
$( "#sliderValue" ).val($( "#slider" ).slider( "value" ));
});
You can just: http://jsfiddle.net/z3xV3/21/
$(document).ready(function() {
$("#slider").slider({
value:0,
min: 0,
max: 150,
step: 1,
range: 'min',
slide: function( event, ui ) {
var offsetLeft = $(this).find(".ui-slider-handle").offset().left;
$( "#sliderValue" )
.val( ui.value + ' timer')
.css({
"position": "absolute",
"left": offsetLeft
});
}
});
});
The slide callback is called every time you move your handle:
offsetLeft is the offset of the handle.
$( "#sliderValue" ) is your input.

jQuery galleryview from append

I'm dynamically adding images via a loop from the flickr.com database. I append these ul, li, img tags as you should do according to the galleryview example. I append it to a div then I call the galleryview function:
$('#gallery').galleryView({
panel_width: 800,
panel_height: 300,
frame_width: 50,
frame_height: 50,
transition_speed: 350,
easing: 'easeInOutQuad',
transition_interval: 0
});
It works if I manually add the ul, li, img tags on the front page but if I add them using jQuery append it doesn't work. But I found that if I make the page load slowly and instantly run the append code it works. How can I use append and afterwards use the galleryview on the appended elements?
Source code:
function initialize_flickr(_div){
var newDiv = $(document.createElement('div'));
//add some style to the div
$(newDiv).css('background-color', '#223');
$(newDiv).css('width', 800);
$(newDiv).css('height', 800);
$(newDiv).css('position', 'absolute');
$(newDiv).css('left', 500);
$(newDiv).css('top', 0);
//append it to the _div
newDiv.appendTo(_div);
// Our very special jQuery JSON function call to Flickr, gets details of the most recent 20 images
$.getJSON("http://api.flickr.com/services/feeds/groups_pool.gne?id=998875#N22&lang=en-us&format=json&jsoncallback=?", displayImages);
function displayImages(data) {
// Randomly choose where to start. A random number between 0 and the number of photos we grabbed (20) minus 9 (we are displaying 9 photos).
var iStart = Math.floor(Math.random()*(11));
// Reset our counter to 0
var iCount = 0;
// Start putting together the HTML string
var htmlString = "<ul id='gallery'>";
// Now start cycling through our array of Flickr photo details
$.each(data.items, function(i,item){
// Let's only display 9 photos (a 3x3 grid), starting from a random point in the feed
if (iCount > iStart && iCount < (iStart + 10)) {
// I only want the ickle square thumbnails
var sourceSquare = (item.media.m).replace("_m.jpg", "_s.jpg");
// Here's where we piece together the HTML
htmlString += '<li>';
htmlString += '<span class="panel-overlay">'+item.title+'</span>';
htmlString += '<img src="'+sourceSquare+'" />';
htmlString += '</li>';
}
// Increase our counter by 1
iCount++;
});
// Pop our HTML in the #images DIV
$(newDiv).append(htmlString + "</ul>").each(function(){
$('#gallery').galleryView({
panel_width: 800,
panel_height: 300,
frame_width: 50,
frame_height: 50,
transition_speed: 350,
easing: 'easeInOutQuad',
transition_interval: 0
});
});
// Close down the JSON function call
}
}
Try adding a callback(for galleryView) to your append. This way you are calling galleryView only after your append.
$(newDiv).append(htmlString + "</ul>").each(function(){ $('#gallery').galleryView({ panel_width: 800, panel_height: 300, frame_width: 50, frame_height: 50, transition_speed: 350, easing: 'easeInOutQuad', transition_interval: 0 }); });
Each Callback Example-
.appendTo('#element').each(function() {
//Call galleryView here
});
Are you trying to run your jQuery before the DOM has finishing parsing? Try executing your code after the browser has loaded.
$(document).ready(function() {
// put all your jQuery goodness in here.
});
http://www.learningjquery.com/2006/09/introducing-document-ready

Categories

Resources