Search the Community

Showing results for tags 'draggable'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • HTML5 / JS
    • GSAP
    • Banner Animation
    • Jobs & Freelance
  • Flash / ActionScript Archive
    • GSAP (Flash)
    • Loading (Flash)
    • TransformManager (Flash)

Product Groups

  • Club GreenSock
  • TransformManager

Categories

There are no results to display.


Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


AIM


MSN


Website URL


ICQ


Yahoo


Jabber


Skype


Location


Interests

Found 460 results

  1. Kuba

    Draggable transform origin

    Hi, I want .home__links-container element to rotate around smiley face. To see exactly what I mean you can open codepen in Firefox or uncomment .home__links-container styling (starts in line 22) and handleRotate function (starts in line 1) and comment out TweenLite.set (line 13). The problem is that on Chrome the .home__links-container element that contains links is bigger than parent <svg> and the circle menu is not in the middle of .home__links-container. On Firefox however .home__links-container has (almost) the same size as parent <svg> and rotation works as expected - see screenshots https://imgur.com/a/Udzvx1D. I don't understand why Chrome doesn't calculate transformOrigin set by TweenLite correctly. Can someone help me with this? I can set Draggable rotate on parent svg but then smiley face rotates too and I want to avoid it.
  2. I tried to place my page using Draggable.js on an Android WebView but it seems like it's not working after I dragged something. It works on the Chrome app though. This is my WebSettings for the WebView. String UA = "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19" + " (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19"; WebSettings settings = webView.getSettings(); settings.setJavaScriptEnabled(true); settings.setLoadWithOverviewMode(true); settings.setSupportZoom(false); settings.setBuiltInZoomControls(false); settings.setPluginState(android.webkit.WebSettings.PluginState.ON_DEMAND); settings.setDatabaseEnabled(true); settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL); settings.setRenderPriority(WebSettings.RenderPriority.HIGH); settings.setCacheMode(WebSettings.LOAD_DEFAULT); settings.setDomStorageEnabled(false); settings.setUseWideViewPort(true); settings.setAllowFileAccess(true); settings.setAppCacheEnabled(true); settings.setUserAgentString(UA); This is my whole code. import android.content.Context; import android.content.DialogInterface; import android.net.http.SslError; import android.os.Build; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.DragEvent; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.webkit.ConsoleMessage; import android.webkit.CookieManager; import android.webkit.SslErrorHandler; import android.webkit.WebChromeClient; import android.webkit.WebResourceError; import android.webkit.WebResourceRequest; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.EditText; import android.widget.RelativeLayout; import android.widget.TextView; public class MainActivity extends AppCompatActivity { WebView webView; SwipeRefreshLayout swiLyt; String url = ""; Context ctx = this; String TAG = "simpler"; String httpReq = ""; TextView lbl; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView = findViewById(R.id.webview); swiLyt = findViewById(R.id.swiLyt); lbl = findViewById(R.id.lbl); httpReq = "http://"; swiLyt.setEnabled(false); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { webView.setWebContentsDebuggingEnabled(true); } final WebViewClient webClient = new WebViewClient(){ @Override public void onPageFinished(WebView view, String url) { swiLyt.setRefreshing(false); lbl.setText(url); fullScreen(); } @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { AlertDialog.Builder dlgBuild = new AlertDialog.Builder(ctx); dlgBuild.setTitle("Error"); dlgBuild.setMessage("Err: "+errorCode+" desc: "+description); dlgBuild.setCancelable(false); dlgBuild.setPositiveButton("Ok", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { dialogInterface.dismiss(); } }); super.onReceivedError(view, errorCode, description, failingUrl); } @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { AlertDialog.Builder dlgBuild = new AlertDialog.Builder(ctx); dlgBuild.setTitle("Error"); dlgBuild.setMessage("Err: "+error.toString()); dlgBuild.setCancelable(false); dlgBuild.setPositiveButton("Ok", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { dialogInterface.dismiss(); } }); super.onReceivedError(view, request, error); } @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { handler.proceed(); AlertDialog.Builder dlgBuild = new AlertDialog.Builder(ctx); dlgBuild.setTitle("SSL Error"); dlgBuild.setMessage("Err: "+error.toString()); dlgBuild.setCancelable(false); dlgBuild.setPositiveButton("Ok", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { dialogInterface.dismiss(); } }); super.onReceivedSslError(view, handler, error); } }; WebChromeClient webChromeClient = new WebChromeClient() { @Override public boolean onConsoleMessage(ConsoleMessage consoleMessage) { AlertDialog.Builder dlgBuild = new AlertDialog.Builder(ctx); dlgBuild.setTitle("Console"); dlgBuild.setMessage(consoleMessage.message()); dlgBuild.setCancelable(false); dlgBuild.setPositiveButton("Ok", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { dialogInterface.dismiss(); } }); return super.onConsoleMessage(consoleMessage); } }; String UA2 = "Mozilla/5.0 (Linux; Android 5.1.1; Nexus 5 Build/LMY48B; wv) AppleWebKit/537.36" + " (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.65 Mobile Safari/537.36"; WebSettings settings = webView.getSettings(); settings.setJavaScriptEnabled(true); settings.setLoadWithOverviewMode(true); settings.setSupportZoom(false); settings.setBuiltInZoomControls(false); settings.setPluginState(android.webkit.WebSettings.PluginState.ON_DEMAND); settings.setDatabaseEnabled(true); settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL); settings.setRenderPriority(WebSettings.RenderPriority.HIGH); settings.setCacheMode(WebSettings.LOAD_DEFAULT); settings.setDomStorageEnabled(false); settings.setUseWideViewPort(true); settings.setAllowFileAccess(true); settings.setAppCacheEnabled(true); settings.setUserAgentString(UA2); webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); webView.setWebViewClient(webClient); webView.setWebChromeClient(webChromeClient); webView.setVerticalScrollBarEnabled(false); webView.setHorizontalScrollBarEnabled(false); webView.setLongClickable(true); webView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View view) { Log.d(TAG, "long click"); return false; } }); webView.setOnDragListener(new View.OnDragListener() { @Override public boolean onDrag(View v, DragEvent event) { return false; } }); showDlg(); } public void showDlg(){ RelativeLayout lyt = new RelativeLayout(ctx); final EditText txt = new EditText(ctx); RelativeLayout.LayoutParams lytParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); txt.setHint("ip:port"); txt.setLayoutParams(lytParams); lyt.addView(txt); txt.setText("192.168.149.59/pos_mock_up"); AlertDialog.Builder dlgBuild = new AlertDialog.Builder(ctx); dlgBuild.setTitle("Enter ip:port"); dlgBuild.setCancelable(false); dlgBuild.setView(lyt); dlgBuild.setPositiveButton("Ok", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { String ipPort = txt.getText().toString(); if(!ipPort.contains(httpReq)){ url = httpReq+ipPort; } Log.d(TAG, "url: "+url); swiLyt.setRefreshing(true); webView.loadUrl(url); } }); dlgBuild.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { dialogInterface.dismiss(); } }); AlertDialog dlg = dlgBuild.create(); dlg.show(); } @Override public void onBackPressed() { webView.loadUrl("javascript:OnBackPressed()"); } private void fullScreen(){ final View decorView = getWindow().getDecorView(); decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); decorView.setOnSystemUiVisibilityChangeListener (new View.OnSystemUiVisibilityChangeListener() { @Override public void onSystemUiVisibilityChange(int visibility) { // Note that system bars will only be "visible" if none of the // LOW_PROFILE, HIDE_NAVIGATION, or FULLSCREEN flags are set. if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) { // The system bars are visible. Make any desired // adjustments to your UI, such as showing the action bar or // other navigational controls. decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); } else { // The system bars are NOT visible. Make any desired // adjustments to your UI, such as hiding the action bar or // other navigational controls. decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); } } }); } } Sorry, I don't really know how to create a test but that code above is everything I only used for the project I'm working. This is my layout file if you need it. <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swiLyt" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> a<WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" > </WebView> </android.support.v4.widget.SwipeRefreshLayout> <TextView android:id="@+id/lbl" android:layout_width="0dp" android:layout_height="wrap_content" android:textColor="#0000ff" android:textSize="18sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> </android.support.constraint.ConstraintLayout>
  3. I keep getting a lot of questions asking about creating sortable lists with Draggable, so I'm just going to make a post about it. My sortable grid example is outdated, and I no longer use that technique, so I'm not going to update it. It relies on hit testing, which I would no longer recommend doing for grids/lists. A better way is to create a model of your list, and map the location of your draggable to that model. This is real easy to do using arrays. You can use the index of an array to represent a cell location in the grid. Draggable already creates an array for you if you use the .create() method, so you could use that if you really wanted to. But first you need to figure out the size of the cells in your list. If everything is uniform, you could probably just divide the size by the number of items in that dimension. If my list is 400px high, and there are 4 elements, the cell size for a row is 100. Notice how the cell size may not be the same size as your element. The cells are in red. When you drag, you can figure out the index of a cell like this. var index = Math.round(this.y / rowSize); This can result in errors if you drag outside of your list, so you should clamp the values like this. var index = clamp(Math.round(this.y / rowSize), 0, totalRows - 1); function clamp(value, a, { return value < a ? a : (value > b ? b : value); } Now you can easily determine where everything is. You also need to keep track of the last index, and compare it to the index you calculate while dragging. If they are different, this means your draggable is inside a different cell, so you need to update your layout. Before you can change the layout, your first need to change the items in your array. Here's a function you can use to move stuff around in an array. arrayMove(myArray, oldIndex, newIndex); function arrayMove(array, from, to) { array.splice(to, 0, array.splice(from, 1)[0]); } Now that your array is in the correct order, you can update the layout. If you were using an array of draggables, you could animate the entire layout like this. myArray.forEach((draggable, index) => { if (!draggable.isDragging) { TweenLite.to(draggable.target, 0.4, { y: index * rowSize }); } }); That's pretty much it! Doing it this way is not only easier, but it performs a lot better, making it really smooth. I made a demo based off of this Framer.js example. It's about 100 lines of code, and is pretty easy to understand. For comparison, The Framer.js example is about 180 lines of code.
  4. Hi guys, I just want to contribute with my findings in case others ran into this. I had been struggling getting GSAP's Draggable to work with Next.js and have finally found a solution. Next.js does Server Side Rendering (SSR) so pages rendered on the server had issues loading the GSAP NPM modules. Please note that pages worked just fine client-side. ERROR: import TweenLite, { _gsScope, globals, EventDispatcher } from "./TweenLite.js"; ^^^^^^ SyntaxError: Unexpected token import To resolve the issue with GSAP not being transpiled, I installed next-plugin-transpile-modules npm install --save next-plugin-transpile-modules Then I modified/created my next.config.js file according to their instructions on their NPM page. https://www.npmjs.com/package/next-plugin-transpile-modules Draggable finally worked after that (only if throwProps was set to false and you did not import ThrowPropsPlugin). However, if using a plugin like ThrowPropsPlugin.js it would display an error message like: TypeError: Cannot read property 'defaultView' of undefined Around line 515 of the ThrowPropsPlugin.js file, I changed it: //FROM THIS: _doc = _gsScope.document, //TO THIS LINE I FOUND IN DRAGGABLE: _doc = _gsScope.document || {createElement: function() {return _dummyElement;}}, After that, I just did "npm run dev" and the pages rendered on the server side were fully functional as expected. Hopefully this helps somebody out! Guys at GSAP, is there any harm in changing that line in the ThrowPropsPlugin? If not, would it be a good idea to update the plugin and other plugins for others who purchased the membership with GSAP so they don't run into this issue that I encountered?
  5. Niek Roemahlewang

    Swipecube Navigation

    Hi all, Recently I made this 3D cube and I can't seem to get the navigation to work properly: I used this example of Chris Gannon: https://codepen.io/GreenSock/pen/3ff3af968fb3356423998050b0ae1d42?editors=0010 to create the cube and interaction. Dragging works fine with snapping, but when you click on the navigation buttons while the cube is tweening, 90 degrees are added, so the cube isn't 'snapping' anymore and it look likes the cube hasn't turned all the way. I've added a check to prevent this, but still no luck. Is there a way to disable the click while the cube is tweening? Or should I use some sort of 'snap' to allow the cube to turn only by 90 degrees. Any help is very much appreciated!
  6. Hello... how can get this overflow-x to scroll with a nice flick ? and be bound to the overflowed container ? Could flexbox be part of the problem ? I've forked one of Diaco's pens from another post. Thank you for the help!
  7. DraggableSock

    Draggable not working with React 16.5

    First of all, congrats for all stuff GSAP! This is a wonderful piece of work! Secondly, I've encountered issues with Draggable, while using React 16.5: Using Draggable.create(target) doesn't allow the user to drag the element at all. A 3d transform is set on the element, having all 0px values, but the element itself doesn't move. The onDrag / onDragEnd / onDragStart handlers aren't called. On the other hand, the onPress handler is called, but two times every click, once with a PointerEvent type event payload, and with a MouseEvent, the second time. Also, it's important to point out that using GSAP 1.19.1 / 2.0.0 / 2.0.2 with React 16.4 and lower doesn't reproduce the issue, nor does it cause the onPress handler to be called twice. It only gets called once, with a PointerEvent. However, I was able to reproduce this issue using GSAP 1.19.1 / 2.0.0 / 2.0.2, with React 16.5. If there's anything more needed, I'll happily provide more details. componentDidMount() { const lis = document.getElementsByTagName('li'); Draggable.create(lis, { cursor: 'grab', onPress(event) { console.log(event); }, onDragEnd() { TweenMax.to(this.target, 0.5, { x: 0, y: 0 }); } }); } Thanks in advance!
  8. b0dg4n

    Draggable with create-react-app

    I am trying to get a div to rotate on drag using the Draggable api in a fresh create-react-appinstallation. I cannot seem to get it to rotate. Here is my App.js file: import React, { Component } from 'react'; import { Draggable } from 'gsap/all' class App extends Component { componentDidMount() { Draggable.create('.draggable', { type: 'rotation', onPress: function() { console.log('clicked'); }, }); } render() { return ( <div> <h2>React & GSAP Draggable</h2> <div className='draggable'>Drag and rotate me</div> </div> ); } } export default App; When I press the div, I can see the clicked log to console, but the div stays put when dragging. TweenMax works fine: TweenMax.to(target, 3, { color: 'red', })
  9. I don't find an example from the draggable knob that does following (based on my codepen live example): - knob is on position 15 percent - I tap (touch) on position 70 percent - knob moves to position 70 percent It is only possible to tap and move (drag) to that position. I don't find anything in your docu. A "simple" answer from you will be "tap or touch" is not "drag". But this doesn't help me. A link that explains what I want. https://radmie.github.io/ng-knob/ My link to my codepen live example. I want only show the missed functionality (compared to the upper example, based on ng-knob). For a review it's to complex. But interesting for you. Hopefully. When you want play with different predefined variants than change line 20 in "JS". https://codepen.io/TirochH/pen/eGqbNL Here a link from a "simple" example from "Greensock" with the same missed functionality (with rotation angle, instead percentage). https://codepen.io/PointC/pen/eWNRpe Hans
  10. Hey there forums! This is kind of more of a general javascript question than a greensock question, though it does involve greensock! I'm trying to build off of this codepen I found - My goal is essentially to create more boxes and targets and have certain boxes with a class of 'incorrect'. I'd like to check for when a box with the class of 'incorrect' is on a target with a Check Answers button that I've created. The difficulty I'm having is trying to add a class of "wrong" to the targets when a box with the class of "incorrect" is snapped onto a target. My theory is that then with the Check Answers button I can just look for targets that have the class of "wrong" added to them. I've started building off of this codepen on my own - Where I've changed the first box to the color blue and added the class of "incorrect" to it. In the CSS panel I also added a class of "wrong" and changed the width to 300px for now in the class, so I will know if my code is working. I wrote the function: if (e.target.hasClass("incorrect")) { $(targets[i]).addClass("wrong"); } I'm still learning, so I hope this function is written correctly? Essentially wanting to add the class "wrong" to targets which have a box with the class of "incorrect" snapped to them. But wherever I put this function in the onDragEnd function, it seems to break things. . . right now it's at the bottom of my code and commented out. I've never seen a function as long as this onDragEnd one with so many nested if statements, so I'm pretty confused as to how everything is firing off and where I could put my function without mucking everything up? Any help is much appreciated!
  11. Hi there, first post on the forums and absolute GSAP newbie - so please be patient I have created an abstract map in SVG (effectively a SVG group <g id="groupAll"> of boxes and lines between them), which I have made draggable by applying Draggable.create("#groupAll", {type:"x,y", edgeResistance:0.65, dragClickables: true}); My question is: How can I use TweenLite.to() to reset the transformation applied by the Draggable? I see that Draggable applies its transformation to the <g>'s style:"transform: matrix3d(...)" but I don't know which value to "cache" beforehand and to set it in the TweenLite.to() Using the transform value with "matrix3d(...)" doesn't work. Thanks for your help! AndyZ
  12. I am working on some concentric circles that should rotate infinitely, until a user clicks on one of them, in which case it should stop the animated rotation and be draggable (rotation). Then, if a different circle is clicked, the new one should stop it's animation, but the previous one should start up again from the position where the user left it after dragging, but with it's original direction and speed. I have managed to get the pausing/unpausing behavior working correctly, except for the fact that if the user drags a band a lot (say, rotating it around fully 2 or 3 times in the same direction), when the animation restarts, it's either going the wrong speed, or the wrong direction, or both. The animation is this: export const bandRotation = (element, rotateDir, rotateSpeed) => { const rotateDeg = rotateDir === "right" ? 360 : -360; const tl = new TimelineLite(); tl.to(element, rotateSpeed, { transformOrigin: "50% 50%", rotation: rotateDeg, repeat: -1, ease: Linear.easeNone }); return tl; }; I've tried a couple different ways of stopping and starting it: if (this.props.paused) { this.state.rotation.kill(); } else { this.setState({ rotation: bandRotation(this.band, this.props.direction, this.props.speed) }); } and: if (this.props.paused) { this.state.rotation.pause(); } else { this.state.rotation.invalidate(); this.state.rotation.restart(); } both of which I would think would restart the animation normally, but again, it's either going the wrong speed, wrong direction, or both. What can I do to ensure the animation restarts with the same speed and direction, no matter how the user drags the circle/band while the animation is paused?
  13. I am trying to set up some concentric circles that are draggable/rotatable, and I'm trying to set it up on <g> tags because there are going to be some smaller SVGs that need to rotate around as if they were attached to the large color bands. I read the pinned SVG gotchas thread, and although it doesn't mention <g> tags, it's clear that it should work because it works here: Some notes about my codesandbox demo: I had some issues trying to use TweenLite by including gsap as a dependency and using a regular import, so I commented out the imports and added CDN links to TweenMax and Draggable in index.html. Clearly Draggable is loaded and works because I also made an extra draggable div just to make sure. The ultimate behavior I am looking to get is that the concentric bands should be rotating infinitely. If a user clicks on one of the bands, the rotation stops and the band becomes draggable. Once the user clicks on a different band, the rotation starts up again. There are two sections of code that are commented out right now, but if you uncomment them you will see the rotation animation/pausing behavior working. The part that's eluding me is the draggability. All the important stuff is happening in the BaseBand.jsx file. Any pointers on how to get draggable rotation working on an SVG <g> tag would be very welcome.
  14. HaunGo

    swipe & flick ?

    I thought there was a GSAP plugin for swiping and flicking ? good for mobile . Am I thinking of the Draggable plugin ? I just need to swipe/drag/and flick while that motion also controls a separate TimelineMax. Any thoughts or suggestions ? Also, I'm looking to do a bit of scroll hijacking.. so, if theres GSAP related solutions for that, I'd love to know! Thanks !
  15. joshlopez

    snap to center of div & replace

    Hello all, I am new around here. I am having 2 issues currently. I am trying to make my draggable boxes snap to the center of my target box. Currently they are snapping way off. lol When a new draggable box is put on the target box, i need any other box currently on the target box to move back to its original position. Thank you for your help, I really appreciate it.
  16. 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"}); } }
  17. reference: https://greensock.com/docs/Utilities/Draggable/hitTest var element1 = green; var element2 = red; if (Draggable.hitTest(element1, element2)) { console.log('HIT!'); } #green { transform: rotate(45deg); } Always triggers HIT! everytime element1(green) enters the area demonstrated as "blue box" even if it doesn't hit element2(red) demo: see attached image Is there any possible way to fix this issue as I wanted to trigger 'HIT!' only when green touches red (given that I want to rotate this image/div), Thanks in advance
  18. Seb-AS

    Draggable + zoom out

    Hi, It's my first time using gsap with react(used a lot in as3), and I've a lot of questions if someone can show me an example o guide me in the right direction. I need to make a map like "google maps", the map it's a div with a background-image and inside svg with point. The issue I'm having it's if I drag the map the +/- buttons scale the map but in the wrong position, my idea it's if I scale up the the map then drag then scale down it should come back and animate to the starting position. Now I'm forcing to move to the starting position if the scale it's equal to 1 window.TweenLite.set(this.map, {force3D: true, ease: ease, scale: minScale, transformOrigin: "center center", x: 0, y: 0, z: .001}); Hope it's something easy to fix. Thanks
  19. elrojo

    Multiple Drag Instances

    Is it possible to have multiple drag instances? Attached pen keeps failing... var count; for(count = 0; count < 2; count++){ console.log(count) Draggable.create("box" + count, { bounds:"#container", edgeResistance:0.5, throwProps:true, lockAxis:true, onDrag:function() { TweenLite.to(document.getElementsByClassName("original" + count), 1, {x:this.x}); }, onThrowUpdate:function() { TweenLite.to(document.getElementsByClassName("original" + count), 1, {x:this.x}); } }); }
  20. benoit

    draggable rotation value

    Hi, I use the draggable plugin. Is there a simple way to return the rotation value between 0 and 360 deg ? I play with something like that : var r = (r + 3600) % 360; It's work but, it's not proof. How can I fixe this?
  21. Deepak Oberoi

    How to limit Draggable to a path

    I want to limit a Draggable within a Path given for an AVG Layer. if that's possible? I read about bounds but it says container or XY cordinates can be passed in bounds if we can pass an SVG path to bounds? something like http://jsfiddle.net/JwkYm/8/
  22. How can I clear z-index from a draggable after releasing it, so that new page elements don't appear beneath the draggable item?
  23. I am using a draggable knob along an svg path. The path is a quadratic bezier curve which has the y coordinates going up and then down. How should I progress the draggable instance so that I am able to fill the path while dragging the knob on the path? To simply put it, I want the path to be filled while dragging the knob and the portion of the path to be filled should be only upto the knob. Also the mouse pointer should be in sync with the draggable knob. Any suggestions or leads are appreciated.
  24. Hey guys, I feel like calling kill() on a Draggable instance should probably clean up after itself and reset the DOM element it was invoked on to it's pre-initialization state. Currently it leaves 'user-select: text' on the inline style attribute of each element, overwriting any default user-select settings that may have been previously defined (inline or css). See line 903 in Draggable.js _setSelectable = function(elements, selectable) { var i = elements.length, e; while (--i > -1) { e = elements[i]; e.ondragstart = e.onselectstart = selectable ? null : _emptyFunc; _setStyle(e, "userSelect", (selectable ? "text" : "none")); } } I can of course manually clean up the style in my implementations (which is what I currently do) but I think it would be much cleaner if Draggable would keep an internal reference to any style properties it is going to modify and reset the element to that reference after the Draggable instance is killed. Sorry for being nitpicky. Keep up the great work! Jonathan
  25. I have taken the Codepen for "Draggable with "droppable" logic" (located here) and forked it and rewritten a lot of it to to get the effect i am looking for. basically, i do not want any draggable item to EVER overlap any any other draggable item. I spent a good part of the morning today searching the forum and reading up in the docs trying to think of some form of simple collision detection. The idea being to detect a collision and have a simple collision event that would make the divs bounce off of each other. that is not built in to gsap (should be!) and I have not found anyone on the forum who has successfully done it. So I must try. What I have in my sample is the result of banging my newbie head on my monitor all day! it is not 100% collision detection (like I'm used to seeing in Unity) but it does prevent overlaps in a clunky sort of way. If you drag, say, box1, over any other box it will be tweened 100px repeatedly until it is no longer overlapping. Additionally, there is a recursiveness in the function calls. If, while moving box1 away from box2, box1 then overlaps box3, the recursive will continue to cycle the functions and the tween will be repeated until box1 is no longer overlapping any box. This works regardless of which box you drag around and drop. I say it is clunky because it tweens 100px, pauses, tweens another 100px, pases...and so forth until the dreaded overlapping is cured. Where I am stuck is replacing the 100px with the amount of overlap (plus some small amount so the box ends up a little bit away from the last box it overlapped). I have commented the code so you can see the varible names, etc. and understand what i am struggling with. As an added bonus, it would be nice, but not strictly necessary, to remove the clunkiness I mentioned above. One final comment, it may appear that this if for a game. It is not. I would do this in Unity if it were a game - or maybe Buildbox. This is actually just one step along the path I have chosen to build a "unique" interface for a desktop app I want to build using Electron.