0.0.8 • Published 3 years ago
solid-canvas v0.0.8
🎨 solid-canvas
a solid wrapper around the Canvas API
Simple example
import { Canvas, Text, Rectangle } from 'solid-canvas'
const App = () => (
<Canvas fill="blue">
<Text position={{ x: 100, y: 100 }} text="hallo" fill="white" size={20} />
<Rectangle
position={{ x: 100, y: 100 }}
dimensions={{ width: 250, height: 250 }}
fill="purple"
stroke="transparent"
/>
</Canvas>
)You can also compose shapes
import { Canvas, Text, Rectangle } from 'solid-canvas'
const App = () => (
<Canvas fill="blue">
<Rectangle
position={{ x: 100, y: 100 }}
dimensions={{ width: 250, height: 250 }}
fill="purple"
stroke="transparent"
>
<Text text="hallo" fill="white" size={20} />
</Rectangle>
</Canvas>
)MouseEvents: draggable <Rectangle/>
import { Canvas, Rectangle } from 'solid-canvas'
const App: Component = () => {
const [selected, setSelected] = createSignal(false)
const [position, setPosition] = createSignal({ x: 100, y: 100 })
return (
<Canvas
onMouseMove={event => {
if (!selected()) return
setPosition(position => ({
x: position + event.delta.x,
y: position + event.delta.y,
}))
}}
onMouseUp={() => setSelected(false)}
>
<Rectangle
position={position()}
dimensions={{ width: 50, height: 50 }}
onMouseDown={() => setSelected(true)}
/>
</Canvas>
)
}Each
Shape2Dalso has a controller-prop which accepts functions that alter the component's prop: an example of this isDrag
import { Canvas, Rectangle } from 'solid-canvas'
const App = () => (
<Canvas>
<Rectangle
position={{ x: 100, y: 100 }}
dimensions={{ width: 50, height: 50 }}
controllers{[Drag()]}
/>
</Canvas>
)<Group/> and Clip
import { Canvas, Rectangle, Group } from 'solid-canvas'
const App = () => (
<Canvas>
<Group
position={{ x: 100, y: 100 }}
clip={() => (
<>
<Rectangle
position={{ x: 0, y: 0 }}
dimensions={{ width: 100, height: 50 }}
/>
<Rectangle
position={{ x: 0, y: 0 }}
dimensions={{ width: 50, height: 100 }}
/>
</>
)}
fill="blue"
>
<Text text="hallo" size={50} />
</Group>
</Canvas>
)All
Shape2Dsinherit fromGroup, so you canclipand addchildrento anyShape2D
Lines: <Line/>, <Bezier/> and <Quadratic/>
import { Bezier, Canvas, Line, Quadratic } from 'solid-canvas'
const App = () => (
<Canvas draggable>
<Line
position={{ x: 100, y: 100 }}
points={[
{ x: 0, y: 0 },
{ x: 50, y: 100 },
{ x: 100, y: 0 },
{ x: 150, y: 100 },
{ x: 200, y: 0 },
{ x: 250, y: 100 },
]}
/>
<Bezier
position={{ x: 500, y: 100 }}
points={[
{ point: { x: 0, y: 0 }, control: { x: 50, y: 0 } },
{ point: { x: 50, y: 100 }, control: { x: -50, y: 0 } },
{ point: { x: 100, y: 0 }, control: { x: -50, y: 0 } },
{ point: { x: 150, y: 100 }, control: { x: -50, y: 0 } },
{ point: { x: 200, y: 0 }, control: { x: -50, y: 0 } },
{ point: { x: 250, y: 100 }, control: { x: -50, y: 0 } },
]}
/>
<Quadratic
position={{ x: 900, y: 150 }}
points={[
{ point: { x: 0, y: 0 }, control: { x: 25, y: -100 } },
{ point: { x: 50, y: 0 } },
{ point: { x: 100, y: 0 } },
{ point: { x: 150, y: 0 } },
{ point: { x: 200, y: 0 } },
{ point: { x: 250, y: 0 } },
]}
/>
</Canvas>
)Canvas API-Coverage
- Object2D
<Group/>- Shape2D
<Text/><Image/>- Path2D
<Rectangle/><Line/><Arc/><Bezier/><Quadratic/>
- Compositing
<Group/>(to 'properly' composite groups we should render to offscreencanvas first)- Shape2D
- Clipping
<Group/>- Shape2D (Shape2D inherits from
Group)
- Color (for fill/stroke)
<Gradient/><Pattern/>
Additional API
Pathcomponent- accepts an svg path constructed with utility-functions from
solid-canvas/dexample - accepts a raw svg path-string
- accepts an svg path constructed with utility-functions from
- MouseEvents for
Shape2D👉Shape2D.onMouseDown,Shape2D.onMouseMoveandShape2D.onMouseUp - MouseEvents for
Canvas👉Canvas.onMouseDown,Canvas.onMouseMoveandCanvas.onMouseUp - HoverStyles for
Shape2D - Navigation
- Pan (draggable-prop in
Canvas) - Zoom
- Pan (draggable-prop in
- Controller-prop: callback which can control the props
- Handles-controller
LineBezierQuadraticRectangleArc
- Nestable
<Canvas/>to divide scene up for optimization (p.ex static background-canvas and dynamic player-canvas) - OffscreenCanvas / Offscreen-prop: offload rendering to webworker
HTMLcomponent: easy way to implement html inCanvascoordinate system- Masking with
destination-insee - Caching any
Object2Dby rendering result toOffscreenCanvas
Overal Ambitions / Roadmap
- Cover the whole Canvas-API
- Provide tools to simplify common canvas operations
- Explore render-optimizations:
- Only render what is in viewport
- Only render the bounds of Shape2Ds that has changed
- Treeshakable: minimal use should result in minimal bundle