0.0.8 • Published 1 year ago

solid-canvas v0.0.8

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

🎨 solid-canvas

pnpm

a solid wrapper around the Canvas API 226027716-6c1653bb-9db9-43ef-9da5-43452530c495

source

source

source

source

source

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 Shape2D also has a controller-prop which accepts functions that alter the component's prop: an example of this is Drag

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 Shape2Ds inherit from Group, so you can clip and add children to any Shape2D

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

  • Path component
    • accepts an svg path constructed with utility-functions from solid-canvas/d example
    • accepts a raw svg path-string
  • MouseEvents for Shape2D 👉 Shape2D.onMouseDown, Shape2D.onMouseMove and Shape2D.onMouseUp
  • MouseEvents for Canvas 👉 Canvas.onMouseDown, Canvas.onMouseMove and Canvas.onMouseUp
  • HoverStyles for Shape2D
  • Navigation
    • Pan (draggable-prop in Canvas)
    • Zoom
  • Controller-prop: callback which can control the props
  • Handles-controller
    • Line
    • Bezier
    • Quadratic
    • Rectangle
    • Arc
  • Nestable <Canvas/> to divide scene up for optimization (p.ex static background-canvas and dynamic player-canvas)
  • OffscreenCanvas / Offscreen-prop: offload rendering to webworker
  • HTML component: easy way to implement html in Canvas coordinate system
  • Masking with destination-in see
  • Caching any Object2D by rendering result to OffscreenCanvas

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
0.0.8

1 year ago

0.0.7

1 year ago

0.0.6

1 year ago

0.0.5

1 year ago

0.0.4

1 year ago

0.0.3

1 year ago

0.0.2

1 year ago

0.0.1

1 year ago