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