Jump to content
Search Community

draggable onDrag hitTest with a timer

phoenixrip test
Moderator Tag

Go to solution Solved by OSUblake,

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Hi gsap gurus.


Just wondering what the smartest way of setting some kind of timer / timeout in a hitTest that is occurring in the onDrag function, so that I can run a function/animation only if the hitTest has been true for more than 0.8 seconds?


Thanks in advance :)



Link to comment
Share on other sites

I'd hesitate to say this is the smartest way, but it seems to meet the requirements.

In simple terms, as soon as the onDrag detects a hit I record the hitStartTime I then fire a function every 0.2 seconds using delayedCall to check if the hitTest is still true. 


I didn't comment it a ton but the console logs should give you an idea of what is happening as you drag


var hitStartTime = 0;
var maxHitTime = 500 //ms

Draggable.create(".green", {
  type: "x,y",
  onDrag: function() {
    if (this.hitTest(".orange") && hitStartTime == 0) {
      hitStartTime = Date.now();
      console.log("first hit", hitStartTime)
      TweenLite.delayedCall(0.2, startCount)

function startCount() {
  if (Draggable.hitTest(".green", ".orange")) {
    console.log("still hitting");
    if (Date.now() - hitStartTime > maxHitTime) {
      console.log("maxHitTime exceeded");
      hitStartTime = 0;
      //do this after maxHitTime exceeded
      TweenLite.set("body", {backgroundColor:"hsl(" + parseInt(Math.random() * 255) + ", 100%, 50%)"})
      TweenLite.set("h1", {color:"hsl(" + parseInt(Math.random() * 255) + ", 100%, 50%)"})
    } else {
      //check again in 0.2 seconds
      TweenLite.delayedCall(0.2, startCount)
  } else {
    console.log("done hitting")
    hitStartTime = 0;



  • Like 2
Link to comment
Share on other sites

  • Solution

Here's another way to do this. Create a flag and a paused delayedCall. The flag is just a quick way to let you know that the timer has started.


If you detect a hit and the flag is false, restart the delayedCall and set the flag. If the flag is set and you detect a hit, do nothing. If the flag is set and there is no hit, pause the delayedCall and clear the flag. 

var draggable = new Draggable(foo, {
  onDrag: function() {
    // We're not hitting the target
    if (!this.hitTest(hitTarget)) {
      // We were hitting the target
      if (this.hitID) {
        this.hitID = 0;
    // We just hit the target
    if (!this.hitID) {

draggable.hitID = 0;
draggable.hitTimer = TweenLite.delayedCall(0.7, function() {
  // your callback

See the Pen ?editors=0011 by osublake (@osublake) on CodePen


  • Like 5
Link to comment
Share on other sites

Yes :) :)

Both of these work perfectly! Wish I could mark both as solved. Thank you both so much for such quick and easy to understand answers!


Blake I'm now wondering for a different but similar interface if there is an easy way of applying a similar sort of delay to your beautiful SortableGrid example, so that instead of switching positions in the array and re-laying out every element you hover over on your way to a new location, it only switches the none dragged item with the empty spot when you've been over its row/col for a little bit (preserving the order of the rest of the array a little more deliberately).


I'm gonna have a go at this myself, but I figured since the master is here I might ask :)


Thanks again guys! Really appreciate it.

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...