手写笔画压感测试

用笔在下面写字,越用力线越粗。右侧会实时读出压力值、倾斜角和笔身旋转,落笔后才能判断这支笔到底有没有压感。

在画布上落笔

先轻轻写几个字,再用力写几个字,压力值应该明显跟着变。线宽用的是 1 + 13 × √压力,只做展示,不带任何笔刷调校。

当前压力 0.000,对应线宽约 1.0 px。

为什么「有数值」不等于「有压感」

PointerEvent 的 pressure 在规范里有一个默认值:鼠标按下时固定报 0.5。这个设计的目的是让不区分输入设备的程序也能拿到一个合法数值,不用到处判断设备类型。代价是「pressure 大于 0」这件事完全没有信息量——鼠标、没有压感的手写笔、甚至某些触摸屏都会给出一个固定的非零值。所以判断压感只能看压力值有没有分级,本页的结论就是这么来的。

倾斜和压感是两套独立能力。tiltX 与 tiltY 描述的是笔杆相对屏幕平面的倾角,单位是度,取值范围 −90 到 90;把两者合成可以算出一个总倾角,用来判断笔是不是快放平了。笔身旋转(twist)又是另一回事,它描述笔绕自身轴转了多少度,只有少数设备支持,缺失时恒为 0,和「正好转到 0 度」在数值上无法区分。

线宽用平方根映射而不是线性映射,原因是压力在低段的变化手感最明显。线性映射时轻轻一按只让线宽变化百分之几,看起来像没反应;平方根会把低段拉开,轻重之间的差别一眼就能看出来。这也是绝大多数绘画软件的默认做法,本页只是照这个思路做展示。

掌压误触在网页端基本无解。浏览器拿到的是原始指针事件,手掌和笔在系统看来都是 pointer,没有可靠的物理特征可以做区分。真正的解决要在系统层:iPad 的 Scribble、Surface 的墨迹识别都是在驱动或系统服务里判断的。网页能做的是只对 pointerType 为 pen 的输入落笔,但这样也就测不出「笔被误识别成手指」这类问题了,所以本页故意不过滤。

想测多点触控和屏幕有没有死区,用触控与多点触控测试;想确认键盘的每个键都能上报,用键盘按键测试;如果是数位板搭配显示器使用,色彩和均匀性可以先用屏幕测试过一遍。

常见问题

笔能写字,但压力值一直是 0.5?

0.5 是鼠标按下时的固定值,也是「设备没有压感」时浏览器给的默认值。先看左边的类型显示:如果写的是笔却显示「鼠标」或「手指触控」,说明系统没有把笔单独上报给浏览器。检查系统里的笔设置、换一支支持压感的笔,或在平板上用支持 Apple Pencil 的浏览器试试。

压感有变化,但画出来的线条粗细不明显?

先看压力值的范围。如果只在 0.4 到 0.6 之间小幅变化,说明压感分级很粗,常见于入门级触控笔;如果范围接近 0 到 1 但线条仍然变化小,多半是绘画软件里的笔刷设置压住了力度曲线。这个页面按 1 + 13 × √压力 把压力换算成线宽,只做展示,没有做任何手感调校。

倾斜角一直是 0,是不是笔不支持?

不一定。部分笔只上报倾斜的一轴,部分只在悬停时才上报。把笔杆压到接近平放再试一次;如果仍然为 0,说明这支笔没有把倾斜信息交给浏览器。倾斜和压感是两套独立的能力,有压感不代表有倾斜。

手掌放上去也会画线,怎么避免?

掌压误触要靠系统或应用做判断,浏览器拿到的总是原始指针事件,没法可靠区分手掌和笔。iPad 上的 Scribble、Surface 的墨迹识别都在系统层处理这件事。网页端能做的是:只对 pointerType 为 pen 的输入落笔,这需要应用自己实现,本页为了能测出问题没有做过滤。

笔迹有断点、画快了会丢线?

最常见的原因是浏览器事件被节流:合成器为了跟上帧率会合并高频的 pointermove。可以在控制台里看采样点数——画一笔很快的线,采样点明显偏少就说明被合并了。降低系统缩放、换用支持 pointerrawupdate 的浏览器,或者把画布尺寸调小,都能改善。

鼠标点上去为什么也有压力值?

规范规定鼠标按下时 pressure 固定为 0.5,这样不区分设备的应用也能拿到一个合法的数值。它不代表力度,只是「按下」的占位值。所以本页判断压感时看的是压力值有没有分级,而不是有没有大于 0。

手机上用手指画,压力值一直是 1?

大多数手机屏幕不测压力,只有少数机型支持 3D Touch 一类的力度感应,而且各家上报方式不同。手指能给出的可靠信息是接触面积(width / height),但浏览器对它的支持也很不一致。想在手机上测压感,基本只能靠外接手写笔。