Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
elrojo

Draggable Loop with Vanilla JS and Greensock

Recommended Posts

This code was inherited from @blakebowen draggable loop however his implementation is using jQuery and I am trying to convert to regular JS.

 

Any thoughts on why this may not be firing?


 

var $overflow = document.getElementById("overflow");
var $viewport = document.getElementsByClassName("viewport");
var $wrapper  = document.getElementsByClassName("wrapper");
var $boxes    = document.getElementsByClassName("boxes");
var $proxy    = document.getElementById("box1"); //$("<div/>") 

var numBoxes  = 4;  
var boxWidth  = 350;
var boxHeight = 250;  
var imgWidth  = boxWidth  - 6;
var imgHeight = boxHeight - 14;
var viewWidth = $viewport.offsetWidth;
var wrapWidth = numBoxes * boxWidth;
var progress  = 0;

var xMin = 0;
var xMax = 0;

TweenLite.set([$wrapper, $viewport], { height: boxHeight, xPercent: -50 });
TweenLite.set($boxes, { left: -boxWidth });

// for (var i = 1; i <= numBoxes; i++) {

//   // var src = "https://unsplash.it/" + imgWidth + "/" + imgHeight + "?random=" + i;
//   // var num = $("<div class='num'/>").text(i);    
//   // var img = $("<img />", { src: src, width: imgWidth, height: imgHeight });
//   //var box = $("<div class='box'/>").append(img).append(num).appendTo($boxes);
//   var box = document.getElementsByClassName("box")
//   console.log(boxWidth)
//   TweenLite.set(box, { x: i * boxWidth, width: boxWidth, height: boxHeight });
// }

var animation = TweenMax.to(".box", 1, {
  x: "+=" + wrapWidth, 
  ease: Linear.easeNone,
  paused: true,
  repeat: -1,
  modifiers: {
    x: function(x, target) {
      x = x % wrapWidth;
      target.style.visibility = x - boxWidth > viewWidth ? "hidden" : "visible";
      return x;
    }
  }
});

Draggable.create($proxy, {
  type: "x",
  trigger: ".wrapper",
  throwProps: true,
  // onDragStart: setRange,
  onDrag: updateProgress,
  onThrowUpdate: updateProgress,
  snap: { 
    x: snapX 
  }
});

$overflow.on("change", applyOverflow);
$(window).resize(resize);

function snapX(x) {
  return Math.round(x / boxWidth) * boxWidth;
}

function updateProgress() {  
  // var norm = normalize(this.x, xMin, xMax);
  animation.progress(this.x / wrapWidth);
}


function resize() {
  viewWidth = $viewport.width();
  animation.render(animation.time(), false, true);
}

function applyOverflow() {
  if($overflow.prop("checked")){
    TweenLite.set(".wrapper", {overflow:"visible"});
  }else {
    TweenLite.set(".wrapper", {overflow:"hidden"});
  }
}


 

See the Pen YvpRNa?editors=1010 by anon (@anon) on CodePen

Link to comment
Share on other sites

Hi,

 

This code makes it work:

 

var $overflow = document.getElementById("overflow");
var $viewport = document.getElementsByClassName("viewport");
var $wrapper  = document.getElementsByClassName("wrapper");
var $boxes    = document.getElementsByClassName("boxes");
var $proxy    = document.getElementById("box1");

var numBoxes  = 4;  
var boxWidth  = 350;
var boxHeight = 250;  
var imgWidth  = boxWidth  - 6;
var imgHeight = boxHeight - 14;
var viewWidth = $viewport[0].offsetWidth;
var wrapWidth = numBoxes * boxWidth;
var progress  = 0;

var xMin = 0;
var xMax = 0;

TweenLite.set([$wrapper, $viewport], { height: boxHeight, xPercent: -50 });
TweenLite.set($boxes, { left: -boxWidth });

var animation = TweenMax.to(".box", 1, {
  x: "+=" + wrapWidth, 
  ease: Linear.easeNone,
  paused: true,
  repeat: -1,
  modifiers: {
    x: function(x, target) {
      x = x % wrapWidth;
      target.style.visibility = x - boxWidth > viewWidth ? "hidden" : "visible";
      return x;
    }
  }
});

Draggable.create($proxy, {
  type: "x",
  trigger: ".wrapper",
  throwProps: true,
  onDrag: updateProgress,
  onThrowUpdate: updateProgress,
  snap: { 
    x: snapX 
  }
});

$overflow.onchange = applyOverflow;
$(window).resize(resize);

function snapX(x) {
  return Math.round(x / boxWidth) * boxWidth;
}

function updateProgress() {  
  animation.progress(this.x / wrapWidth);
}


function resize() {
  console.log($viewport[0].offsetWidth);
  viewWidth = $viewport[0].offsetWidth;
  animation.render(animation.time(), false, true);
}

function applyOverflow() {
  if($overflow.checked){
    TweenLite.set(".wrapper", {overflow:"visible"});
  }else {
    TweenLite.set(".wrapper", {overflow:"hidden"});
  }
}

 

Just needed to remove some jquery methods and use onchange instead of on in the checkbox.

 

Happy Tweening!!

  • Like 3
Link to comment
Share on other sites

Thanks @Rodrigo - looks like all the images are stacked however? Anythoughts?

 

 

This doesn't seem to work.

 

for (var i = 1; i <= numBoxes; i++) {
  var box = document.getElementsByClassName("box");
  TweenLite.set(box, { x: i * boxWidth, width: boxWidth, height: boxHeight });
}

 

Link to comment
Share on other sites

Sorry I didn't went through all the code. What's the idea here, have a horizontal stripe of images to drag/throw and snap I presume?.

 

My knowledge of flex is quite limited (working on backend and PIXI for too long does that to you :roll:) so I'd suggest to look how that can be done. Also consider that the element have an absolute position. Also how the progress is being calculated via the drag/throw update and being applied.

 

I managed to get something barely useful with this css:
 

.box {
  flex-grow:0;
}

.boxes {
  display: flex;
  position: relative;
  flex-direction: row;
}

 

This creates a horizontal stripe with the images, but there are some issues with the progress of the tween. Unfortunately I don't have a lot of time to go through the and get what the issue is, but my suggestion is to first get the animation to work, like this:
 

https://codepen.io/rhernando/pen/RVLBGJ

 

And when that's working like that go to the draggable part of it to calculate and apply the progress.

 

Use this pen from the GreenSock collection to understand how the modifiers plugin works:

See the Pen QEdpLe by GreenSock (@GreenSock) on CodePen

 

 

https://greensock.com/modifiersPlugin

 

Happy Tweening!!

  • Like 3
Link to comment
Share on other sites

TweenMax.set(".box", {
  x:function(i) {
    return i * boxWidth;
  }
});

this solved it :)

  • Like 3
Link to comment
Share on other sites

 

3 hours ago, elrojo said:

This code was inherited from @blakebowen draggable loop however his implementation is using jQuery and I am trying to convert to regular JS.

 

Sorry, jQuery is all I know.

 

Not really. That demo is a fork of that modifiers plugin demo which uses jQuery, so I kept it.

  • Like 1
  • Haha 4
Link to comment
Share on other sites

1 hour ago, OSUblake said:

Sorry, jQuery is all I know.

 

Mhh.. I see you're rehearsing your stand up comedy routine 

  • Haha 5
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.
×