├── .babelrc
├── .gitignore
├── LICENSE
├── README.md
├── assets
├── Vue-path-recognizer.jpg
├── directions.png
├── other_moves.gif
└── screencast.gif
├── example
├── .babelrc
├── .gitignore
├── README.md
├── package-lock.json
├── package.json
└── src
│ ├── App.vue
│ ├── index.html
│ └── index.js
├── package-lock.json
├── package.json
├── src
├── PathRecognizer.vue
└── index.js
└── webpack.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env"],
3 | "plugins": [
4 | "babel-plugin-transform-class-properties",
5 | "transform-async-to-generator"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | tmp
3 | ppt
4 | app
5 | .vscode
6 | *.lnk
7 | /.sass-cache
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 vue-path-recognizer
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | 
4 |
Path recognizing component for Vue
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | [](https://www.npmjs.com/package/vue-path-recognizer)
18 |
19 | ## Demo
20 |
21 |
22 | ## Installation
23 | ```bash
24 | npm install vue-path-recognizer --save
25 | ```
26 |
27 | ## Basic usage
28 |
29 | 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.
30 |
31 | ```js
32 | import PathRecognizer, { PathRecognizerModel } from 'vue-path-recognizer';
33 |
34 | export default {
35 | components: {
36 | PathRecognizer,
37 | },
38 | data() {
39 | return {
40 | context: null,
41 | result: "",
42 | models: [
43 | new PathRecognizerModel([7, 1], "A"),
44 | new PathRecognizerModel([2, 6, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4], "B"),
45 | new PathRecognizerModel([4, 3, 2, 1, 0], "C"),
46 | ]
47 | }
48 | }
49 | }
50 | ```
51 | Add some path model to the recognizer.
52 | Each path is defined by a direction-sequence and an associated data object.
53 |
54 | ```js
55 | models: [
56 | new PathRecognizerModel([7, 1], "A"),
57 | new PathRecognizerModel([2,6,0,1,2,3,4,0,1,2,3,4], "B"),
58 | new PathRecognizerModel([4,3,2,1,0], "C"),
59 | new PathRecognizerModel([2,6,7,0,1,2,3,4], "D"),
60 | new PathRecognizerModel([4,3,2,1,0,4,3,2,1,0], "E")
61 | }
62 | ```
63 | Wrap your sliding template range
64 | ```html
65 |
66 |
72 |
73 |
77 |
78 |
79 |
80 |
81 | ```
82 |
83 | For example, here the model for the letter E :
84 |
85 | 
86 |
87 | Set the models and the onGesture prop on the PathRecognizer component :
88 |
89 | ```html
90 |
96 |
97 | ```
98 |
99 | Note that onGesture({datas}) is always invoked at the end of the drawing. If no gesture is recognized, this parametter is null.
100 |
101 | ## Custom filter
102 | 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.
103 |
104 | 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.
105 |
106 | ```js
107 | filter(infos, model){
108 | let lastPoint
109 | switch (model.datas){
110 | case "P":
111 | lastPoint = [...infos.deltaPoints].pop()
112 | if (lastPoint.y > infos.boundingBox.top + infos.boundingBox.height * 0.6) return Number.POSITIVE_INFINITY
113 | return infos.cost
114 | case "D":
115 | lastPoint = [...infos.deltaPoints].pop()
116 | if (lastPoint.y < infos.boundingBox.top + infos.boundingBox.height * 0.6) return Number.POSITIVE_INFINITY
117 | return infos.cost
118 | }
119 | }
120 | ```
121 |
122 | For a full example, please consult the example folder of this repo.
123 |
124 | ## API
125 |
126 | ### PathRecognizer props
127 |
128 |
129 |
130 |
131 | name |
132 | type |
133 | default |
134 | description |
135 |
136 |
137 |
138 |
139 | sliceCount |
140 | Number |
141 | 8 |
142 | Resolution of the direction wheel |
143 |
144 |
145 | deltaMove |
146 | Number |
147 | 8 |
148 | Mouse move threshold (pixels) |
149 |
150 |
151 | costMax |
152 | Number |
153 | 32 |
154 | Max cost limit to detect a gesture |
155 |
156 |
157 | models |
158 | [PathRecognizerModel([Number], Any)] |
159 | [] |
160 | Models to recognize |
161 |
162 |
163 | onStartDraw |
164 | Function() |
165 | function |
166 | Invoked when the user mouse down the zone |
167 |
168 |
169 | onMovePath |
170 | Function([{x:Number, y:Number}]) |
171 | function |
172 | Invoked when the user move his mouse during a record session |
173 |
174 |
175 | onStopDraw |
176 | Function() |
177 | function |
178 | Invoked when the user mouse up the zone |
179 |
180 |
181 | onGesture |
182 | Function(datas:Any) |
183 | function |
184 | Invoked with the datas of the model recognized or null if no gesture is recognized |
185 |
186 |
187 |
188 |
189 | ## Free path
190 |
191 | 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 :
192 |
193 | 
194 |
195 | ## References & Original Authors
196 | [Didier Brun](https://github.com/didierbrun)
197 |
198 |
199 | ## License
200 | MIT © [MikeCheng1208](https://github.com/MikeCheng1208)
201 |
--------------------------------------------------------------------------------
/assets/Vue-path-recognizer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MikeCheng1208/Vue-path-recognizer/cdb362d20a70567bac26a3e244bde2e5dc64a680/assets/Vue-path-recognizer.jpg
--------------------------------------------------------------------------------
/assets/directions.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MikeCheng1208/Vue-path-recognizer/cdb362d20a70567bac26a3e244bde2e5dc64a680/assets/directions.png
--------------------------------------------------------------------------------
/assets/other_moves.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MikeCheng1208/Vue-path-recognizer/cdb362d20a70567bac26a3e244bde2e5dc64a680/assets/other_moves.gif
--------------------------------------------------------------------------------
/assets/screencast.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MikeCheng1208/Vue-path-recognizer/cdb362d20a70567bac26a3e244bde2e5dc64a680/assets/screencast.gif
--------------------------------------------------------------------------------
/example/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | presets: [
3 | [
4 | '@babel/preset-env',
5 | {
6 | modules: false
7 | }
8 | ]
9 | ]
10 | }
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | .cache
2 | dist
3 | node_modules
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # Vue-path-recognizer Example
2 |
3 |
4 | ## Building and running on localhost
5 |
6 | First install dependencies:
7 |
8 | ```sh
9 | npm install
10 | ```
11 |
12 | To run in hot module reloading mode:
13 |
14 | ```sh
15 | npm start
16 | ```
17 |
18 | To create a production build:
19 |
20 | ```sh
21 | npm run build-prod
22 | ```
23 |
24 | ## Running
25 |
26 | ```sh
27 | node dist/bundle.js
28 | ```
29 |
--------------------------------------------------------------------------------
/example/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-path-recognizer-example",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "vue-path-recognizer": {
8 | "version": "1.0.6",
9 | "resolved": "https://registry.npmjs.org/vue-path-recognizer/-/vue-path-recognizer-1.0.6.tgz",
10 | "integrity": "sha512-i55Fo10W1tV/rdkML5ENrjZQrr4RuVqwfkyZBMRmigDyW0PZUgetzq4mStv2vZzmyrHVUMH2hFy0jQimnTXLiQ=="
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-path-recognizer-example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "keywords": [],
7 | "author": "",
8 | "license": "ISC",
9 | "scripts": {
10 | "clean": "rm dist/bundle.js",
11 | "start": "parcel src/index.html",
12 | "build-prod": "parcel build src/index.html"
13 | },
14 | "dependencies": {
15 | "vue": "^2.6.10",
16 | "vue-hot-reload-api": "^2.3.3",
17 | "vue-path-recognizer": "^1.0.6"
18 | },
19 | "devDependencies": {
20 | "@babel/core": "^7.5.0",
21 | "@babel/preset-env": "^7.5.2",
22 | "@vue/component-compiler-utils": "^3.0.0",
23 | "parcel-bundler": "^1.12.3",
24 | "vue-template-compiler": "^2.6.10"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/example/src/App.vue:
--------------------------------------------------------------------------------
1 |
115 |
116 |
117 |
118 |
124 |
125 |
132 |
133 |
134 |
135 |
{{this.result}}
136 |
137 |
138 |
139 |
140 |
145 |
--------------------------------------------------------------------------------
/example/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | vue-path-recognizer
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/example/src/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import App from './App.vue';
3 |
4 | new Vue({
5 | el: '#app',
6 | render: h => h(App),
7 | });
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-path-recognizer",
3 | "version": "1.0.22",
4 | "description": "Path recognizing component for Vue",
5 | "main": "./src/index.js",
6 | "scripts": {
7 | "deploy": "webpack --mode production",
8 | "push": "git push && npm publish"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/MikeCheng1208/Vue-path-recognizer.git"
13 | },
14 | "keywords": [
15 | "vue",
16 | "javascript"
17 | ],
18 | "author": "mike cheng (https://github.com/MikeCheng1208/)",
19 | "license": "MIT",
20 | "bugs": {
21 | "url": "https://github.com/MikeCheng1208/Vue-path-recognizer/issues"
22 | },
23 | "homepage": "https://github.com/MikeCheng1208/Vue-path-recognizer",
24 | "devDependencies": {
25 | "@babel/core": "^7.5.4",
26 | "@babel/preset-env": "^7.5.4",
27 | "babel-core": "^6.26.3",
28 | "babel-loader": "^8.0.6",
29 | "babel-plugin-transform-async-to-generator": "^6.24.1",
30 | "babel-plugin-transform-class-properties": "^6.24.1",
31 | "babel-plugin-transform-export-extensions": "^6.22.0",
32 | "babel-plugin-transform-runtime": "^6.23.0",
33 | "babel-polyfill": "^6.26.0",
34 | "babel-preset-env": "^1.7.0",
35 | "css-loader": "^3.0.0",
36 | "loader-utils": "^1.2.3",
37 | "npm": "^10.2.4",
38 | "npm-run-all": "^4.1.5",
39 | "style-loader": "^0.23.1",
40 | "vue": "^2.6.10",
41 | "vue-html-loader": "^1.2.4",
42 | "vue-loader": "^15.7.0",
43 | "vue-template-compiler": "^2.6.10",
44 | "webpack": "^4.35.3",
45 | "webpack-cli": "^3.3.5",
46 | "webpack-manifest-plugin": "^2.0.4"
47 | },
48 | "directories": {
49 | "example": "example"
50 | },
51 | "dependencies": {}
52 | }
53 |
--------------------------------------------------------------------------------
/src/PathRecognizer.vue:
--------------------------------------------------------------------------------
1 |
293 |
294 |
295 |
299 |
300 |
301 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import PathRecognizer, { PathRecognizerModels } from './PathRecognizer.vue';
2 | export const PathRecognizerModel = PathRecognizerModels;
3 | export default PathRecognizer;
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const VueLoaderPlugin = require('vue-loader/lib/plugin')
3 | const config = {
4 | context: path.resolve(__dirname, 'src'),
5 | entry: {
6 | index: 'index',
7 | },
8 | output: {
9 | path: path.resolve(__dirname, 'dist'),
10 | filename: '[name].js',
11 | },
12 | resolve: {
13 | alias: {
14 | vue: 'vue/dist/vue.min.js',
15 | },
16 | modules: [
17 | path.resolve('src'),
18 | path.resolve('node_modules')
19 | ],
20 | extensions: ['.js', '.vue']
21 | },
22 | module:{
23 | rules:[
24 | {
25 | test: /\.(css)$/,
26 | use: [
27 | 'vue-style-loader',
28 | 'css-loader',
29 | ]
30 | },
31 | {
32 | test: /\.(vue)$/,
33 | use: 'vue-loader',
34 | },
35 | {
36 | test: /\.(js)$/,
37 | use: 'babel-loader',
38 | },
39 | ]
40 | },
41 | plugins: [
42 | new VueLoaderPlugin()
43 | ]
44 | };
45 |
46 | module.exports = config;
47 |
--------------------------------------------------------------------------------