An open API service indexing awesome lists of open source software.

https://github.com/udevbe/react-canvaskit

Experiment in creating a custom react renderer using an offscreen webgl canvas on top of Skia CanvasKit
https://github.com/udevbe/react-canvaskit

accelerated canvas canvaskit hardware-acceleration html5 html5-canvas react react-reconciler reactjs skia skia-library webgl

Last synced: 6 months ago
JSON representation

Experiment in creating a custom react renderer using an offscreen webgl canvas on top of Skia CanvasKit

Awesome Lists containing this project

README

          

# React-CanvasKit

![npm](https://img.shields.io/npm/v/react-canvaskit)

Experimental implementation of [Skia CanvasKit](https://skia.org/user/modules/canvaskit) using [ReactJS](https://reactjs.org/).

This implementation allows you to use all familiar React concepts like hooks and contexts, in conjunction with JXS elements that closely match the existing Skia CanvasKit API. Everything is drawn to a hardware accelerated WebGL canvas.

# Examples
#### Paragraph with dynamic font loading
![Alt text](/demos/paragraph-demo/paragraph-demo.gif?raw=true "Paragraph Demo")

```typescript jsx
import type { FunctionComponent } from 'react'
import React from 'react'
import { FontManagerProvider } from 'react-canvaskit'
import ParagraphDemo from './ParagraphDemo'

const robotoPromise = fetch('https://storage.googleapis.com/skia-cdn/google-web-fonts/Roboto-Regular.ttf')
.then((resp) => resp.arrayBuffer())
const notoColorEmojiPromise = fetch('https://storage.googleapis.com/skia-cdn/misc/NotoColorEmoji.ttf')
.then((resp) => resp.arrayBuffer())

const fontsPromise = Promise.all([robotoPromise, notoColorEmojiPromise])

export const App: FunctionComponent = () => {
const [fonts, setFonts] = React.useState(undefined)
fontsPromise.then(fetchedFonts => setFonts(fetchedFonts))

return (



)
}
```

```typescript jsx
import type { SkParagraph } from 'canvaskit-oc'
import React from 'react'
import type { SkObjectRef } from 'react-canvaskit'
import { PaintStyle, TextAlignEnum, useFontManager } from 'react-canvaskit'
import useAnimationFrame from './useAnimationFrame'

const fontPaint = { style: PaintStyle.Fill, antiAlias: true }

const X = 250
const Y = 250
const paragraphText = 'The quick brown fox ๐ŸฆŠ ate a zesty hamburgerfonts ๐Ÿ”.\nThe ๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง laughed.'

export default () => {
const skParagraphRef = React.useRef>(null)
const fontManager = useFontManager()

const calcWrapTo = (time: number): number => 350 + 150 * Math.sin(time / 2000)
const [wrapTo, setWrapTo] = React.useState(calcWrapTo(performance.now()))

useAnimationFrame(time => setWrapTo(calcWrapTo(time)))

return (


{paragraphText}


{`At (${X.toFixed(2)}, ${Y.toFixed(2)}) glyph is '${glyph}'`}

)
}
```

#### Simple Paint
![Alt text](/demos/simple-paint/hello-react-canvaskit.png?raw=true "Hello React-CanvasKit!")

```typescript jsx
const App: FunctionComponent = () => {
return (


Hello React-CanvasKit!



React-CanvasKit.




)
}

const htmlCanvasElement = document.createElement('canvas')
const rootElement = document.getElementById('root')
if (rootElement === null) {
throw new Error('No root element defined.')
}
rootElement.appendChild(htmlCanvasElement)
document.body.appendChild(htmlCanvasElement)
htmlCanvasElement.width = 400
htmlCanvasElement.height = 300

init().then(() => render(, htmlCanvasElement))
```