Vue-path-recognizer

Path Recognizing component for Vue.

Path-recognizing-component-for-Vue

Installation

npm install vue-path-recognizer --save

Basic usage

Import the PathRecongizer component. PathRecognizer is a container, it requires a child element to capture mouse moves. PathRecognizer does not draw the moves, for a full drawing example, check the example/ folder of this repo.

import PathRecognizer, { PathRecognizerModel } from 'vue-path-recognizer';

export default {
  components: {
    PathRecognizer,
  },
  data() {
    return {
      context: null,
      result: "",
      models: [
        new PathRecognizerModel([7, 1], "A"),
        new PathRecognizerModel([2, 6, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4], "B"),
        new PathRecognizerModel([4, 3, 2, 1, 0], "C"),
      ]
    }
  }
}

Add some path model to the recognizer.
Each path is defined by a direction-sequence and an associated data object.

models: [
  new PathRecognizerModel([7, 1], "A"),
  new PathRecognizerModel([2,6,0,1,2,3,4,0,1,2,3,4], "B"),
  new PathRecognizerModel([4,3,2,1,0], "C"),
  new PathRecognizerModel([2,6,7,0,1,2,3,4], "D"),
  new PathRecognizerModel([4,3,2,1,0,4,3,2,1,0], "E")
}

Wrap your sliding template range


<path-recognizer
  :models="models"
  :onGesture="handleGesture"
  :onStartDraw="handleStartDraw"
  :onMovePath="handleMovePath"
>
  <template v-slot:default="props">
    <div 
      @mousedown="props.onMouseDown"
      @mouseup="props.onMouseUp"
    >
    </div>
  </template>
</path-recognizer>

For example, here the model for the letter E :

56374696f6e732e706e67

Set the models and the onGesture prop on the PathRecognizer component :

  <path-recognizer
    :models="models"
    :onGesture="handleGesture"
    :onStartDraw="handleStartDraw"
    :onMovePath="handleMovePath"
  >
  </path-recognizer>

Note that onGesture({datas}) is always invoked at the end of the drawing. If no gesture is recognized, this parametter is null.

Custom filter

While adding a model, you can specify a custom filter (third parametter of PathRecognizerModel). The filter callback method, if specified, will let you a last chance to modify / analyze the datas to determine a new score.

For example, the letter D & P have a similar draw-direction-path, however you can discriminate each one by detecting the position of the last point (up -> it's a P, down -> it's a D). The PathInfos struct transmited to the filter function will help you to determine the new score.

 filter(infos, model){
    let lastPoint
    switch (model.datas){
      case "P":
        lastPoint = [...infos.deltaPoints].pop()
        if (lastPoint.y > infos.boundingBox.top + infos.boundingBox.height * 0.6) return Number.POSITIVE_INFINITY
        return infos.cost
      case "D":
        lastPoint = [...infos.deltaPoints].pop()
        if (lastPoint.y < infos.boundingBox.top + infos.boundingBox.height * 0.6) return Number.POSITIVE_INFINITY
        return infos.cost
   }
}

For a full example, please consult the example folder of this repo.

API

PathRecognizer props

name type default description
sliceCount Number 8 Resolution of the direction wheel
deltaMove Number 8 Mouse move threshold (pixels)
costMax Number 32 Max cost limit to detect a gesture
models [PathRecognizerModel([Number], Any)] [] Models to recognize
onStartDraw Function() function Invoked when the user mouse down the zone
onMovePath Function([{x:Number, y:Number}]) function Invoked when the user move his mouse during a record session
onStopDraw Function() function Invoked when the user mouse up the zone
onGesture Function(datas:Any) function Invoked with the datas of the model recognized or null if no gesture is recognized

Free path

In this sample project I've used the Graffiti alphabet for the didactic aspect. However, react-path-recognizer is a generic algorithm, you can add any free path to control an interface / game :

65732e676966

References & Original Authors

Didier Brun

GitHub