Skip to the content

Drag canvas

A wall of cards with no edge: pictures of a collection, projects, products.

Become a member to unlock the full effect today.

Join now

Already a member? Sign in

Documentation

  1. Copy to Webflow

    Add Geist and Geist Mono to your site's fonts (Site settings, Fonts, Google Fonts) before pasting: Webflow removes any font your site has not installed.

  2. Add custom CSS

    Give the canvas a height: once mounted the cards are placed by the script and no longer push the box open. The size of a card is not a class here but the width and height settings, which the script hands to the stylesheet. And leave the transform of a card to the engine, which writes it every frame.
  3. Add custom JS

  4. Use it on your own elements

    Custom attributes
    Select the element on the canvas and open the Settings panel. Under Custom attributes, add a pair: the name on the left, the value on the right.
    Custom attributeWhat it does
    data-drag-canvas Marks the box that holds the cards. It takes no value: leave the value field empty. That box is the canvas: what the hand drags, what the effect is mounted on and what carries the settings. It takes its height from the page. Without it on any box of the page, the embed marks the parent of every card it finds (data-drag-canvas-card).
    data-drag-canvas-card Marks one card, a direct child of the canvas. It takes no value. A card can be a link: a plain click still opens it, a drag never does. Without it on any card, the canvas takes its own children as the cards. [ Optional ]
    data-drag-canvas-image Marks the picture of a card, the element that slides inside it as the wall goes by. It takes no value. Without it the first image of the card is taken; a card with no image simply does not slide. [ Optional ]
    data-drag-canvas-state Written by the engine on the canvas once mounted: ready. Never written by hand; the stylesheet reads it to clip the canvas, keep the gesture and take the cards out of the flow. [ Optional ]
    data-drag-canvas-dragging Written by the engine on the canvas while a drag runs. Never written by hand; the stylesheet reads it for the closed hand. [ Optional ]
    data-drag-canvas-clone Written by the engine on the copies of the cards it adds to fill the wall, each one hidden from screen readers and out of the Tab order. Never written by hand. [ Optional ]
    Settings
    Every setting is a custom attribute too, added the same way and on the same element. An attribute always wins over the defaults written in the code.
    AttributeDefaultWhat it is
    data-drag-canvas-tint #15100c Colour of the veil laid on the cards away from the pointer, the ink in the cream and ink look. Options: any CSS colour; taken out of this block, --drag-canvas-tint on the canvas takes over.
    data-drag-canvas-veil 0.16 Strength of that veil, 0 to 1, on a card out of the pointer's reach.
    data-drag-canvas-width clamp(150px, 17vw, 300px) Width of a card, any CSS unit.
    data-drag-canvas-height clamp(188px, 21.25vw, 375px) Height of a card, any CSS unit.
    data-drag-canvas-gap clamp(10px, 1.2vw, 20px) Space between two cards, on both axes, any CSS unit.
    data-drag-canvas-stagger 0.5 How far every other column sits lower, as a share of one cell, 0 to 1.
    data-drag-canvas-friction 0.05 Share of its speed a thrown wall loses on each frame, 0 to 1.
    data-drag-canvas-ratio 1 How far the wall travels for one pixel of hand travel.
    data-drag-canvas-snap 0 Whether a throw comes to rest with one card in the middle of the canvas, 0 or 1.
    data-drag-canvas-wheel 1 Whether the wheel and the trackpad move the wall, 0 or 1.
    data-drag-canvas-lift 1.05 Scale of the card right under the pointer.
    data-drag-canvas-reach clamp(220px, 30vw, 520px) Radius around the pointer inside which cards lift and clear, any CSS unit.
    data-drag-canvas-parallax 0.05 How far a picture slides inside its card as the card crosses the canvas, as a share of the card, 0 to 0.2.

What it does

Drag canvas is a cursor animation for Webflow and vanilla JavaScript, with no library. Also called infinite draggable grid, infinite draggable gallery or infinite draggable scrollable grid.

A wall of cards with no edge: pictures of a collection, projects, products. The hand grabs it anywhere, with the mouse, a pen or a finger, and drags it in every direction; released, the wall runs on with the speed it was given, slows down on its own and comes to rest. The cards of the page come round again on both axes, in a sequence shifted from row to row so the same card never sits beside itself. Every card is a real element, a link that still opens on a plain click, and the script keeps only as many on the page as one canvas can show: a card that leaves on one side is moved to the cell that enters on the other. Near the pointer the cards lift a little and stay clear while the others take a light veil of the tint, and each picture slides inside its card as the wall goes by, which gives the wall its depth. The wheel and the trackpad move it, the arrow keys move it by one card, and Tab reaches each card and brings it to the middle. No library. Under reduced motion the wall follows the hand and nothing runs on, lifts or slides.

Updated

Questions

Add the custom attribute data-drag-canvas to a box and data-drag-canvas-card to each card, its direct children. Give the box a height of its own, because the script places the cards and they no longer push it open. Settings are attributes on that box, for instance data-drag-canvas-snap="1", and the size of a card is one of them: data-drag-canvas-width and data-drag-canvas-height.

No. It has no library: the drag is written on pointer events, and the throw is a glide that fades the speed read from the last 100 ms of the drag. Each card is a real element, and a card that leaves on one side is moved to the cell that enters on the other, so the page only holds as many as one canvas can show.

Set data-drag-canvas-friction, the share of its speed a thrown wall loses on each frame, 0.05 by default. Lower lets it glide a long way before it stops, higher stops it almost where the hand left it. data-drag-canvas-snap="1" makes every throw, wheel and arrow land on a centred card.

It can. A finger on the canvas never scrolls the page, because the canvas keeps both axes of a swipe with touch-action: none: on a phone, keep it shorter than the screen or make it the whole page. With a mouse the canvas keeps the wheel by default, so write data-drag-canvas-wheel="0" on a canvas that sits in the middle of a long page.

Yes. A press that travels less than six pixels opens the card's link, and a drag never opens one. The arrow keys move the wall by one card, Tab reaches each card and brings it to the middle, and the copies are hidden from a screen reader, which reads each card once.