Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 109
  • Last Modified:

jQuery Time Off Event

Hello Experts,

I am taking a jQuery classes and need to create a "Wack a Gopher" game.  It is almost done, but I dont know how to do the following:

The mallet's css should change somehow to give the user a graphic representation that it was clicked, after it is clicked create a timeout event that then changes that css property back


I have started this at line 66, but I am not quite sure how to handle the changing back property. I also need to swing the mallet 180 degree, which I guess is the same way, maybe I need to use step function, but I am not sure?

My code so far is http://codepen.io/AleksPoposki/pen/NRZRZb

Any help will be appreciated.
0
APD Toronto
Asked:
APD Toronto
  • 10
  • 9
1 Solution
 
RobOwner (Aidellio)Commented:
Okay so what you need to do is store the original element (the mallet) and the current css property.  in this example i'm using a color: http://jsbin.com/fevebinimu/edit?html,css,js,output

$(function() {
  $("#btn").on('click',function() {
    // remember the current back-color state
    var self = this;
    var back = $(this).css('background-color');
    $(this).css('background-color','yellow');
    setTimeout(function(){(function(el,col) {
      $(el).css('background-color',col);
    }(self,back));},1000);
  });
});

Open in new window


I'm using a closure for the setTimout so that you're able to pass variables from the click event scope
0
 
RobOwner (Aidellio)Commented:
Now as for the mallet rotating: http://jsbin.com/ravocuvesa/edit?html,css,js,output

You use a CSS transition (for the actual animation) and transform (for the rotation)

.image.on {
  transform: rotate(180deg);
}
.image {
  -webkit-transition: transform 1s;
  -moz-transition: transform 1s;
  transition: transform 1s;  
}

Open in new window


Then use can use the toggleClass function within the click event of the mallet to toggle the "on" class for the mallet
0
 
APD TorontoAuthor Commented:
I would like to animate the size, but it does not working

 //Animate Mallet by changing its size
            var timer = 500;
            var malletWidth = $("#mallet").width();
            $("#mallet").animate(
               {
                    width: (malletWidth * 2) + "px"
                },timer, 
                function()
                    {
                        width: (malletWidth) + "px"
                    } 
                        ); //End animate

Open in new window


Do I need to nest another animate function within the first animate?
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
RobOwner (Aidellio)Commented:
is there a reason you want to do it in jQuery vs css?
0
 
RobOwner (Aidellio)Commented:
The js in much more intensive to run and can have performance issues
0
 
APD TorontoAuthor Commented:
But how would you animate the width for example?
0
 
APD TorontoAuthor Commented:
In your example you clearly call a function twice, but how do you do that?
0
 
APD TorontoAuthor Commented:
Plus, as I see the assignment's requirements, I need to  use step as this is a jQuery course
0
 
RobOwner (Aidellio)Commented:
the function isn't called twice, more that the setTimeout call a function that calls another function (closure).  This wrapping is done to prevent the closure being executed when the page loads.  If the closure was the only thing passed to the setTimeout then it would be called both when the page loads and the result (should it actually return anything, which is doesn't) would be what setTimeout tries to do.  Confusing i know but that's the reason for the multiple levels.

I understand that you need to satisfy the requirements of the course.  So step is a must then yeah?  I"ll modify my example.
0
 
RobOwner (Aidellio)Commented:
Okay here is an example: http://jsbin.com/negehig/edit?html,js,output

I've modified the code from: http://stackoverflow.com/questions/15191058/css-rotation-cross-browser-with-jquery-animate?answertab=active#tab-top

$(function() {
  $("#mallet").on("click",function() {
    AnimateRotate(0,180);
    setTimeout(function() {
      AnimateRotate(180,360);
    },1250);
  });
});

function AnimateRotate(start, angle) {
    // caching the object for performance reasons
    var $elem = $('#mallet');

    // we use a pseudo object for the animation
    // (starts from `0` to `angle`), you can name it as you want
    $({deg: start}).animate({deg: angle}, {
        duration: 250,
        step: function(now) {
            // in the step-callback (that is fired each step of the animation),
            // you can use the `now` paramter which contains the current
            // animation-position (`0` up to `angle`)
            $elem.css({
                transform: 'rotate(' + now + 'deg)'
            });
        }
    });
}

Open in new window

0
 
APD TorontoAuthor Commented:
It works, but can you explain

$({deg: start}).animate({deg: angle}, {

and why not use .css on both lines?
0
 
APD TorontoAuthor Commented:
I guess I don't quite understand the step function as well. Why is this needed when without it the animation happens anyway?
0
 
APD TorontoAuthor Commented:
Does step controls the animation flow, so its not instantaneous?

If yes, then how does it know now not to exceed 180, especially if we need to animate multiple of properties, like  degree and width?
0
 
RobOwner (Aidellio)Commented:
The animate function works on any object and its properties... This is essentially saying that you want animate to perform its algorithm (with easing) etc and call the step function for each increment.

$({deg: start}).animate({deg: angle}

You pass in a simple object with only the deg property defined.  You then tell the animate function that you want to "animate" (or just increment based on the settings you might pass) the deg property to angle.  You could rename "deg" to anything you like, it's just a property that you're telling animate to go from and to.

The animation doesn't work for me without the step function.  This is where the actual css is done, like i said before the pseudo object is just to essentially create a glorified "for" loop.

And in saying that you could just use a loop in conjunction with a setTimout/setInterval, however you would lose the ability to control easing and the duration and it would be very hard to get it right
0
 
RobOwner (Aidellio)Commented:
When you say to the animate object that you want to use a particular easing and duration in conjunction with the start and end parameters, it will work out a number of steps to your animation.  If you want the width to animate at a different rate to your rotation then you need a different function.  In fact you will need a different function for each animation as they will have different start and end points.
0
 
RobOwner (Aidellio)Commented:
The issue here is that jQuery animate does not support more complex css properties such as rotation.  To get rotation to occur you need to set the "transition: rotate(angle)" css property.  Animate will not work with this because of the css rotate function.
0
 
Julian HansenCommented:
Do you means something like this
  $(window).click(function(){
    $('#mallet').css({backgroundColor: 'yellow'})
    setTimeout(function() {
      $('#mallet').css({backgroundColor: 'transparent'})
    }, 3000)
  })

Open in new window

0
 
APD TorontoAuthor Commented:
What if I want to animate 2 properties:

animate by 180deg
increase by 50%
0
 
RobOwner (Aidellio)Commented:
http://jsbin.com/divepim/1/edit?js,output

Just added another function that animates width.  You'll also notice that I've added a "flag" or boolean variable to prevent additional animations happening from multiple clicks on the mallet.

var animating = false;
$(function() {
  $("#mallet").on("click",function() {
    if (animating) {return;}
    animating = true;
    AnimateRotate(0,180);
    AnimateWidth($('#mallet').width(),$('#mallet').width()*1.5);
    setTimeout(function() {
      AnimateRotate(180,360);
      AnimateWidth($('#mallet').width(),$('#mallet').width()/1.5);
      setTimeout(function() {animating=false;},250);
    },1250);
  });
});

function AnimateRotate(start, angle) {
  // caching the object for performance reasons
  var $elem = $('#mallet');

  // we use a pseudo object for the animation
  // (starts from `0` to `angle`), you can name it as you want
  $({deg: start}).animate({deg: angle}, {
    duration: 250,
    step: function(now) {
      // in the step-callback (that is fired each step of the animation),
      // you can use the `now` paramter which contains the current
      // animation-position (`0` up to `angle`)
      $elem.css({
        transform: 'rotate(' + now + 'deg)'
      });
    }
  });
}
function AnimateWidth(start, size) {
  // caching the object for performance reasons
  var $elem = $('#mallet');
  $({w: start}).animate({w: size}, {
    duration: 250,
    step: function(now) {
      $elem.css({
        width: now
      });
    }
  });
}

Open in new window

0
 
APD TorontoAuthor Commented:
Thank you
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 10
  • 9
Tackle projects and never again get stuck behind a technical roadblock.
Join Now