├── .editorconfig
├── .eslintrc.json
├── .gitattributes
├── .github
├── ISSUE_TEMPLATE.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .jshintrc
├── .travis.yml
├── CONTRIBUTING.md
├── Gruntfile.js
├── LICENSE
├── README.md
├── bower.json
├── demo
├── annyang.min.js
├── css
│ ├── main.css
│ └── main.min.css
├── images
│ ├── flickr.png
│ ├── footer_background.jpg
│ ├── icon_js.png
│ ├── icon_speech.png
│ ├── icon_user.png
│ ├── mini_icon_say.png
│ ├── palette.png
│ └── tpscover.jpg
├── index.html
└── vendor
│ ├── css
│ ├── default.css
│ ├── github.css
│ └── tomorrow.css
│ ├── html
│ └── github-btn.html
│ └── js
│ └── highlight.pack.js
├── dist
├── annyang.js
├── annyang.js.map
└── annyang.min.js
├── docs
├── FAQ.md
└── README.md
├── package-lock.json
├── package.json
├── require.js
├── src
└── annyang.js
└── test
├── SpecRunner.html
├── init_corti.js
├── spec
├── .jshintrc
├── BasicSpec.js
└── IssuesSpec.js
└── vendor
└── corti.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # http://editorconfig.org
4 |
5 | root = true
6 |
7 | [*]
8 | indent_style = space
9 | indent_size = 2
10 | end_of_line = lf
11 | charset = utf-8
12 | trim_trailing_whitespace = true
13 | insert_final_newline = true
14 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["jasmine"],
3 | "env": {
4 | "browser": true,
5 | "node": true,
6 | "jasmine": true
7 | },
8 | "extends": ["eslint:recommended", "plugin:jasmine/recommended"],
9 | "parserOptions": {
10 | "sourceType": "module"
11 | },
12 | "rules": {
13 | "no-console": 0,
14 | "indent": ["error", 2, { "SwitchCase": 1 }],
15 | "linebreak-style": ["error", "unix"],
16 | "quotes": ["error", "single", { "avoidEscape": true }],
17 | "semi": ["error", "always"]
18 | },
19 | "globals": {
20 | "define": false,
21 | "Corti": false
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | demo/* linguist-documentation
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Expected Behavior
4 |
5 |
6 |
7 | ## Current Behavior
8 |
9 |
10 |
11 | ## Possible Solution
12 |
13 |
14 |
15 | ## Steps to Reproduce (for bugs)
16 |
17 |
18 | 1.
19 | 2.
20 | 3.
21 | 4.
22 |
23 | ## Context
24 |
25 |
26 |
27 | ## Your Environment
28 |
29 | * Version used:
30 | * Browser name and version:
31 | * Operating system and version (desktop or mobile):
32 | * Link to your project:
33 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Description
4 |
5 |
6 | ## Motivation and Context
7 |
8 |
9 |
10 | ## How Has This Been Tested?
11 |
12 |
13 |
14 |
15 | ## Types of changes
16 |
17 | - [ ] Bug fix (non-breaking change which fixes an issue)
18 | - [ ] New feature (non-breaking change which adds functionality)
19 | - [ ] Breaking change (fix or feature that would cause existing functionality to change)
20 |
21 | ## Checklist:
22 |
23 |
24 | - [ ] My code follows the code style of this project.
25 | - [ ] My change requires a change to the documentation.
26 | - [ ] I have updated the documentation accordingly.
27 | - [ ] I have read the **CONTRIBUTING** document.
28 | - [ ] I have added tests to cover my changes.
29 | - [ ] All new and existing tests passed.
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | npm-debug.log
3 | .idea
4 | .grunt
5 | .DS_Store
6 | test/coverage/
7 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "node" : true,
3 | "browser" : true,
4 | "devel" : false,
5 | "camelcase" : true,
6 | "curly" : true,
7 | "latedef" : true,
8 | "unused" : true,
9 | "trailing" : true,
10 | "eqeqeq" : true,
11 | "eqnull" : true,
12 | "evil" : false,
13 | "forin" : true,
14 | "immed" : true,
15 | "laxbreak" : false,
16 | "newcap" : true,
17 | "noarg" : true,
18 | "noempty" : false,
19 | "nonew" : true,
20 | "onevar" : false,
21 | "plusplus" : false,
22 | "undef" : true,
23 | "sub" : true,
24 | "strict" : true,
25 | "white" : false,
26 | "indent" : 2,
27 | "esversion" : 6,
28 | "globals" : {
29 | "define" : false
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: node_js
3 | node_js:
4 | - '10'
5 | - '9'
6 | - '8'
7 | - '7'
8 | - '6'
9 | - 'node'
10 | deploy:
11 | provider: npm
12 | email: tal@talater.com
13 | api_key:
14 | secure: B7djVh1jMSccBqDoFYO+yDcucgd5u7vR8dy6U1p48BKcA78bNlIm58MO2XF22Qx0uqKAv3piD385DgUoICoHU4Au9BXFBEdMpxbLsd4LVIOekPCnOlF2GHz9p8mhUzNbXP4qXLjoNz1tZlcd9LgSujN35PnNDp00AKdjs8vIceo=
15 | on:
16 | tags: true
17 | branch: master
18 | node: '5'
19 | repo: TalAter/annyang
20 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to annyang
2 |
3 | Thank you for taking the time to get involved with annyang! :+1:
4 |
5 | There are several ways you can help the project out:
6 |
7 | * [Contributing code](#contributing-code)
8 | * [Reporting Bugs](#reporting-bugs)
9 | * [Feature Requests and Ideas](#feature-requests-and-ideas)
10 |
11 | ## How Can I Contribute?
12 |
13 | ### Contributing Code
14 |
15 | A lot of annyang's functionality came from pull requests sent over GitHub. Here is how you can contribute too:
16 |
17 | - [x] Fork the repository from the [annyang GitHub page](https://github.com/TalAter/annyang).
18 | - [x] Clone a copy to your local machine with `$ git clone git@github.com:YOUR-GITHUB-USER-NAME/annyang.git`
19 | - [x] Make sure you have *node.js* and *npm* installed on your machine. You can use this [guide](https://docs.npmjs.com/getting-started/installing-node) for help.
20 | - [x] Install all of annyang's development dependencies with npm. `$ cd annyang; npm install`
21 | - [x] If you do not have the grunt-cli installed globally, run `$ npm install -g grunt-cli`
22 | - [x] Run grunt to make sure everything runs smoothly `$ grunt`
23 | - [x] Add tests for your code. [See details below](#automated-testing).
24 | - [x] Code, code, code. Changes should be done in `/src/annyang.js`. They will be transpiled to `/dist/annyang.js` and `/dist/annyang.min.js`.
25 | - [x] Run `$ grunt` after making changes to verify that everything still works and the tests all pass.
26 |
27 | :bulb: A great alternative to repeatedly running `$ grunt` is to run `$ grunt watch` once, and leave this process running. It will continuously run all the tests and build the files every time you make a change to one of annyang's files. It will even *beep* if you make an error, and help you debug it. :+1:
28 | - [x] You can run a local server to test your work in the browser by running `$ grunt dev`. This will also automatically run `$ grunt watch` for you.
29 | Point your browser to `https://localhost:8443/demo/` to see the demo page.
30 | Since it's using a self-signed certificate, you might need to click *"Proceed Anyway"*.
31 | - [x] Before committing your changes, the last step must always be running `$ grunt`. This makes sure everything works, and all files are kept up to date with your changes.
32 | - [x] Once you've made sure all your changes work correctly and have been committed, push your local changes back to github with `$ git push -u origin master`
33 | - [x] Visit your fork on GitHub.com ([https://github.com/YOUR-USER-NAME/annyang](https://github.com/YOUR-USER-NAME/annyang)) and create a pull request for your changes.
34 | - [x] Makes sure your pull request describes exactly what you changed and if it relates to an open issue references that issue (just include the issue number in the title like this: #49)
35 |
36 | #### Important:
37 |
38 | * Make sure to run `npm install` and `grunt` and make sure all tasks completed successfully before committing.
39 | * Do not change the [API docs](https://github.com/TalAter/annyang/blob/master/docs/README.md) in `/docs/README.md` directly. This file is generated automatically, and your changes will be overwritten. Instead, update the relevant comments in `src/annyang.js`
40 | * annyang is still not completely automatically tested :disappointed:. If you make a change, please make sure to test your change thoroughly to make sure no backward functionality was broken, and that your change works as intended.
41 | * Do not update the version number yourself.
42 | * Please stick to the project's existing coding style. Coding styles don't need to have a consensus, they just need to be consistent :smile:.
43 | * Push your changes to a topic branch in your fork of the repository. Your branch should be based on the `master` branch.
44 | * When submitting [pull request](https://help.github.com/articles/using-pull-requests/), please elaborate as much as possible about the change, your motivation for the change, etc.
45 |
46 | #### Automated Testing
47 |
48 | annyang is tested using [Jasmine](http://jasmine.github.io/2.0/introduction.html).
49 |
50 | Please include tests for any changes you make:
51 | * If you found a bug, please write a test that fails because of that bug, then fix the bug so that the test passes.
52 | * If you are adding a new feature, write tests that thoroughly test every possible use of your code.
53 | * If you are changing existing functionality, make sure to update existing tests so they pass. (This is a last resort move. Whenever possible try to maintain backward compatibility)
54 |
55 | The tests reside in *BasicSpec.js*. The file contains a series of spec groups (e.g. `describe('a spec group', function() {});`) which each contain 1 or more specs (e.g. `it('should do stuff', function() {});`). Some of the spec groups also contain some code which runs before each spec (`beforeEach(function() {});`).
56 |
57 | To simulate Speech Recognition in the testing environment, annyang uses a mock object called [Corti](https://github.com/TalAter/Corti) which mocks the browser's SpeechRecognition object. Corti also adds a number of utility functions to the SpeechRecognition object which simulate user actions (e.g. `say('Hello there')`), and allow checking the SpeechRecognition's status (e.g. `isListening() === true`).
58 |
59 | ### Reporting Bugs
60 |
61 | Bugs are tracked as [GitHub issues](https://github.com/TalAter/annyang/issues). If you found a bug with annyang, the quickest way to get help would be to look through existing open and closed [GitHub issues](https://github.com/TalAter/annyang/issues?q=is%3Aissue). If the issue is already being discussed and hasn't been resolved yet, you can join the discussion and provide details about the problem you are having. If this is a new bug, please open a [new issue](https://github.com/TalAter/annyang/issues/new).
62 |
63 | When you are creating a bug report, please include as many details as possible.
64 |
65 | Explain the problem and include additional details to help maintainers reproduce the problem.
66 |
67 | * Use a clear and descriptive title for the issue to identify the problem.
68 | * Describe the exact steps which reproduce the problem. Share the relevant code to reproduce the issue if possible.
69 | * Try to isolate the issue as much as possible, reducing unrelated code until you get to the minimal amount of code in which the bug still reproduces. This is the most important step to help the community solve the issue.
70 |
71 | ### Feature Requests and Ideas
72 |
73 | We track discussions of new features, proposed changes, and other ideas as [GitHub issues](https://github.com/TalAter/annyang/issues). If you would like to discuss one of those, please first look through existing open and closed [GitHub issues](https://github.com/TalAter/annyang/issues?q=is%3Aissue) and see if there is already a discussion on this topic which you can join. If there isn't, please open a [new issue](https://github.com/TalAter/annyang/issues/new).
74 |
75 | When discussing new ideas or proposing changes, please take the time to be as descriptive as possible about the topic at hand. Please take the time to explain the issue you are facing, or the problem you propose to solve in as much detail as possible.
76 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 | 'use strict';
3 |
4 | // Project configuration.
5 | grunt.initConfig({
6 | pkg: grunt.file.readJSON('package.json'),
7 | jshint: {
8 | all: [
9 | 'Gruntfile.js',
10 | 'src/annyang.js',
11 | 'test/spec/*Spec.js'
12 | ],
13 | options: {
14 | jshintrc: true
15 | }
16 | },
17 | 'babel': {
18 | options: {
19 | sourceMap: true,
20 | presets: ['env']
21 | },
22 | dist: {
23 | files: {
24 | 'dist/annyang.js': 'src/annyang.js'
25 | }
26 | }
27 | },
28 | watch: {
29 | files: ['src/*.js', 'demo/css/*.css', 'test/spec/*Spec.js', '!**/node_modules/**'],
30 | tasks: ['default']
31 | },
32 | uglify: {
33 | options: {
34 | output: {
35 | comments: /^\! /
36 | }
37 | },
38 | all: {
39 | files: {
40 | 'dist/annyang.min.js': ['dist/annyang.js']
41 | }
42 | }
43 | },
44 | imagemin: {
45 | demoimages: { // Target
46 | options: { // Target options
47 | },
48 | files: [{
49 | expand: true, // Enable dynamic expansion
50 | cwd: 'demo/images', // Src matches are relative to this path
51 | src: ['*.{png,jpg,gif}'], // Actual patterns to match
52 | dest: 'demo/images' // Destination path prefix
53 | }]
54 | }
55 | },
56 | cssmin: {
57 | combine: {
58 | files: {
59 | 'demo/css/main.min.css': ['demo/css/main.css', 'demo/vendor/css/default.css', 'demo/vendor/css/github.css']
60 | }
61 | }
62 | },
63 | markdox: {
64 | target: {
65 | files: [
66 | {src: 'src/annyang.js', dest: 'docs/README.md'}
67 | ]
68 | }
69 | },
70 | connect: {
71 | server: {
72 | options: {
73 | protocol: 'https',
74 | port: 8443,
75 | hostname: '*',
76 | base: '.',
77 | open: 'https://localhost:8443/demo'
78 | }
79 | }
80 | },
81 | jasmine: {
82 | browserAMD: {
83 | src: ['dist/annyang.min.js'],
84 | options: {
85 | specs: 'test/spec/*Spec.js',
86 | outfile: 'test/SpecRunner.html',
87 | vendor: ['test/vendor/corti.js', 'test/init_corti.js'],
88 | keepRunner: true,
89 | template: require('grunt-template-jasmine-requirejs'),
90 | templateOptions: {
91 | requireConfig: {
92 | baseUrl: '../dist/'
93 | }
94 | }
95 | }
96 | }
97 | }
98 | });
99 |
100 | // Load NPM tasks
101 | require('load-grunt-tasks')(grunt, {
102 | pattern: ['grunt-*', '!grunt-template-jasmine-istanbul']
103 | });
104 |
105 | // Register tasks
106 | grunt.registerTask('default', ['jshint', 'babel', 'uglify', 'cssmin', 'markdox']);
107 | grunt.registerTask('dev', ['default', 'connect', 'watch']);
108 | grunt.registerTask('test', ['default', 'jasmine']);
109 |
110 | };
111 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2021 Tal Ater
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | 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, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # annyang!
2 |
3 | A tiny JavaScript Speech Recognition library that lets your users control your site with voice commands.
4 |
5 | **annyang** has no dependencies, weighs just 2 KB, and is free to use and modify under the MIT license.
6 |
7 | ## Demo and Tutorial
8 |
9 | [Play with some live speech recognition demos](https://www.talater.com/annyang)
10 |
11 | ## FAQ, Technical Documentation, and API Reference
12 |
13 | - [annyang Frequently Asked Questions](https://github.com/TalAter/annyang/blob/master/docs/FAQ.md)
14 | - [annyang API reference](https://github.com/TalAter/annyang/blob/master/docs/README.md)
15 | - [annyang tutorial](https://www.talater.com/annyang)
16 |
17 | ## Hello World
18 |
19 | It's as easy as adding [one javascript file](//cdnjs.cloudflare.com/ajax/libs/annyang/2.6.1/annyang.min.js) to your document and defining the commands you want.
20 |
21 | ````html
22 |
23 |
37 | ````
38 |
39 | **Check out some [live speech recognition demos and advanced samples](https://www.talater.com/annyang), then read the full [API Docs](https://github.com/TalAter/annyang/blob/master/docs/README.md).**
40 |
41 | ## Adding a GUI
42 |
43 | You can easily add a GUI for the user to interact with Speech Recognition using [Speech KITT](https://github.com/TalAter/SpeechKITT).
44 |
45 | Speech KITT makes it easy to add a graphical interface for the user to start or stop Speech Recognition and see its current status. KITT also provides clear visual hints to the user on how to interact with your site using their voice, providing instructions and sample commands.
46 |
47 | Speech KITT is fully customizable and comes with many different themes, and instructions on how to create your own designs.
48 |
49 | [](https://github.com/TalAter/SpeechKITT)
50 |
51 | ````html
52 |
53 |
54 |
71 | ````
72 |
73 | For help with setting up a GUI with KITT, check out the [Speech KITT page](https://github.com/TalAter/SpeechKITT).
74 |
75 | ## Author
76 |
77 | Tal Ater: [@TalAter](https://twitter.com/TalAter)
78 |
79 | ## License
80 |
81 | Licensed under [MIT](https://github.com/TalAter/annyang/blob/master/LICENSE).
82 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "annyang",
3 | "description": "A javascript library for adding voice commands to your site, using speech recognition",
4 | "main": "dist/annyang.min.js",
5 | "keywords": [
6 | "annyang",
7 | "annyang.js",
8 | "speechrecognition",
9 | "webkitspeechrecognition",
10 | "voice",
11 | "speech",
12 | "recognition"
13 | ],
14 | "author": "Tal Ater (https://www.talater.com/)",
15 | "license": "MIT",
16 | "ignore": [
17 | "**/.*",
18 | "node_modules",
19 | "Gruntfile.js",
20 | "package.json",
21 | "bower.json",
22 | "demo"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/demo/annyang.min.js:
--------------------------------------------------------------------------------
1 | ../dist/annyang.min.js
--------------------------------------------------------------------------------
/demo/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | background: url('../images/palette.png') repeat-x 0 -2px;
3 | font: 14px/1.6 helvetica, sans-serif;
4 | margin: 0 0;
5 | padding: 0 0;
6 | color: #333;
7 | }
8 |
9 | .hidden {
10 | display: none;
11 | }
12 |
13 | a, a:visited {
14 | color: #d9e7f3;
15 | text-decoration: underline;
16 | }
17 | a:hover {
18 | text-decoration: none;
19 | }
20 |
21 | h2 {
22 | font-size: 2em;
23 | }
24 |
25 | pre code a, pre code a:visited {
26 | color: #00f;
27 | }
28 |
29 | #tpsreport {
30 | position: fixed;
31 | z-index: 1000;
32 | bottom: -500px;
33 | right: 10px;
34 | -webkit-transform: rotate(-15deg);
35 | -moz-transform: rotate(-15deg);
36 | -ms-transform: rotate(-15deg);
37 | -o-transform: rotate(-15deg);
38 | transform: rotate(-15deg);
39 | -webkit-box-shadow: 2px 1px 6px 1px #555;
40 | box-shadow: 2px 1px 6px 1px #555;
41 | }
42 | #section_header h2 {
43 | margin: 5px 0;
44 | font-size: 20px;
45 | line-height: 30px;
46 | font-weight: 400;
47 | }
48 |
49 | pre code {
50 | overflow: scroll;
51 | padding: 10px 20px!important;
52 | margin-left: 50px;
53 | }
54 | h1 em {
55 | font-weight: 800;
56 | margin-right: 9px;
57 | }
58 | h1 {
59 | font-weight: 400;
60 | font-size: 40px;
61 | line-height: 41px;
62 | margin: 25px 0;
63 | }
64 | p em {
65 | font-weight: 600;
66 | font-size: 23px;
67 | line-height: 45px;
68 | }
69 | p.voice_instructions {
70 | background: url('../images/mini_icon_say.png') no-repeat 0 6px;
71 | padding-left: 24px;
72 | }
73 | #hello {
74 | font-size: 2.5em;
75 | font-weight: 600;
76 | }
77 | #flickrLoader p {
78 | background: url('../images/flickr.png') no-repeat 0 7px;
79 | padding-left: 39px;
80 | }
81 | #flickrLoader {
82 | height: 40px;
83 | }
84 | section {
85 | padding: 3% 10%;
86 | font-size: 20px;
87 | line-height: 30px;
88 | font-weight: 400;
89 | }
90 | #section_header img {
91 | margin: 30px 50px 0;
92 | }
93 | #section_header {
94 | padding-top: 70px;
95 | text-align: center;
96 | }
97 | #section_hello {
98 | background-color: #0b4f3f;
99 | color: #fff;
100 | }
101 | #section_image_search {
102 | background-color: #295074;
103 | color: #fff;
104 | }
105 | #section_biz_use {
106 | background-color: #4a5758;
107 | color: #fff;
108 | }
109 | #section_footer {
110 | background: #000 url('../images/footer_background.jpg') repeat-x top center;
111 | background-size: auto 100%;
112 | text-align: center;
113 | background-color: #34495d;
114 | color: #fff;
115 | padding: 2% 10%;
116 | }
117 | div.social{
118 | margin-top: 40px;
119 | }
120 | div.copyright{
121 | margin-top: 50px;
122 | font-size: 12px;
123 | line-height: 18px;
124 | font-weight: 100;
125 | }
126 | div#unsupported {
127 | text-align: center;
128 | position: fixed;
129 | bottom: 0;
130 | width: 100%;
131 | max-height: 60%;
132 | color: #b94a48;
133 | background-color: #f2dede;
134 | border: 1px solid #eed3d7;
135 | -webkit-box-shadow: -32px -50px 109px rgba(0, 0, 0, 0.92);
136 | -moz-box-shadow: -32px -50px 109px rgba(0, 0, 0, 0.92);
137 | box-shadow: -32px -50px 109px rgba(0, 0, 0, 0.92);
138 | font-size: 1.3em;
139 | line-height: 1.4em;
140 | padding-bottom: 10px;
141 | }
142 | div#unsupported a, div#unsupported a:visited {
143 | color: #b94a48;
144 | font-weight: bold;
145 | }
146 | div#unsupported h4 {
147 | font-size: 1.5em;
148 | margin: 15px 0 10px 0;
149 | }
150 | div#unsupported p {
151 | line-height: 20px;
152 | }
153 |
--------------------------------------------------------------------------------
/demo/css/main.min.css:
--------------------------------------------------------------------------------
1 | body{background:url(../images/palette.png) repeat-x 0 -2px;font:14px/1.6 helvetica,sans-serif;margin:0 0;padding:0 0;color:#333}.hidden{display:none}a,a:visited{color:#d9e7f3;text-decoration:underline}a:hover{text-decoration:none}h2{font-size:2em}pre code a,pre code a:visited{color:#00f}#tpsreport{position:fixed;z-index:1000;bottom:-500px;right:10px;-webkit-transform:rotate(-15deg);-moz-transform:rotate(-15deg);-ms-transform:rotate(-15deg);-o-transform:rotate(-15deg);transform:rotate(-15deg);-webkit-box-shadow:2px 1px 6px 1px #555;box-shadow:2px 1px 6px 1px #555}#section_header h2{margin:5px 0;font-size:20px;line-height:30px;font-weight:400}pre code{overflow:scroll;padding:10px 20px!important;margin-left:50px}h1 em{font-weight:800;margin-right:9px}h1{font-weight:400;font-size:40px;line-height:41px;margin:25px 0}p em{font-weight:600;font-size:23px;line-height:45px}p.voice_instructions{background:url(../images/mini_icon_say.png) no-repeat 0 6px;padding-left:24px}#hello{font-size:2.5em;font-weight:600}#flickrLoader p{background:url(../images/flickr.png) no-repeat 0 7px;padding-left:39px}#flickrLoader{height:40px}section{padding:3% 10%;font-size:20px;line-height:30px;font-weight:400}#section_header img{margin:30px 50px 0}#section_header{padding-top:70px;text-align:center}#section_hello{background-color:#0b4f3f;color:#fff}#section_image_search{background-color:#295074;color:#fff}#section_biz_use{background-color:#4a5758;color:#fff}#section_footer{background:#000 url(../images/footer_background.jpg) repeat-x top center;background-size:auto 100%;text-align:center;background-color:#34495d;color:#fff;padding:2% 10%}div.social{margin-top:40px}div.copyright{margin-top:50px;font-size:12px;line-height:18px;font-weight:100}div#unsupported{text-align:center;position:fixed;bottom:0;width:100%;max-height:60%;color:#b94a48;background-color:#f2dede;border:1px solid #eed3d7;-webkit-box-shadow:-32px -50px 109px rgba(0,0,0,.92);-moz-box-shadow:-32px -50px 109px rgba(0,0,0,.92);box-shadow:-32px -50px 109px rgba(0,0,0,.92);font-size:1.3em;line-height:1.4em;padding-bottom:10px}div#unsupported a,div#unsupported a:visited{color:#b94a48;font-weight:700}div#unsupported h4{font-size:1.5em;margin:15px 0 10px 0}div#unsupported p{line-height:20px}pre code{display:block;padding:.5em;background:#f0f0f0}pre .clojure .built_in,pre .lisp .title,pre .nginx .title,pre .subst,pre .tag .title,pre code{color:#000}pre .addition,pre .aggregate,pre .apache .cbracket,pre .apache .tag,pre .bash .variable,pre .constant,pre .django .variable,pre .erlang_repl .function_or_atom,pre .flow,pre .markdown .header,pre .parent,pre .preprocessor,pre .ruby .symbol,pre .ruby .symbol .string,pre .rules .value,pre .rules .value .number,pre .smalltalk .class,pre .stream,pre .string,pre .tag .value,pre .template_tag,pre .tex .command,pre .tex .special,pre .title{color:#800}pre .annotation,pre .chunk,pre .comment,pre .diff .header,pre .markdown .blockquote,pre .template_comment{color:#6b6b5b}pre .change,pre .date,pre .go .constant,pre .literal,pre .markdown .bullet,pre .markdown .link_url,pre .number,pre .regexp,pre .smalltalk .char,pre .smalltalk .symbol{color:#080}pre .apache .sqbracket,pre .array,pre .attr_selector,pre .clojure .attribute,pre .coffeescript .property,pre .decorator,pre .deletion,pre .doctype,pre .envvar,pre .erlang_repl .reserved,pre .filter .argument,pre .important,pre .javadoc,pre .label,pre .localvars,pre .markdown .link_label,pre .nginx .built_in,pre .pi,pre .prompt,pre .pseudo,pre .ruby .string,pre .shebang,pre .tex .formula,pre .vhdl .attribute{color:#88f}pre .aggregate,pre .apache .tag,pre .bash .variable,pre .built_in,pre .css .tag,pre .go .typename,pre .id,pre .javadoctag,pre .keyword,pre .markdown .strong,pre .phpdoc,pre .request,pre .smalltalk .class,pre .status,pre .tex .command,pre .title,pre .winutils,pre .yardoctag{font-weight:700}pre .markdown .emphasis{font-style:italic}pre .nginx .built_in{font-weight:400}pre .coffeescript .javascript,pre .javascript .xml,pre .tex .formula,pre .xml .cdata,pre .xml .css,pre .xml .javascript,pre .xml .vbscript{opacity:1}pre code{display:block;padding:.5em;color:#333;background:#f8f8ff}pre .comment,pre .diff .header,pre .javadoc,pre .template_comment{color:#6b6b5b;font-style:italic}pre .css .rule .keyword,pre .javascript .title,pre .keyword,pre .nginx .title,pre .request,pre .status,pre .subst,pre .winutils{color:#333;font-weight:700}pre .hexcolor,pre .number,pre .ruby .constant{color:#099}pre .phpdoc,pre .string,pre .tag .value,pre .tex .formula{color:#d14}pre .id,pre .title{color:#900;font-weight:700}pre .clojure .title,pre .javascript .title,pre .lisp .title,pre .subst{font-weight:400}pre .class .title,pre .haskell .type,pre .tex .command,pre .vhdl .literal{color:#458;font-weight:700}pre .django .tag .keyword,pre .rules .property,pre .tag,pre .tag .title{color:navy;font-weight:400}pre .attribute,pre .lisp .body,pre .variable{color:teal}pre .regexp{color:#009926}pre .class{color:#458;font-weight:700}pre .lisp .keyword,pre .prompt,pre .ruby .symbol .string,pre .symbol,pre .tex .special{color:#990073}pre .built_in,pre .clojure .built_in,pre .lisp .title{color:#0086b3}pre .cdata,pre .doctype,pre .pi,pre .preprocessor,pre .shebang{color:#999;font-weight:700}pre .deletion{background:#fdd}pre .addition{background:#dfd}pre .diff .change{background:#0086b3}pre .chunk{color:#aaa}
--------------------------------------------------------------------------------
/demo/images/flickr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TalAter/annyang/46d3f1c212d43cae147e633ff9c52b36605c5728/demo/images/flickr.png
--------------------------------------------------------------------------------
/demo/images/footer_background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TalAter/annyang/46d3f1c212d43cae147e633ff9c52b36605c5728/demo/images/footer_background.jpg
--------------------------------------------------------------------------------
/demo/images/icon_js.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TalAter/annyang/46d3f1c212d43cae147e633ff9c52b36605c5728/demo/images/icon_js.png
--------------------------------------------------------------------------------
/demo/images/icon_speech.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TalAter/annyang/46d3f1c212d43cae147e633ff9c52b36605c5728/demo/images/icon_speech.png
--------------------------------------------------------------------------------
/demo/images/icon_user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TalAter/annyang/46d3f1c212d43cae147e633ff9c52b36605c5728/demo/images/icon_user.png
--------------------------------------------------------------------------------
/demo/images/mini_icon_say.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TalAter/annyang/46d3f1c212d43cae147e633ff9c52b36605c5728/demo/images/mini_icon_say.png
--------------------------------------------------------------------------------
/demo/images/palette.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TalAter/annyang/46d3f1c212d43cae147e633ff9c52b36605c5728/demo/images/palette.png
--------------------------------------------------------------------------------
/demo/images/tpscover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TalAter/annyang/46d3f1c212d43cae147e633ff9c52b36605c5728/demo/images/tpscover.jpg
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | annyang! Easily add speech recognition to your site
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
100 |
101 |
102 |
103 |
104 |
annyang! SpeechRecognition that just works
105 |
annyang is a tiny javascript library that lets your visitors control your site with voice commands.
106 |
annyang supports multiple languages, has no dependencies, weighs just 2kb and is free to use.
107 |
108 |
109 |
110 |
111 |
112 |
Go ahead, try it…
113 |
Say "Hello!"
114 |
Annyang!
115 |
116 |
117 |
Let's try something more interesting…
118 |
Say "Show me cute kittens!"
119 |
Say "Show me Arches National Park!"
120 |
Now go wild. Say "Show me…" and make your demands!
121 |
122 |
123 |
124 |
125 |
That's cool, but in the real world it's not all kittens and hello world.
126 |
No problem, say "Show TPS report"
127 |
128 |
129 |
130 |
How did you do that?
131 |
Simple. Here is all the code needed to achieve that:
132 |
<script src="//cdnjs.cloudflare.com/ajax/libs/annyang/2.6.1/annyang.min.js"></script>
133 | <script>
134 | if (annyang) {
135 | // Let's define our first command. First the text we expect, and then the function it should call
136 | const commands = {
137 | 'show tps report': function() {
138 | $('#tpsreport').animate({bottom: '-100px'});
139 | }
140 | };
141 |
142 | // Add our commands to annyang
143 | annyang.addCommands(commands);
144 |
145 | // Start listening. You can call this here, or attach this call to an event, button, etc.
146 | annyang.start();
147 | }
148 | </script>
149 |
150 |
151 |
What about more complicated commands?
152 |
annyang understands commands with named variables, splats, and optional words.
153 |
Use named variables for one word arguments in your command.
154 |
Use splats to capture multi-word text at the end of your command (greedy).
155 |
Use optional words or phrases to define a part of the command as optional.
156 |
<script>
157 | const commands = {
158 | // annyang will capture anything after a splat (*) and pass it to the function.
159 | // e.g. saying "Show me Batman and Robin" is the same as calling showFlickr('Batman and Robin');
160 | 'show me *tag': showFlickr,
161 |
162 | // A named variable is a one word variable, that can fit anywhere in your command.
163 | // e.g. saying "calculate October stats" will call calculateStats('October');
164 | 'calculate :month stats': calculateStats,
165 |
166 | // By defining a part of the following command as optional, annyang will respond to both:
167 | // "say hello to my little friend" as well as "say hello friend"
168 | 'say hello (to my little) friend': greeting
169 | };
170 |
171 | const showFlickr = function(tag) {
172 | var url = 'http://api.flickr.com/services/rest/?tags='+tag;
173 | $.getJSON(url);
174 | }
175 |
176 | const calculateStats = function(month) {
177 | $('#stats').text('Statistics for '+month);
178 | }
179 |
180 | const greeting = function() {
181 | $('#greeting').text('Hello!');
182 | }
183 |
184 | </script>
185 |
186 |
187 |
What about browser support?
188 |
annyang plays nicely with all browsers, progressively enhancing browsers that support SpeechRecognition, while leaving users with older browsers unaffected.
189 |
190 |
191 |
Ready to get started?
192 |
Grab the latest version of annyang.min.js, drop it in your html, and start adding commands.
Tal Ater retains creative control, spin-off rights and theme park approval for Mr. Banana Grabber, Baby Banana Grabber, and any other Banana Grabber family character that might emanate there from.
203 |
204 |
205 |
206 |
It looks like your browser doesn't support speech recognition.
207 |
annyang plays nicely with all browsers, progressively enhancing modern browsers that support the SpeechRecognition standard, while leaving users with older browsers unaffected.