指针事件监听器,形状手势 - 如何?[包含图形示例]

2 javascript html5 canvas gesture

建立

我想创建一个网页,当用户的光标位于屏幕的某个区域,并且他"绘制"该区域中的假想圆圈时,javascript会检测到该手势并执行一项功能.对于正方形,将执行不同的功能.

我从未见过这样做,但我相信使用javascript和HTML5画布,它应该是完全可能的.

题:

我怎么能以一种允许我检测用户不完美的手势形状输入并让我的脚本区分不同手势/形状的方式来做到这一点?

在此输入图像描述

注意:

这不仅仅是一个触摸屏功能.它必须使用用户的鼠标使用普通光标.

伟大的用途:

网站可以使用此功能允许用户使用鼠标和手动手势快捷方式访问特定页面,或触发用户在网站中经常使用的功能.例如,用户可以在任何堆栈溢出页面的中心绘制问号,以直接发送到新的问题页面.甚至可以允许用户自己制作手势以查看喜欢的问题,转到主页或提交当前问题页面的答案.

sle*_*man 6

我一直想要自己实现这样的东西但是用于不同的用例.我希望我的用户能够手工绘制"圆圈"和"矩形"和"钻石",我的软件将用完美的圆形,矩形和钻石替代它们而不是原始的扭曲线.这是一个简单的图表/图表绘制webapp我想到的.

无论如何,我们需要的是从用户不完美的手绘图中检测形状.我想我对如何做到这一点有一个粗略的想法.

几年前,我在Tcl wiki上遇到了一个简单的玩具手写识别应用程序.它没有使用花哨的AI或任何东西来检测字母,而是使用了一个聪明的图片"散列"技术.

这个想法基本上是这样的:

  1. 将您的书写区域划分为区域 - 最简单的是网格,但它可以是奇数形状的区域,以提高准确性.

  2. 当用户绘制某些内容时,请浏览区域列表并检测其中是否有"墨水".

  3. 如果有"墨水",则将区域的值设置为1.如果未将其设置为0.这将为您提供1和0的数组(或字符串).如果您已经累积了一个数组,则将其转换为字符串.这个字符串是你的绘图"哈希".

  4. 将此"哈希"与形状哈希数据库进行比较.完全匹配是不太可能的,因此使用像Levenshtein距离这样的模糊匹配函数来找到最接近的匹配.

  5. 如果找到匹配(在合理的阈值内),那么你已经找到了你的形状(在原始算法中它是一个字母或数字但是这个想法可以推广到形状).

以下是检测三角形的一个示例:

Sample triangle:
. . . . . . . . . . . . . . . .
0     1     2  #  3     4     .
.     .     . # # .     .     .
. . . . . . .#. .#. . . . . . .
5     .     #     #     .     .
.     .    #.     .#    .     .
. . . . . # . . . . # . . . . .
10    .  #  .     .  #  .     .
.     . #   .     .   # .     .
. . . .#. . . . . . . .#. . . .
15    #     .     .     #     .
.    #.     .     .     .#    .
. . # . . . . . . . . . . # . .
20 #  .     .     .     24 #  .
. ########################### .
. . . . . . . . . . . . . . . .
Run Code Online (Sandbox Code Playgroud)

从上面的ASCII艺术.数据库中的示例三角形生成"哈希":

00100
01110
01010
11011
11111
Run Code Online (Sandbox Code Playgroud)

重新排列为一个字符串:0010001110010101101111111.

现在让我们比较一个非常糟糕的三角形用户绘图:

User drawing:
. . . . . . . . . . . . . . . .
0     1     2 #   3     4     .
.     .     . # # .     .     .
. . . . . . .#. .#. . . . . . .
5     .      #     #    .     .
.     .     #     . #   .     .
. . . . . # . . . . # . . . . .
10    . #   .     . #   .     .
.     .#    .     .  #  .     .
. . . .#. . . . . . . .#. . . .
15    #     .     .      #    .
.   # .     .     .     . #   .
. .#  . . . . . . ### . .  #. .
20### .     .#### .  ## 24  # .
.    #######.     .    ###### .
. . . . . . . . . . . . . . . .
Run Code Online (Sandbox Code Playgroud)

其哈希值为:0010001110010101111111111.将其与数据库中的原始三角形进行比较:

  triangle: 0010001110010101101111111
   drawing: 0010001110010101111111111
difference: -----------------1-------
Run Code Online (Sandbox Code Playgroud)

现在将绘图与其他形状的散列进行比较:

    circle: 0111011011100011101101110
   drawing: 0010001110010101111111111
difference: -1-1-1-1-111-11--1--1---1

    square: 1111110001100011000111111
   drawing: 0010001110010101111111111
difference: 11-111111111-11-111------

   diamond: 0111001010100010101001110
   drawing: 0010001110010101111111111
difference: -1-1---1--11-111-1-11---1
Run Code Online (Sandbox Code Playgroud)

由于三角形是最佳匹配,我们假设用户正在尝试绘制三角形.

我一直在考虑一些策略来提高算法的可靠性.

  1. 而不只是存储1和0存储0,1,2.这使得数据库中的哈希值成为"灰度"哈希,这可能使我们能够捕获非常糟糕的形状.
  2. 而不是仅存储1和0存储0,1和"不关心",这可以允许我们过滤掉图中的噪声并且可以改善匹配.
  3. 获取绘图的边界矩形而不是使用固定网格,然后将绘图划分为区域.这允许我们使用相同的散列检测具有相同散列和正方形和矩形的圆和椭圆.它还适用于比预期更小或更大的图纸.

至于如何记录绘图 - 这取决于你.您可以使用画布,SVG甚至只使用onmousemove轮询鼠标坐标.