跟大家分享一下我实现的一个小工具:@sketchjs
小程序使用的话占用包体积比较大,
taro
主包体积优化插件已经在路上了
给大家介绍一个我实现的一个小工具 ——@sketchjs
。它能实现像写 React Native(RN)一样,相对轻松地完成绘图任务。接下来,就详细跟大家唠唠它。
一、安装轻松上手
- 要是你习惯
npm
,在命令行输入下面这行就行:
npm install @sketchjs/react
- 喜欢
yarn
的话,就执行:
yarn add @sketchjs/react
- 用
pnpm
的朋友,输入:
pnpm add @sketchjs/react
二、多平台支持
不管是 H5 页面,还是 Taro 小程序,都能稳稳地发挥作用。
(一)H5
环境中
在 H5 环境里,可以通过以下代码进行简单的Canvas
绘制:
import React, { useEffect } from 'react'
import { StyleSheet, Sketch } from '@sketchjs/react'
import logo from './logo.png'
import './App.css'
const style = StyleSheet.create({
root: {
width: 500,
height: 500,
backgroundColor: '#282c34'
},
view: {
width: 500,
height: 500,
justifyContent: 'center',
alignItems: 'center'
},
logo: {
width: 200,
height: 200
},
text: {
width: 500,
marginTop: 20,
color: '#ffffff',
fontSize: 50,
fontWeight: 400,
lineHeight: 50,
textAlign: 'center'
}
})
function App () {
const sketch = Sketch.useSketch()
const canvasRef = React.useRef<HTMLCanvasElement>(null)
const handleToDataURL = () => {
const dataUrl = sketch.toDataURL('image/png', 1)
console.log({ dataUrl })
}
const handleSketchUpdate = () => {
console.log('sketch update')
}
const handleSketchInitialized = () => {
console.log('sketch initialized')
}
const initCanvas = () => {
const canvas = canvasRef.current
const ctx = canvas?.getContext('2d')
if (!canvas || !ctx) return
return sketch.init({ canvas, ctx })
}
useEffect(() => {
initCanvas()
}, [])
return (
<div className="App" onClick={handleToDataURL}>
<canvas className="sketch-canvas" ref={canvasRef}/>
<Sketch.Root style={style.root} sketch={sketch} onReady={handleSketchInitialized} onUpdate={handleSketchUpdate}>
<Sketch.View style={style.view}>
<Sketch.Image src={logo} style={style.logo}/>
<Sketch.Text text="Hello World!" style={style.text}/>
</Sketch.View>
</Sketch.Root>
</div>
)
}
export default App
(二)Taro
小程序中
在 Taro 小程序这边,@sketchjs/react
同样没让人失望。
- 首先,得在
taro
项目config/index.ts
中配置下环境变量:
import { defineConfig } from '@tarojs/cli';
export default defineConfig({
defineConstants: {
'process.env.SKETCH_PLATFORM': '"APPLET"', // 使用小程序端 sketch 实现
'process.env.YOGA_USE_WASM': 'false', // 不使用 WASM 实现
},
});
- 接着就是具体的示例代码,和 H5 那边有些类似:
import { View, Canvas } from '@tarojs/components'
import { StyleSheet, Sketch } from '@sketchjs/react'
import logo from '@/assets/logo.png'
import React, { useEffect } from 'react'
import Taro from '@tarojs/taro'
import './index.less'
Sketch.debug = true
const style = StyleSheet.create({
root: {
width: 500,
height: 500,
backgroundColor:'#282c34'
},
rootView: {
width: 500,
height: 500,
justifyContent: 'center',
alignItems: 'center',
},
logo: {
width: 200,
height: 200
},
text: {
width: 500,
marginTop: 20,
color: '#ffffff',
fontSize: 50,
fontWeight: 400,
lineHeight: 50,
textAlign: 'center'
}
})
const Index: React.FC = () => {
const sketch = Sketch.useSketch()
const handleSketchUpdate = () => {
console.log('sketch update')
}
const handleSketchInitialized = () => {
console.log('sketch initialized')
}
const initCanvas = async () => {
const canvasNode: HTMLCanvasElement = await new Promise((resolve) => {
const selectorQuery = Taro.createSelectorQuery()
const callback = (res:any) => resolve(res?.node)
selectorQuery.select('#sketch-canvas').fields({ node: true },callback).exec()
})
const canvasCtx = canvasNode.getContext('2d')
if (!canvasNode || !canvasCtx) return
return sketch.init({canvas:canvasNode, ctx: canvasCtx}).then(()=>sketch.render())
}
useEffect(() => {
initCanvas()
}, [])
return (
<View className='index-view'>
<Canvas id='sketch-canvas' type='2d' className='sketch-canvas' />
<Sketch.Root sketch={sketch} style={style.root} onReady={handleSketchInitialized} onUpdate={handleSketchUpdate}>
<Sketch.View style={style.rootView}>
<Sketch.Image src={logo} style={style.logo} />
<Sketch.Text text='Hello World!' style={style.text} />
</Sketch.View>
</Sketch.Root>
</View>
)
}
export default Index
三、关键绘图组件
@sketchjs/react
和 RN 开发模式相似,用起来比较容易上手。
(一)<Sketch.Root>
组件
在代码里,咱们用 StyleSheet.create
来定义样式赋予它宽高。比如说:
import React from'react';
import { StyleSheet, Sketch } from '@sketchjs/react';
const style = StyleSheet.create({
root: {
width: 500,
height: 500
}
});
function MySketch() {
return (
<Sketch.Root style={style.root}>
{/* 这里面放其他绘图子组件,像 <Sketch.View> 等 */}
</Sketch.Root>
);
}
(二)<Sketch.View>
组件
<Sketch.View>
在绘图区域内划分出一个个子区域,用于对绘图元素进行分组管理。通过 style
属性,我们能运用熟悉的 CSS 布局技巧对其进行调控。以常见的居中布局为例,在代码中:
import React from'react';
import { StyleSheet, Sketch } from '@sketchjs/react';
const style = StyleSheet.create({
rootView: {
width: 500,
height: 500,
justifyContent: 'center',
alignItems: 'center',
},
});
function MySketch() {
return (
<Sketch.Root>
<Sketch.View style={style.rootView}>
{/* 这里面放图片、文本等绘图子组件,它们就能按设定布局展示 */}
</Sketch.View>
</Sketch.Root>
);
}
style.rootView
样式对象定义了子区域的宽度与高度均为500
,justifyContent: 'center'
使得子组件在水平方向上居中对齐,alignItems: 'center'
让子组件在垂直方向上也居中对齐。- 这样一来,不管是
<Sketch.Image>
展示的图片,还是<Sketch.Text>
呈现的文本,都能在这个子区域内找到合适的展示位置,布局整整齐齐的。
(三)<Sketch.Image>
组件
<Sketch.Image>
功能很明确,就是把图片展示在 Canvas 绘图区域里。咱们只要给 src
属性指定图片的路径就行,超级简单。
结合 StyleSheet.create
定义样式来看个例子:
import React from'react';
import { StyleSheet, Sketch } from '@sketchjs/react';
import myImage from './myImage.png'; // 这里引入实际的图片资源
const style = StyleSheet.create({
imageStyle: {
width: 200,
height: 200,
marginLeft: 50, // 还可以设置图片的边距等样式,按需调整
},
});
function MySketch() {
return (
<Sketch.Root>
<Sketch.View>
<Sketch.Image src={myImage} style={style.imageStyle} />
</Sketch.View>
</Sketch.Root>
);
}
- 通过
src
属性把myImage
(指向实际图片文件的路径)传给<Sketch.Image>
组件, - 然后用
StyleSheet.create
生成的style.imageStyle
来设置图片尺寸,像这里设置宽度200
像素,高度200
像素, - 还可以通过其他属性调整图片位置,这样图片就能以咱们想要的样子出现在绘图区域,给画面添彩。
(四)<Sketch.Text>
组件
<Sketch.Text>
组件负责在绘图区域里显示文字内容。咱们用 text
属性写上要显示的文字,再用 style
属性设置字体、大小、颜色、对齐方式这些,文字就能自然融入绘图。
比如这个例子:
import React from'react';
import { StyleSheet, Sketch } from '@sketchjs/react';
const style = StyleSheet.create({
textStyle: {
width: 500,
marginTop: 20,
color: '#ffffff',
fontSize: 50,
fontWeight: 400,
lineHeight: 50,
textAlign: 'center'
},
});
function MySketch() {
return (
<Sketch.Root>
<Sketch.View>
<Sketch.Text text="Hello World!" style={style.textStyle} />
</Sketch.View>
</Sketch.Root>
);
}
- 在这个例子里,
text
属性写上 “Hello World!” style.textStyle
样式对象里设置了文字颜色为白色、字体大小50
像素、居中对齐等- 这样文字就能在绘图区域里以合适的样子出现,和图片等其他元素搭配起来,共同完成绘图效果。
四、总结
总的来说,@sketchjs/react
开发体验还不错,能让咱们像写 RN 代码一样相对轻松地搞定 Canvas 2D 绘图。要是你在绘图开发上也遇到难题,不妨试试它,说不定能帮你省不少事儿,让你的项目绘图功能实现得更顺利。希望对大家的Canvas
绘图开发有点帮助。
目前@sketchjs/react
还是alpha
版本。要是在使用的过程中有什么问题,欢迎提issues
随时交流。
如果这个库在canvas
开发中帮到了你,请给个赞或者github
的star
吧
本文由豆包AI生成如有错漏,辛苦指正。