@tsok-dev/design-system-canvas
v0.0.1
Published
A flexible React component library for creating interactive canvases with support for multiple media types, layers, and floating toolbars/panels.
Readme
Canvas Component Library
A flexible React component library for creating interactive canvases with support for multiple media types, layers, and floating toolbars/panels.
Features
- 🎨 Multi-layer Support: Stack content with z-index, opacity, and blend modes
- 📍 Flexible Zones: 9 predefined zones for toolbars and panels
- 🎬 Media Renderers: Built-in support for images, videos, text, markdown, rich text, and 3D models
- ⚡ Context-based State: Centralized layer and viewport management
- 🎯 Styled Components: Complete theming support
- 📱 Responsive: Adapts to different screen sizes
Installation
npm install @tsok-dev/design-system-canvasBasic Usage
import { Canvas } from '@tsok-dev/design-system-canvas';
function MyApp() {
return (
<Canvas width="100vw" height="100vh">
<Canvas.Viewport backgroundColor="#f8f9fa">
<Canvas.Layer name="Background" zIndex={0}>
<div>Background content</div>
</Canvas.Layer>
<Canvas.Layer name="Foreground" zIndex={1} opacity={0.9}>
<div>Foreground content</div>
</Canvas.Layer>
</Canvas.Viewport>
<Canvas.Zone position="top-left">
<Toolbar />
</Canvas.Zone>
<Canvas.Zone position="center-right">
<LayersPanel />
</Canvas.Zone>
</Canvas>
);
}Components
Canvas
Main container component that provides context for all child components.
interface CanvasProps {
children: ReactNode;
width?: string | number;
height?: string | number;
className?: string;
style?: CSSProperties;
onReady?: () => void;
}Canvas.Viewport
The main content area where layers are rendered. Supports zoom and pan transformations.
interface ViewportProps {
children: ReactNode;
backgroundColor?: string;
className?: string;
}Canvas.Layer
Individual layers within the viewport. Each layer can have different z-index, opacity, and blend modes.
interface LayerProps {
children: ReactNode;
name?: string;
zIndex?: number;
opacity?: number;
visible?: boolean;
locked?: boolean;
blendMode?: string;
className?: string;
}Canvas.Zone
Positioned containers for toolbars and panels. Supports 9 predefined positions.
interface ZoneProps {
position: ZonePosition;
children: ReactNode;
offset?: { x?: number; y?: number };
zIndex?: number;
className?: string;
}
type ZonePosition =
| 'top-left' | 'top-center' | 'top-right'
| 'center-left' | 'center' | 'center-right'
| 'bottom-left' | 'bottom-center' | 'bottom-right';Media Renderers
The library includes several media renderers for different content types:
ImageRenderer
import { ImageRenderer } from '@tsok-dev/design-system-canvas';
<Canvas.Layer>
<ImageRenderer
data="https://example.com/image.jpg"
width={300}
height={200}
fit="contain"
alt="Example image"
/>
</Canvas.Layer>TextRenderer
import { TextRenderer } from '@tsok-dev/design-system-canvas';
<Canvas.Layer>
<TextRenderer
data="Hello World"
fontSize={18}
color="#333"
fontFamily="Arial, sans-serif"
textAlign="center"
/>
</Canvas.Layer>MarkdownRenderer
import { MarkdownRenderer } from '@tsok-dev/design-system-canvas';
<Canvas.Layer>
<MarkdownRenderer
data="# Title\n\nThis is **bold** text."
theme="light"
/>
</Canvas.Layer>RichTextRenderer
import { RichTextRenderer } from '@tsok-dev/design-system-canvas';
<Canvas.Layer>
<RichTextRenderer
data={{
content: '<h1>Rich Text</h1><p>Editable content</p>',
editable: true
}}
onChange={(content) => console.log('Updated:', content)}
/>
</Canvas.Layer>VideoRenderer
import { VideoRenderer } from '@tsok-dev/design-system-canvas';
<Canvas.Layer>
<VideoRenderer
data="https://example.com/video.mp4"
controls={true}
width={400}
height={300}
/>
</Canvas.Layer>ModelRenderer
import { ModelRenderer } from '@tsok-dev/design-system-canvas';
<Canvas.Layer>
<ModelRenderer
data={{
src: "/models/example.glb",
format: "glb"
}}
backgroundColor="#f0f0f0"
enableControls={true}
/>
</Canvas.Layer>Using the Canvas Context
Access canvas state and controls using the useCanvas hook:
import { useCanvas } from '@tsok-dev/design-system-canvas';
function LayerControls() {
const {
state,
addLayer,
removeLayer,
updateLayer,
setActiveLayer,
setZoom,
setPan
} = useCanvas();
const createNewLayer = () => {
const layerId = addLayer({
zIndex: state.layers.length,
opacity: 1,
visible: true,
locked: false
});
setActiveLayer(layerId);
};
return (
<div>
<button onClick={createNewLayer}>Add Layer</button>
<button onClick={() => setZoom(state.zoom * 1.2)}>Zoom In</button>
<button onClick={() => setZoom(state.zoom * 0.8)}>Zoom Out</button>
</div>
);
}Zone Positioning
The Canvas supports 9 predefined zones for placing toolbars and panels:
┌─────────┬─────────┬─────────┐
│ top-left│top-center│top-right│
├─────────┼─────────┼─────────┤
│center- │ center │center- │
│ left │ │ right │
├─────────┼─────────┼─────────┤
│bottom- │bottom- │bottom- │
│ left │ center │ right │
└─────────┴─────────┴─────────┘Advanced Example
import {
Canvas,
ImageRenderer,
TextRenderer,
useCanvas
} from '@tsok-dev/design-system-canvas';
function AdvancedCanvas() {
return (
<Canvas width="100vw" height="100vh">
<Canvas.Viewport backgroundColor="#2c3e50">
{/* Background image layer */}
<Canvas.Layer name="Background" zIndex={0}>
<ImageRenderer
data="https://example.com/background.jpg"
fit="cover"
width="100%"
height="100%"
/>
</Canvas.Layer>
{/* Text overlay with transparency */}
<Canvas.Layer name="Title" zIndex={5} opacity={0.9}>
<div style={{
position: 'absolute',
top: '50px',
left: '50px'
}}>
<TextRenderer
data="Welcome to Canvas"
fontSize={48}
color="white"
fontFamily="Arial Black, sans-serif"
/>
</div>
</Canvas.Layer>
{/* Interactive elements */}
<Canvas.Layer name="Interactive" zIndex={10}>
<div style={{
position: 'absolute',
bottom: '100px',
right: '100px'
}}>
<button>Click me!</button>
</div>
</Canvas.Layer>
</Canvas.Viewport>
{/* Main toolbar */}
<Canvas.Zone position="top-center">
<MainToolbar />
</Canvas.Zone>
{/* Properties panel */}
<Canvas.Zone position="center-right">
<PropertiesPanel />
</Canvas.Zone>
{/* Layer management */}
<Canvas.Zone position="bottom-right">
<LayerPanel />
</Canvas.Zone>
</Canvas>
);
}TypeScript Support
The library is fully typed with TypeScript. All components, props, and hooks have complete type definitions.
Styling
All components are built with styled-components and can be customized using:
- Custom CSS classes via
classNameprop - Styled-components theming
- Direct style overrides via
styleprop
Browser Support
- Modern browsers (Chrome, Firefox, Safari, Edge)
- React 16.8+ (hooks support required)
- TypeScript 4.0+ for type support
Contributing
See the main repository for contribution guidelines.
License
MIT License - see LICENSE file for details.
