logo

Aki UI

アキ ウイ

Draggable Canvas

ドラッガブルキャンバス

A board larger than its window, moved by grabbing it. The bounds are worked out from the board's own measurements rather than handed a reference, so it can overflow in both directions and still come to rest exactly on its edges — with a little give at the limit so it never feels stuck. Momentum carries a flick. Built with Framer Motion drag↗↗ and Tailwind CSS.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
Drag to move around

Installation

Install the following dependencies:1

npm install framer-motion

Copy and paste the following code into a new component file:2

"use client"

import { motion, useMotionValue } from "framer-motion"
import { useRef, type ReactNode } from "react"

export type CanvasCell = {
id: string | number,
content: ReactNode
}

How to use it3

"use client"

import { DraggableCanvas } from "@/components/ui/draggable-canvas"

const cells = [
{ id: 1, content: <img src="/one.jpg" alt="" /> },
{ id: 2, content: <img src="/two.jpg" alt="" /> },
]

export default function Page() {

Props

DraggableCanvas

NameDefaultDescription
cells—

CanvasCell[]

Tiles laid out across the board

columns4

number

Tiles per row; rows are derived from the count

cellSize140

number

Width and height of a tile in pixels

gap12

number

Space between tiles in pixels

height380

number

Height of the window onto the board

darkfalse

boolean

Render the dark palette

CanvasCell (type)

NameDefaultDescription
id—

string | number

Stable key for the tile

content—

ReactNode

What the tile renders