├── .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 | ![ScreenShot](./assets/Vue-path-recognizer.jpg) 4 |

Path recognizing component for Vue

5 |

6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |

16 | 17 | [![NPM](https://nodei.co/npm/vue-path-recognizer.png?downloads=true&downloadRank=true&stars=true)](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 | 79 | 80 | 81 | ``` 82 | 83 | For example, here the model for the letter E : 84 | 85 | ![ScreenShot](https://mikecheng1208.github.io/Vue-path-recognizer/assets/directions.png) 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 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 |
nametypedefaultdescription
sliceCountNumber8Resolution of the direction wheel
deltaMoveNumber8Mouse move threshold (pixels)
costMaxNumber32Max cost limit to detect a gesture
models[PathRecognizerModel([Number], Any)][]Models to recognize
onStartDrawFunction()functionInvoked when the user mouse down the zone
onMovePathFunction([{x:Number, y:Number}])functionInvoked when the user move his mouse during a record session
onStopDrawFunction()functionInvoked when the user mouse up the zone
onGestureFunction(datas:Any)functionInvoked with the datas of the model recognized or null if no gesture is recognized
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 | ![ScreenShot](https://mikecheng1208.github.io/Vue-path-recognizer/assets/other_moves.gif) 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 | 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 | 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 | --------------------------------------------------------------------------------