Skip to content

iOS 与 Android 差异 ​

两个平台上的 JavaScript API 相同,但绘制引擎不同。iOS 把绘制交给 Apple 的 PencilKit。Android 使用自研视图,把每一笔绘制成贝塞尔曲线,线宽随手指速度变化。本页把所有差异集中在一起。

渲染 ​

iOSAndroid
引擎PencilKit 的 PKCanvasView自研 View,绘制到离屏位图
线宽由 PencilKit 根据压感和速度自行调整。工具宽度为 penMinWidth 与 penMaxWidth 的中点。max(penMaxWidth / (velocity + 1), penMinWidth),速度单位为 dp/ms。慢则粗,快则细。
velocityFilterWeight忽略对样本之间的速度做平滑(默认 0.7)
defaultInkTypepen、marker、pencil;iOS 17+ 另有 monoline、fountainPen、watercolor、crayon(更早版本回退为 pen)忽略
手写笔Apple Pencil 的压感和倾斜会影响墨迹与手指相同,pencilOnly 除外

为什么 Android 有自己的渲染器 ​

Android 没有可与 PencilKit 相比的系统墨迹引擎。Android 视图是签名板中常见的基于速度方法的原生移植:每个新的触摸样本都会用最近四个点构建一段三次贝塞尔曲线,线宽在每段曲线内从起点到终点逐渐变化。笔画绘制在位图中,所以继续书写时,已完成的笔画不需要重绘。

你可以在 Props 页面试用同一算法的 JavaScript 版本。

默认值 ​

PropiOSAndroid
penColorblack#111111
toolbarHeight4448
toolbarTintColor视图的 tint color(系统蓝)各图标自身的颜色。见工具栏颜色。
baselineColor50% 不透明度的系统灰#80808080
baselineOffsetFromBottom816
baselineStyle="dotted" 时的 baselineWidth1.52

如果希望两个平台外观一致,请显式设置这些 props。

历史记录 ​

iOSAndroid
undo() 撤销的对象最后一笔、clear() 或 setStrokeData()最后一笔
clear()可以撤销不能撤销,并且会清空重做栈
setStrokeData()可以撤销之前的内容会丢失;undo() 会逐笔移除恢复的笔画
新的一笔清空重做栈清空重做栈

导出 ​

iOSAndroid
PNG 背景始终透明设置了 backgroundColor 则包含
saveToPhotoLibrary 的 PNG不透明,未设置 backgroundColor 时为白色设置了 backgroundColor 则包含,否则透明
剪贴板通过 UIPasteboard 写入透明的裁剪 PNG通过 FileProvider URI 写入带背景的裁剪 PNG
trim 边距2 pt0.6 × penMaxWidth dp + 2 px
SVG 单位与线宽pt,每笔取平均宽度物理像素,(penMinWidth + penMaxWidth) / 2
toFile 位置临时目录缓存目录
saveToPhotoLibrary 结果{ granted };拒绝访问时 granted: false{ granted, uri };写入失败时 granted: false

详见导出格式。

笔画数据 ​

iOSAndroid
坐标ptdp
t自这一笔开始以来的秒数系统开机时长,单位毫秒
额外字段pressure、size、azimuth、altitude无
恢复时的宽度每个点的 size当前的 penMinWidth 和 penMaxWidth

详见笔画数据与回放。

输入 ​

iOSAndroid
pencilOnlyPencilKit 的 drawingPolicy(iOS 14+),忽略手指。只有 TOOL_TYPE_STYLUS 能绘制,手指和手写笔橡皮擦端都会被忽略。
在 ScrollView 中无额外处理一笔开始后,视图会要求父视图不要拦截触摸
压感PencilKit 会使用不使用,线宽只取决于速度
showToolPicker显示 PencilKit 工具选择器忽略

工具栏 ​

iOSAndroid
图标SF Symbols随库附带的同风格矢量图
溢出菜单带图标的原生菜单(iOS 14+),更早版本为操作表只显示标签的 PopupMenu

事件 ​

iOSAndroid
每一笔的 onChange可能触发多次一次
onChange 与 onEnd 的顺序先 onEnd先 onChange
渲染错误信息Failed to encode imageFailed to render bitmap

基于 MIT 许可证发布。