ZingTouch

repository·master·Indexed 24 days ago

https://github.com/zingchart/zingtouch

A modern JavaScript touch gesture library (v2.0.0) for implementing interactions such as tap, swipe, pan, rotate, and distance. It utilizes a 'Region' abstraction to handle complex touch interactions across different browsers and provides a generic Gesture class for creating custom gestures via lifecycle hooks.

Tokens
5.5K
Snippets
12
Records
29
Agent score
80%

What's inside zingtouch

  1. Avoid mutation pitfalls when binding gestures

    master

    The Problem

    ZingTouch treats gestures as non-mutable events. It expects the element being bound to remain stable between the start and end of a gesture. If you bind a transformation (like moving an element) directly to a gesture callback, the element's bounding box changes, which can invalidate the initial reference points used by ZingTouch and lead to unpredictable behavior.

    The Solution

    Instead of binding the gesture to the element you intend to move, attach the gesture listener to a non-mutating parent container. In the callback, calculate the movement and apply it to your target element. This ensures the gesture's reference point remains stable.

  2. How Regions and Gestures work together

    master

    ZingTouch uses Regions to define the area where it listens for window events (like touchstart, touchmove, etc.). A Region is necessary because ZingTouch needs to track events across the window to accurately determine if a gesture is recognized, even if the user's finger moves outside the target element.

    Key Concepts:

    • Forgiveness: By setting a Region on a parent element rather than the target element itself, you allow the gesture to continue being tracked even if the user's finger moves slightly outside the target boundaries (e.g., during a swipe).
    • Initiation: A gesture can only be initiated on the specific element it is bound to. However, the movement and end of the gesture can occur within the bounds of the Region.
    • Performance: Instead of using a single Region on document.body, it is recommended to split your application into multiple smaller Regions to improve performance by reducing the number of bindings each Region must iterate through.
  3. Install ZingTouch

    master

    You can include ZingTouch in your project using Node/CommonJS, ES6 modules, or a direct <script> tag.

    // Node / CommonJS
    var ZingTouch = require('zingtouch');
    
    // ES6
    import ZingTouch from 'zingtouch';
    <!-- Include the file -->
    <script src='./path/to/zingtouch.min.js'></script>
  4. What is a Region in ZingTouch?

    master

    A Region defines the specific area of the DOM that ZingTouch monitors for input events (like touch or mouse interactions). By specifying a Region, you tell the library which part of the document should feed events into the gesture engine.

    Performance Tip: The more specific the region (e.g., a specific <div> instead of the entire document), the better the application's performance will be, as the library will only monitor events within that bounded area.

  5. Understand the ZingEvent object

    master
    The ZingEvent class is an event wrapper used by ZingTouch to normalize events across different browsers and input devices (such as mouse vs. touch). When you listen to gestures or lifecycle hooks, the event object passed to your callback is an instance of ZingEvent. It provides a consistent interface for accessing coordinates and event types, regardless of whether the input originated from a touch screen or a mouse.
  6. Unbind gestures with Region.unbind()

    master

    Use Region.unbind() to remove gesture listeners from an element. You can unbind a specific gesture or remove all gestures from an element entirely.

    Parameters

    • element: The DOM element to unbind.
    • gesture (optional): The string key of the registered gesture or the specific gesture instance used during binding.

    Returns

    • An array of bindings that were successfully unbound.
    // Unbind from a specific gesture
    var myElement = document.getElementById('mydiv');
    myRegion.unbind(myElement, 'tap');
    
    // Unbind from all gestures
    var myElement = document.getElementById('mydiv');
    myRegion.unbind(myElement);
    
    // Unbind from a specific gesture instance
    var myElement = document.getElementById('mydiv');
    var myRegion = new ZingTouch.Region(document.body);
    var myTapGesture = new ZingTouch.Tap({ maxDelay : 100 });
    
    myRegion.bind(myElement, myTapGesture, function(e) {});
    myRegion.unbind(myElement, myTapGesture);
  7. Create a ZingTouch Region

    master

    A Region specifies an area to listen for all window events. You can reuse regions for multiple elements and gesture bindings.

    Constructor: new ZingTouch.Region(element, [capture], [preventDefault])

    • element: The element to set the listener upon.
    • capture: (Optional) Whether the region listens for captures or bubbles.
    • preventDefault: (Optional) If true, disables browser functionality such as scrolling and zooming over the region.
    var zt = new ZingTouch.Region(document.body);
  8. Bind a gesture only once with Region.bindOnce()

    master
    The Region.bindOnce() method behaves identically to Region.bind(), with one key difference: the gesture is captured exactly once. After the first time the gesture is emitted, the binding is automatically destroyed.
  9. Bind gestures to elements with Region.bind()

    master

    The Region.bind() method allows you to attach gesture listeners to DOM elements. There are two primary ways to use this method:

    1. Direct Binding: Pass the element, a gesture key (string) or instance, and a handler function. This is useful for specific, one-off bindings.
    2. Chainable Binding: Pass only the element. This returns a chainable object that allows you to call gesture methods (like .tap(), .swipe(), etc.) directly. This is often cleaner for multiple bindings on the same element.

    Important Performance Note: When using custom gesture instances, reuse the gesture object instead of creating a new one inside a loop to avoid memory overhead and performance degradation.

    Event Data: The handler function receives a CustomEvent. All gesture-specific data is located in event.detail.

    // Example 1: Direct binding with a gesture key
    var myRegion = new ZingTouch.Region(document.body);
    var myElement = document.getElementById('some-div');
    
    myRegion.bind(myElement, 'tap', function(e) {
    	console.log('Tap gesture emitted: ' + e.detail.interval);
    });
    
    // Example 2: Direct binding with a custom gesture instance
    var myElement = document.getElementById('some-div');
    var myTapGesture = new ZingTouch.Tap({ maxDelay : 100 });
    var myRegion = new ZingTouch.Region(document.body);
    
    myRegion.bind(myElement, myTapGesture, function(e) {
    	console.log('Custom Tap gesture emitted: ' + e.detail.interval);
    }, false);
    
    // Example 3: Chainable binding
    var myElement = document.getElementById('mydiv');
    var myRegion = new ZingTouch.Region(myElement);
    var chainableObject = myRegion.bind(myElement);
    
    chainableObject
    	.tap(function(e){
    		console.log(e.detail);
    	})
    	.swipe(function(e){
    		console.log(e.detail);
    	}, true);
  10. Register and unregister custom gestures

    master

    To use custom gestures with the Region.bind() chainable syntax or via string keys, you must first register them with the Region instance.

    Registering a gesture

    Use Region.register(key, gesture) to associate a string key with a Gesture instance. This makes the gesture available for both direct binding and the chainable .key() syntax.

    Unregistering a gesture

    Use Region.unregister(key) to remove a gesture from the region. Warning: Unregistering a gesture automatically unbinds all elements currently listening to that gesture.

    Returns

    • register: Returns the registered gesture object.
    • unregister: Returns the gesture that was unregistered.
    // Registering
    var myTapGesture = new ZingTouch.Tap({ maxDelay : 60 });
    var myRegion = new ZingTouch.Region(document.body);
    myRegion.register('shortTap', myTapGesture);
    
    // Usage via key
    myRegion.bind(myElement, 'shortTap', function(e){});
    
    // Usage via chainable object
    myRegion.bind(myElement).shortTap(function(e){});
    
    // Unregistering
    myRegion.unregister('shortTap');
  11. Use the generic Gesture class for lifecycle hooks

    master

    The ZingTouch.Gesture class is a generic gesture that does not emit events by default. It is intended to be used as a base for creating custom gestures by hooking into ZingTouch's lifecycle events: start, move, and end.

    new ZingTouch.Gesture()
  12. Configure the Rotate gesture

    master

    A Rotate is detected when two inputs move in a circle or one input moves circularly around the center of the bound target.

    Emits:

    • angle: Angle of the initial right-most input relative to the unit circle.
    • distanceFromOrigin: Angular distance traveled by the initial right-most input.
    • distanceFromLast: Change in angle between the last position and current position. Positive is counter-clockwise, negative is clockwise.
    new ZingTouch.Rotate()