Code Monkey home page Code Monkey logo

solid-canvas's Introduction

solid-canvas

๐ŸŽจ solid-canvas

pnpm

a solid wrapper around the Canvas API

rec.mp4

source

_rec.mp4

source

_rec2.mp4

source

_rec3.mp4

source

curves.mp4

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>
)

Screenshot 2023-03-22 at 20 36 47

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>
)
_rec3.mp4

<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>
)

Screenshot 2023-03-22 at 20 46 40

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>
)

Screenshot 2023-03-26 at 12 00 18

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 with "&:hover" selector ๐Ÿ‘‰ "&:hover: Shape2DStyles`
  • Transitions for Shape2D: automatic lerping between styles/transforms
  • Navigation
    • Pan (draggable-prop in Canvas)
    • Zoom
  • Controller-prop: callback which can control the props
  • Handles-controller
    • Pan (draggable-prop in Canvas)
    • Zoom
  • Controllers-prop: transform props through a series of composable controller-functions
  • CurveHandles-controller: edit points of Path2D
    • Line
    • Bezier
    • Quadratic
    • Rectangle
    • Arc
  • TransformHandles-controller: edit transform (position, rotation, scale and skew) of Object2D
  • 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 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

solid-canvas's People

Contributors

bigmistqke avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.