├── .gitignore ├── LICENSE ├── README.md ├── angular.json ├── package-lock.json ├── package.json ├── projects ├── demo-app │ ├── browserslist │ ├── e2e │ │ ├── protractor.conf.js │ │ ├── src │ │ │ ├── app.e2e-spec.ts │ │ │ └── app.po.ts │ │ └── tsconfig.json │ ├── karma.conf.js │ ├── src │ │ ├── app │ │ │ ├── app.component.css │ │ │ ├── app.component.html │ │ │ ├── app.component.spec.ts │ │ │ ├── app.component.ts │ │ │ └── app.module.ts │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── main.ts │ │ ├── polyfills.ts │ │ ├── styles.css │ │ └── test.ts │ ├── tsconfig.app.json │ ├── tsconfig.spec.json │ └── tslint.json └── ngx-rough-notation │ ├── LICENSE │ ├── README.md │ ├── karma.conf.js │ ├── ng-package.json │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── lib │ │ ├── components │ │ │ ├── rough-notation-group │ │ │ │ ├── index.ts │ │ │ │ ├── rough-notation-group.component.html │ │ │ │ └── rough-notation-group.component.ts │ │ │ └── rough-notation │ │ │ │ ├── index.ts │ │ │ │ ├── rough-notation.component.html │ │ │ │ ├── rough-notation.component.ts │ │ │ │ └── types.ts │ │ └── rough-notation.module.ts │ ├── public-api.ts │ └── test.ts │ ├── tsconfig.lib.json │ ├── tsconfig.spec.json │ └── tslint.json ├── tsconfig.json └── tslint.json /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | node_modules 13 | 14 | # profiling files 15 | chrome-profiler-events*.json 16 | speed-measure-plugin*.json 17 | 18 | # IDEs and editors 19 | /.idea 20 | .project 21 | .classpath 22 | .c9/ 23 | *.launch 24 | .settings/ 25 | *.sublime-workspace 26 | 27 | # IDE - VSCode 28 | .vscode/* 29 | !.vscode/settings.json 30 | !.vscode/tasks.json 31 | !.vscode/launch.json 32 | !.vscode/extensions.json 33 | .history/* 34 | 35 | # misc 36 | /.sass-cache 37 | /connect.lock 38 | /coverage 39 | /libpeerconnection.log 40 | npm-debug.log 41 | yarn-error.log 42 | testem.log 43 | /typings 44 | 45 | # System Files 46 | .DS_Store 47 | Thumbs.db 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Mudasse Ajaz 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Angular wrapper for Rough Notation library 2 | 3 | 4 | This is an Angular wrapper for [rough-notation](https://roughnotation.com/), a small JavaScript library to create and animate annotations on a web page. 5 | 6 | - [Visit website to see it in action](https://roughnotation.com/) 7 | - [Library docs](https://github.com/pshihn/rough-notation) 8 | 9 | ## Demo 10 | You can play around with the demo [here](https://stackblitz.com/edit/angular-n9jsex). 11 | 12 | ## Installation 13 | 14 | Install rough-notation, which is peer dependency to this wrapper. 15 | ``` 16 | npm install --save rough-notation 17 | ``` 18 | Install wrapper. 19 | ``` 20 | npm install --save ngx-rough-notation 21 | ``` 22 | 23 | Import wrapper module into your app mobule 24 | 25 | ```js 26 | import { RoughNotationModule } from 'ngx-rough-notation'; 27 | ``` 28 | 29 | ## RoughNotation Component 30 | 31 | 32 | ### Usage 33 | 34 | ```html 35 | 36 | Hello I am a notation 37 | 38 | ``` 39 | 40 | ### Properties 41 | 42 | #### type 43 | This is a mandatory field. It sets the annotation style. Following are the list of supported annotation types: 44 | 45 | * __underline__: This style creates a sketchy underline below an element. 46 | * __box__: This style draws a box around the element. 47 | * __circle__: This style draws a circle around the element. 48 | * __highlight__: This style creates a highlight effect as if marked by a highlighter. 49 | * __strike-through__: This style draws horizontal lines through the element. 50 | * __crossed-off__: This style draws an 'X' across the element. 51 | 52 | #### animate 53 | Boolean property to turn on/off animation when annotating. Default value is `true`. 54 | 55 | #### animationDuration 56 | Duration of the animation in milliseconds. Default is `800ms`. 57 | 58 | #### color 59 | String value representing the color of the annotation sketch. Default value is `currentColor`. 60 | 61 | #### strokeWidth 62 | Width of the annotation strokes. Default value is `1`. 63 | 64 | #### padding 65 | Padding between the element and roughly where the annotation is drawn. Default value is `5` (in pixels). 66 | If you wish to specify different `top`, `left`, `right`, `bottom` paddings, you can set the value to an array akin to CSS style padidng `[top, right, bottom, left]` or just `[top & bottom, left & right]`. 67 | 68 | #### multiline 69 | This property only applies to inline text. To annotate multiline text (each line separately), set this property to `true`. 70 | 71 | #### iterations 72 | By default annotations are drawn in two iterations, e.g. when underlining, drawing from left to right and then back from right to left. Setting this property can let you configure the number of iterations. 73 | 74 | #### brackets 75 | Value could be a string or an array of strings, each string being one of these values: **left, right, top, bottom**. When drawing a bracket, this configures which side(s) of the element to bracket. Default value is `right`. 76 | 77 | #### show 78 | This boolean value hide/show the annotation. By default set to `false`. 79 | 80 | ## RoughNotation Group Component 81 | 82 | This is a wrapper for multiple annotations, it will trigger the `show()` method on every child annotation. 83 | 84 | ### Usage 85 | 86 | ```html 87 | 88 | 89 | Circle 90 | 91 | 92 | Highlight 93 | 94 | 95 | ``` 96 | 97 | ### Properties 98 | 99 | #### show 100 | This boolean value hide/show the annotations. By default set to `false`. 101 | 102 | 103 | ## TODO 104 | - Testing 105 | -------------------------------------------------------------------------------- /angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "ngx-rough-notation": { 7 | "projectType": "library", 8 | "root": "projects/ngx-rough-notation", 9 | "sourceRoot": "projects/ngx-rough-notation/src", 10 | "prefix": "lib", 11 | "architect": { 12 | "build": { 13 | "builder": "@angular-devkit/build-ng-packagr:build", 14 | "options": { 15 | "tsConfig": "projects/ngx-rough-notation/tsconfig.lib.json", 16 | "project": "projects/ngx-rough-notation/ng-package.json" 17 | } 18 | }, 19 | "test": { 20 | "builder": "@angular-devkit/build-angular:karma", 21 | "options": { 22 | "main": "projects/ngx-rough-notation/src/test.ts", 23 | "tsConfig": "projects/ngx-rough-notation/tsconfig.spec.json", 24 | "karmaConfig": "projects/ngx-rough-notation/karma.conf.js" 25 | } 26 | }, 27 | "lint": { 28 | "builder": "@angular-devkit/build-angular:tslint", 29 | "options": { 30 | "tsConfig": [ 31 | "projects/ngx-rough-notation/tsconfig.lib.json", 32 | "projects/ngx-rough-notation/tsconfig.spec.json" 33 | ], 34 | "exclude": [ 35 | "**/node_modules/**" 36 | ] 37 | } 38 | } 39 | } 40 | }, 41 | "demo-app": { 42 | "projectType": "application", 43 | "schematics": {}, 44 | "root": "projects/demo-app", 45 | "sourceRoot": "projects/demo-app/src", 46 | "prefix": "app", 47 | "architect": { 48 | "build": { 49 | "builder": "@angular-devkit/build-angular:browser", 50 | "options": { 51 | "outputPath": "dist/demo-app", 52 | "index": "projects/demo-app/src/index.html", 53 | "main": "projects/demo-app/src/main.ts", 54 | "polyfills": "projects/demo-app/src/polyfills.ts", 55 | "tsConfig": "projects/demo-app/tsconfig.app.json", 56 | "aot": false, 57 | "assets": [ 58 | "projects/demo-app/src/favicon.ico", 59 | "projects/demo-app/src/assets" 60 | ], 61 | "styles": [ 62 | "projects/demo-app/src/styles.css" 63 | ], 64 | "scripts": [] 65 | }, 66 | "configurations": { 67 | "production": { 68 | "fileReplacements": [ 69 | { 70 | "replace": "projects/demo-app/src/environments/environment.ts", 71 | "with": "projects/demo-app/src/environments/environment.prod.ts" 72 | } 73 | ], 74 | "optimization": true, 75 | "outputHashing": "all", 76 | "sourceMap": false, 77 | "extractCss": true, 78 | "namedChunks": false, 79 | "aot": true, 80 | "extractLicenses": true, 81 | "vendorChunk": false, 82 | "buildOptimizer": true, 83 | "budgets": [ 84 | { 85 | "type": "initial", 86 | "maximumWarning": "2mb", 87 | "maximumError": "5mb" 88 | }, 89 | { 90 | "type": "anyComponentStyle", 91 | "maximumWarning": "6kb", 92 | "maximumError": "10kb" 93 | } 94 | ] 95 | } 96 | } 97 | }, 98 | "serve": { 99 | "builder": "@angular-devkit/build-angular:dev-server", 100 | "options": { 101 | "browserTarget": "demo-app:build" 102 | }, 103 | "configurations": { 104 | "production": { 105 | "browserTarget": "demo-app:build:production" 106 | } 107 | } 108 | }, 109 | "extract-i18n": { 110 | "builder": "@angular-devkit/build-angular:extract-i18n", 111 | "options": { 112 | "browserTarget": "demo-app:build" 113 | } 114 | }, 115 | "test": { 116 | "builder": "@angular-devkit/build-angular:karma", 117 | "options": { 118 | "main": "projects/demo-app/src/test.ts", 119 | "polyfills": "projects/demo-app/src/polyfills.ts", 120 | "tsConfig": "projects/demo-app/tsconfig.spec.json", 121 | "karmaConfig": "projects/demo-app/karma.conf.js", 122 | "assets": [ 123 | "projects/demo-app/src/favicon.ico", 124 | "projects/demo-app/src/assets" 125 | ], 126 | "styles": [ 127 | "projects/demo-app/src/styles.css" 128 | ], 129 | "scripts": [] 130 | } 131 | }, 132 | "lint": { 133 | "builder": "@angular-devkit/build-angular:tslint", 134 | "options": { 135 | "tsConfig": [ 136 | "projects/demo-app/tsconfig.app.json", 137 | "projects/demo-app/tsconfig.spec.json", 138 | "projects/demo-app/e2e/tsconfig.json" 139 | ], 140 | "exclude": [ 141 | "**/node_modules/**" 142 | ] 143 | } 144 | }, 145 | "e2e": { 146 | "builder": "@angular-devkit/build-angular:protractor", 147 | "options": { 148 | "protractorConfig": "projects/demo-app/e2e/protractor.conf.js", 149 | "devServerTarget": "demo-app:serve" 150 | }, 151 | "configurations": { 152 | "production": { 153 | "devServerTarget": "demo-app:serve:production" 154 | } 155 | } 156 | } 157 | } 158 | }}, 159 | "defaultProject": "ngx-rough-notation" 160 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ngx-rough-notation-workspace", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "test": "ng test", 9 | "lint": "ng lint", 10 | "e2e": "ng e2e" 11 | }, 12 | "private": true, 13 | "dependencies": { 14 | "@angular/animations": "~8.2.14", 15 | "@angular/common": "~8.2.14", 16 | "@angular/compiler": "~8.2.14", 17 | "@angular/core": "~8.2.14", 18 | "@angular/forms": "~8.2.14", 19 | "@angular/platform-browser": "~8.2.14", 20 | "@angular/platform-browser-dynamic": "~8.2.14", 21 | "@angular/router": "~8.2.14", 22 | "ngx-rough-notation": "file:dist/ngx-rough-notation", 23 | "rough-notation": "^0.4.0", 24 | "rxjs": "~6.4.0", 25 | "tslib": "^1.10.0", 26 | "zone.js": "~0.9.1" 27 | }, 28 | "devDependencies": { 29 | "@angular-devkit/build-angular": "~0.803.25", 30 | "@angular-devkit/build-ng-packagr": "~0.803.25", 31 | "@angular/cli": "~8.3.25", 32 | "@angular/compiler-cli": "~8.2.14", 33 | "@angular/language-service": "~8.2.14", 34 | "@types/node": "~8.9.4", 35 | "@types/jasmine": "~3.3.8", 36 | "@types/jasminewd2": "~2.0.3", 37 | "codelyzer": "^5.0.0", 38 | "jasmine-core": "~3.4.0", 39 | "jasmine-spec-reporter": "~4.2.1", 40 | "karma": "~4.1.0", 41 | "karma-chrome-launcher": "~2.2.0", 42 | "karma-coverage-istanbul-reporter": "~2.0.1", 43 | "karma-jasmine": "~2.0.1", 44 | "karma-jasmine-html-reporter": "^1.4.0", 45 | "ng-packagr": "^5.4.0", 46 | "protractor": "~5.4.0", 47 | "ts-node": "~7.0.0", 48 | "tsickle": "^0.37.0", 49 | "tslint": "~5.15.0", 50 | "typescript": "~3.5.3" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /projects/demo-app/browserslist: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /projects/demo-app/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Protractor configuration file, see link for more information 3 | // https://github.com/angular/protractor/blob/master/lib/config.ts 4 | 5 | const { SpecReporter } = require('jasmine-spec-reporter'); 6 | 7 | /** 8 | * @type { import("protractor").Config } 9 | */ 10 | exports.config = { 11 | allScriptsTimeout: 11000, 12 | specs: [ 13 | './src/**/*.e2e-spec.ts' 14 | ], 15 | capabilities: { 16 | browserName: 'chrome' 17 | }, 18 | directConnect: true, 19 | baseUrl: 'http://localhost:4200/', 20 | framework: 'jasmine', 21 | jasmineNodeOpts: { 22 | showColors: true, 23 | defaultTimeoutInterval: 30000, 24 | print: function() {} 25 | }, 26 | onPrepare() { 27 | require('ts-node').register({ 28 | project: require('path').join(__dirname, './tsconfig.json') 29 | }); 30 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 31 | } 32 | }; -------------------------------------------------------------------------------- /projects/demo-app/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | import { browser, logging } from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', () => { 12 | page.navigateTo(); 13 | expect(page.getTitleText()).toEqual('demo-app app is running!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /projects/demo-app/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText() { 9 | return element(by.css('app-root .content span')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /projects/demo-app/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /projects/demo-app/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, '../../coverage/demo-app'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /projects/demo-app/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: sans-serif; 3 | margin: 0; 4 | } 5 | 6 | h3 { 7 | font-family: "SF Pro Display", -apple-system, BlinkMacSystemFont, 8 | "San Francisco", "Helvetica Neue", Helvetica, Ubuntu, Roboto, Noto, 9 | "Segoe UI", Arial, sans-serif; 10 | font-size: 1.6em; 11 | font-weight: 300; 12 | letter-spacing: 1px; 13 | line-height: 1.6; 14 | margin: 0; 15 | } 16 | 17 | h3::first-letter { 18 | text-transform: uppercase; 19 | } 20 | 21 | .box { 22 | font-family: "SF Pro Display", -apple-system, BlinkMacSystemFont, 23 | "San Francisco", "Helvetica Neue", Helvetica, Ubuntu, Roboto, Noto, 24 | "Segoe UI", Arial, sans-serif; 25 | font-size: 18px; 26 | line-height: 1.6; 27 | padding: 32px 0; 28 | } 29 | 30 | .content { 31 | font-size: 18px; 32 | box-sizing: border-box; 33 | font-family: "SF Pro Display", -apple-system, BlinkMacSystemFont, 34 | "San Francisco", "Helvetica Neue", Helvetica, Ubuntu, Roboto, Noto, 35 | "Segoe UI", Arial, sans-serif; 36 | line-height: 1.6; 37 | margin: 0 auto; 38 | max-width: 640px; 39 | padding: 0 16px; 40 | position: relative; 41 | } 42 | 43 | .button { 44 | background: none; 45 | border: 2px solid; 46 | cursor: pointer; 47 | display: block; 48 | font-family: inherit; 49 | font-size: 15px; 50 | font-weight: 400; 51 | letter-spacing: 1px; 52 | margin-top: 8px; 53 | outline: none; 54 | padding: 10px 16px; 55 | text-transform: uppercase; 56 | user-select: none; 57 | } 58 | 59 | input[type="color"] { 60 | background-color: transparent; 61 | border: 0; 62 | height: 24px; 63 | padding: 0; 64 | width: 24px; 65 | } 66 | 67 | .properties { 68 | padding: 1em; 69 | } 70 | 71 | label { 72 | display: block; 73 | } 74 | -------------------------------------------------------------------------------- /projects/demo-app/src/app/app.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |

Angular Rough Notation Playground

5 |
6 |
7 |
8 |
9 |

10 | 11 | Underline 12 | 13 |

14 |

create a sketchy 15 | underline below an element. 16 |

17 | 20 |
21 |
22 |
23 |
24 |

25 | Box 26 | 27 |

28 |

This style draws a box 30 | around the element.

31 | 34 |
35 |
36 |
37 |
38 |

39 | Circle 40 | 41 |

42 |

43 | Draw a circle 44 | around 45 | the element.

46 | 49 |
50 |
51 |
52 |
53 |

54 | Highlight 55 |

56 |

Creates a highlight 57 | 58 | effect as if marked 59 | by a highlighter.

60 | 63 |
64 |
65 |
66 |
67 |

68 | Strike-through 69 | 70 |

71 |

Draw a hand-drawn line through an element creating a 73 | stroke-through effect.

74 | 77 |
78 |
79 |
80 |
81 |

82 | Crossed-off 83 | 84 |

85 |

To symbolize rejection, use a crossed-off 87 | effect on an element..

88 | 91 |
92 |
93 |
94 |
95 |

96 | 97 | Brackets 98 | 99 |

100 |

Create a hand-drawn bracket around a block (like a paragraph of text) on one or multiple sides of the block. 101 |

102 |

103 | 105 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed accumsan nisi hendrerit augue molestie tempus. 106 | Phasellus purus quam, aliquet nec commodo quis, pharetra ut orci. Donec laoreet ligula nisl, 107 | placerat molestie mauris luctus id. Fusce dapibus non libero nec lobortis. Nullam iaculis nisl ac eros 108 | consequat, sit amet placerat massa vulputate. Maecenas euismod volutpat ultrices. Pellentesque felis ex, 109 | ullamcorper in felis finibus, feugiat dignissim augue. Integer malesuada non eros consectetur interdum. Mauris 110 | mollis non urna in porta. 111 | 112 |

113 | 116 |
117 |
118 |
119 |
120 |

121 | 122 | Multiple lines 123 | 124 |

125 |

Ability to annotate inline content that can span multiple lines

126 |

127 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed accumsan nisi hendrerit augue molestie tempus. 128 | Phasellus purus quam, aliquet nec commodo quis, pharetra ut orci. Donec laoreet ligula nisl, 130 | placerat molestie mauris luctus id. Fusce dapibus non libero nec lobortis. Nullam iaculis nisl ac eros 131 | consequat, sit amet placerat 132 | massa vulputate. Maecenas euismod volutpat ultrices. Pellentesque felis ex, ullamcorper in felis finibus, 133 | feugiat 134 | dignissim augue. Integer malesuada non eros consectetur interdum. Mauris mollis non urna in 135 | porta. 136 |

137 | 140 |
141 |
142 |
143 |
144 | 145 |

146 | Annotation Group 147 | 148 |

149 |

150 | Rough Notation provides a way to order the animation of annotations by creating an annotation-group. Pass the 152 | list of annotations to create a group. When show is called on the group, the annotations are animated in 154 | order. 155 |

156 |
157 | 160 |
161 |
162 |
-------------------------------------------------------------------------------- /projects/demo-app/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | 4 | describe('AppComponent', () => { 5 | beforeEach(async(() => { 6 | TestBed.configureTestingModule({ 7 | declarations: [ 8 | AppComponent 9 | ], 10 | }).compileComponents(); 11 | })); 12 | 13 | it('should create the app', () => { 14 | const fixture = TestBed.createComponent(AppComponent); 15 | const app = fixture.debugElement.componentInstance; 16 | expect(app).toBeTruthy(); 17 | }); 18 | 19 | it(`should have as title 'demo-app'`, () => { 20 | const fixture = TestBed.createComponent(AppComponent); 21 | const app = fixture.debugElement.componentInstance; 22 | expect(app.title).toEqual('demo-app'); 23 | }); 24 | 25 | it('should render title', () => { 26 | const fixture = TestBed.createComponent(AppComponent); 27 | fixture.detectChanges(); 28 | const compiled = fixture.debugElement.nativeElement; 29 | expect(compiled.querySelector('.content span').textContent).toContain('demo-app app is running!'); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /projects/demo-app/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.css'] 7 | }) 8 | export class AppComponent { 9 | title = 'demo-app'; 10 | annotations = { 11 | underline: false, 12 | box: false, 13 | circle: false, 14 | highlight: false, 15 | strikeThrough: false, 16 | crossedOff: false, 17 | group: false, 18 | multiline: false, 19 | bracket: false 20 | }; 21 | bracketsPadding = [2, 10]; 22 | brackets = ['left', 'right']; 23 | } 24 | -------------------------------------------------------------------------------- /projects/demo-app/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | 4 | import { AppComponent } from './app.component'; 5 | import { RoughNotationModule } from 'ngx-rough-notation'; 6 | 7 | @NgModule({ 8 | declarations: [ 9 | AppComponent 10 | ], 11 | imports: [ 12 | BrowserModule, 13 | RoughNotationModule 14 | ], 15 | providers: [], 16 | bootstrap: [AppComponent] 17 | }) 18 | export class AppModule { } 19 | -------------------------------------------------------------------------------- /projects/demo-app/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikyaj/ngx-rough-notation/b58ebcbf30e80839ae5c98b6af637cac48a0295b/projects/demo-app/src/assets/.gitkeep -------------------------------------------------------------------------------- /projects/demo-app/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /projects/demo-app/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /projects/demo-app/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikyaj/ngx-rough-notation/b58ebcbf30e80839ae5c98b6af637cac48a0295b/projects/demo-app/src/favicon.ico -------------------------------------------------------------------------------- /projects/demo-app/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DemoApp 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /projects/demo-app/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /projects/demo-app/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 22 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 23 | 24 | /** 25 | * Web Animations `@angular/platform-browser/animations` 26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 28 | */ 29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 30 | 31 | /** 32 | * By default, zone.js will patch all possible macroTask and DomEvents 33 | * user can disable parts of macroTask/DomEvents patch by setting following flags 34 | * because those flags need to be set before `zone.js` being loaded, and webpack 35 | * will put import in the top of bundle, so user need to create a separate file 36 | * in this directory (for example: zone-flags.ts), and put the following flags 37 | * into that file, and then add the following code before importing zone.js. 38 | * import './zone-flags.ts'; 39 | * 40 | * The flags allowed in zone-flags.ts are listed here. 41 | * 42 | * The following flags will work for all browsers. 43 | * 44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 46 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 47 | * 48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 50 | * 51 | * (window as any).__Zone_enable_cross_context_check = true; 52 | * 53 | */ 54 | 55 | /*************************************************************************************************** 56 | * Zone JS is required by default for Angular itself. 57 | */ 58 | import 'zone.js/dist/zone'; // Included with Angular CLI. 59 | 60 | 61 | /*************************************************************************************************** 62 | * APPLICATION IMPORTS 63 | */ 64 | -------------------------------------------------------------------------------- /projects/demo-app/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /projects/demo-app/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /projects/demo-app/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/app", 5 | "types": [] 6 | }, 7 | "files": [ 8 | "src/main.ts", 9 | "src/polyfills.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.ts" 13 | ], 14 | "exclude": [ 15 | "src/test.ts", 16 | "src/**/*.spec.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /projects/demo-app/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /projects/demo-app/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "app", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "app", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /projects/ngx-rough-notation/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Mudasse Ajaz 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. 22 | -------------------------------------------------------------------------------- /projects/ngx-rough-notation/README.md: -------------------------------------------------------------------------------- 1 | # Angular wrapper for Rough Notation library 2 | 3 | 4 | This is an Angular wrapper for [RoughNotation](https://roughnotation.com/), a small JavaScript library to create and animate annotations on a web page. 5 | 6 | - [Visit website to see it in action](https://roughnotation.com/) 7 | - [Library docs](https://github.com/pshihn/rough-notation) 8 | 9 | ![Rough Notation logo](https://roughnotation.com/images/social.png) 10 | 11 | ## Demo 12 | You can play around with the demo [here](https://stackblitz.com/edit/angular-n9jsex). 13 | 14 | ## Installation 15 | 16 | Install rough-notation, which is peer dependency to this wrapper. 17 | ``` 18 | npm install --save rough-notation 19 | ``` 20 | Install wrapper. 21 | ``` 22 | npm install --save ngx-rough-notation 23 | ``` 24 | 25 | Import wrapper module into your app mobule 26 | 27 | ```js 28 | import { RoughNotationModule } from 'ngx-rough-notation'; 29 | ``` 30 | 31 | ## RoughNotation Component 32 | 33 | 34 | ### Usage 35 | 36 | ```html 37 | 38 | Hello I am a notation 39 | 40 | ``` 41 | 42 | ### Properties 43 | 44 | Following configurations can be passed to compeo 45 | 46 | | name | type | default | description | 47 | | ------------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 48 | | animate | `boolean` | `true` | Turn on/off animation when annotating | 49 | | animationDelay | `number` | `0` | Delay in animation in milliseconds | 50 | | animationDuration | `number` | `800` | Duration of the animation in milliseconds | 51 | | color | `string` | | String value representing the color of the annotation sketch 52 | | iterations | `number` | `2` | By default annotations are drawn in two iterations, e.g. when underlining, drawing from left to right and then back from right to left. Setting this property can let you configure the number of iterations. | 53 | | padding | `number`, `[top, right, bottom, left]`, `[vertical, horizontal]` | `5` | Padding in pixels between the element and roughly where the annotation is drawn. If you wish to specify different `top`, `left`, `right`, `bottom` paddings, you can set the value to an array akin to CSS style padding `[top, right, bottom, left]` or just `[top & bottom, left & right]` | 54 | | show | `boolean` | `false` | Show/hide the annotation | 55 | | strokeWidth | `number` | `1 | Width of the annotation strokes | | type |`enum`|`underline`,`box`,`circle`,`highlight`,`strike-through`,`crossed-off` | This is a mandatory field. It sets the annotation style | 56 | 57 | ### Type values 58 | 59 | | value | description | 60 | | -------------- | ------------------------------------------------------- | 61 | | underline | Create a sketchy underline below an element | 62 | | box | This style draws a box around the element | 63 | | circle | Draw a circle around the element | 64 | | highlight | Creates a highlight effect as if maked by a highlighter | 65 | | strike-through | This style draws a box around the element | 66 | | crossed-off | This style draws a box around the element | 67 | 68 | ## RoughNotation Group Component 69 | 70 | This is a wrapper for multiple annotations, it will trigger the `show()` method on every child annotation. 71 | 72 | ### Usage 73 | 74 | ```html 75 | 76 | 77 | Circle 78 | 79 | 80 | Highlight 81 | 82 | 83 | ``` 84 | 85 | ### Properties 86 | 87 | | name | type | default | description | 88 | | ---- | ------- | ------- | -------------------------- | 89 | | show | boolean | false | show/hides the annotations | 90 | 91 | 92 | ## TODO 93 | - Custom ordering of annotations triggering in group component 94 | - Testing 95 | -------------------------------------------------------------------------------- /projects/ngx-rough-notation/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, '../../coverage/ngx-rough-notation'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /projects/ngx-rough-notation/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/ngx-rough-notation", 4 | "lib": { 5 | "entryFile": "src/public-api.ts", 6 | "umdModuleIds": { 7 | "rough-notation": "rough-notation" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /projects/ngx-rough-notation/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ngx-rough-notation", 3 | "version": "0.0.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@angular/common": { 8 | "version": "8.2.14", 9 | "resolved": "https://registry.npmjs.org/@angular/common/-/common-8.2.14.tgz", 10 | "integrity": "sha512-Qmt+aX2quUW54kaNT7QH7WGXnFxr/cC2C6sf5SW5SdkZfDQSiz8IaItvieZfXVQUbBOQKFRJ7TlSkt0jI/yjvw==", 11 | "requires": { 12 | "tslib": "^1.9.0" 13 | } 14 | }, 15 | "@angular/core": { 16 | "version": "8.2.14", 17 | "resolved": "https://registry.npmjs.org/@angular/core/-/core-8.2.14.tgz", 18 | "integrity": "sha512-zeePkigi+hPh3rN7yoNENG/YUBUsIvUXdxx+AZq+QPaFeKEA2FBSrKn36ojHFrdJUjKzl0lPMEiGC2b6a6bo6g==", 19 | "requires": { 20 | "tslib": "^1.9.0" 21 | } 22 | }, 23 | "rough-notation": { 24 | "version": "0.3.1", 25 | "resolved": "https://registry.npmjs.org/rough-notation/-/rough-notation-0.3.1.tgz", 26 | "integrity": "sha512-WrUTmZa1CxuW2KdghcppZ7WBk7An/ty1bQ5kpYwl5YtXSBCEINa6NO7wx+pViO9TwlMqmIZuRxCJiWtYcIOK0w==" 27 | }, 28 | "tslib": { 29 | "version": "1.13.0", 30 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", 31 | "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /projects/ngx-rough-notation/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ngx-rough-notation", 3 | "version": "0.4.0", 4 | "description": "Angular wrapper for rough-notation", 5 | "author": "Mudasser Ajaz", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/mikyaj/ngx-rough-notation.git" 9 | }, 10 | "bugs": { 11 | "url": "https://github.com/mikyaj/ngx-rough-notation/issues" 12 | }, 13 | "homepage": "https://github.com/mikyaj/ngx-rough-notation", 14 | "keywords": [ 15 | "angular", 16 | "angular 8", 17 | "angular 9", 18 | "rough notation", 19 | "angular rough notation", 20 | "angular wrapper rough notation" 21 | ], 22 | "peerDependencies": { 23 | "@angular/common": "^8.2.14", 24 | "@angular/core": "^8.2.14", 25 | "rough-notation": "^0.4.0" 26 | }, 27 | "license": "MIT" 28 | } 29 | -------------------------------------------------------------------------------- /projects/ngx-rough-notation/src/lib/components/rough-notation-group/index.ts: -------------------------------------------------------------------------------- 1 | export { RoughNotationGroupComponent } from './rough-notation-group.component'; 2 | -------------------------------------------------------------------------------- /projects/ngx-rough-notation/src/lib/components/rough-notation-group/rough-notation-group.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /projects/ngx-rough-notation/src/lib/components/rough-notation-group/rough-notation-group.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, QueryList, AfterContentInit, ContentChildren, Input } from '@angular/core'; 2 | import { RoughNotationComponent } from '../rough-notation/rough-notation.component'; 3 | 4 | @Component({ 5 | selector: 'rough-notation-group', 6 | templateUrl: 'rough-notation-group.component.html' 7 | }) 8 | 9 | export class RoughNotationGroupComponent implements AfterContentInit { 10 | public showAll: boolean; 11 | @Input() 12 | set show(value: boolean) { 13 | this.showAll = value; 14 | this.updateAnnotationsVisiblity(value); 15 | } 16 | @ContentChildren(RoughNotationComponent) annotations: QueryList; 17 | 18 | ngAfterContentInit(): void { 19 | this.updateAnnotationsVisiblity(this.showAll); 20 | } 21 | 22 | updateAnnotationsVisiblity(value: boolean): void { 23 | if (this.annotations) { 24 | this.annotations.forEach((comp) => { 25 | comp.show = this.showAll; 26 | }); 27 | } 28 | } 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /projects/ngx-rough-notation/src/lib/components/rough-notation/index.ts: -------------------------------------------------------------------------------- 1 | export { RoughNotationComponent } from './rough-notation.component'; 2 | export { types, Annotation, RoughNotationProperties } from './types'; 3 | -------------------------------------------------------------------------------- /projects/ngx-rough-notation/src/lib/components/rough-notation/rough-notation.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /projects/ngx-rough-notation/src/lib/components/rough-notation/rough-notation.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, ElementRef, AfterContentInit, OnDestroy, Input } from '@angular/core'; 2 | import { annotate } from 'rough-notation'; 3 | import { Annotation, types, RoughPadding } from './types'; 4 | import { BracketType } from 'rough-notation/lib/model'; 5 | 6 | @Component({ 7 | // tslint:disable-next-line:component-selector 8 | selector: 'rough-notation', 9 | templateUrl: './rough-notation.component.html' 10 | }) 11 | 12 | export class RoughNotationComponent implements AfterContentInit, OnDestroy { 13 | public annotation: Annotation; 14 | private _show = false; 15 | private _color = 'currentColor'; 16 | private _strokeWidth = 1; 17 | private _padding: RoughPadding = 5; 18 | @Input() type: types; 19 | @Input() multiline: boolean; 20 | @Input() animate = true; 21 | @Input() animationDuration = 800; 22 | @Input() iterations = 2; 23 | @Input() brackets: BracketType | BracketType[] = 'right'; 24 | 25 | @Input() 26 | set color(value: string) { 27 | this._color = value; 28 | if (this.annotation) { 29 | this.annotation.color = value; 30 | } 31 | } 32 | 33 | @Input() 34 | set strokeWidth(value: number) { 35 | this._strokeWidth = value; 36 | if (this.annotation) { 37 | this.annotation.strokeWidth = value; 38 | } 39 | } 40 | 41 | @Input() 42 | set padding(value: RoughPadding) { 43 | this._padding = value; 44 | if (this.annotation) { 45 | this.annotation.padding = value; 46 | } 47 | } 48 | 49 | @Input() 50 | set show(value: boolean) { 51 | this._show = value; 52 | if (this.annotation) { 53 | this.updateAnnotationVisibility(value); 54 | } 55 | } 56 | 57 | constructor(private elementRef: ElementRef) { } 58 | 59 | ngAfterContentInit(): void { 60 | const ele = this.elementRef.nativeElement; 61 | if (ele && this.type) { 62 | this.annotation = annotate(ele, { 63 | type: this.type, 64 | color: this._color, 65 | animate: this.animate, 66 | animationDuration: this.animationDuration, 67 | strokeWidth: this._strokeWidth, 68 | padding: this._padding, 69 | iterations: this.iterations, 70 | multiline: this.multiline, 71 | brackets: this.brackets 72 | }); 73 | if (this._show === true) { 74 | this.annotation.show(); 75 | } 76 | } 77 | } 78 | 79 | private updateAnnotationVisibility(value: boolean): void { 80 | if (value === true) { 81 | this.annotation.show(); 82 | } else { 83 | this.annotation.hide(); 84 | } 85 | } 86 | 87 | ngOnDestroy(): void { 88 | this.annotation.remove(); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /projects/ngx-rough-notation/src/lib/components/rough-notation/types.ts: -------------------------------------------------------------------------------- 1 | export type types = 2 | | 'underline' 3 | | 'box' 4 | | 'circle' 5 | | 'highlight' 6 | | 'strike-through' 7 | | 'crossed-off' 8 | | 'bracket'; 9 | 10 | export type FullPadding = [number, number, number, number]; 11 | export type RoughPadding = number | [number, number] | FullPadding; 12 | export type BracketType = 'left' | 'right' | 'top' | 'bottom'; 13 | 14 | export interface RoughNotationProperties { 15 | animate?: boolean; 16 | animationDuration?: number; 17 | color?: string; 18 | iterations?: number; 19 | padding?: RoughPadding; 20 | strokeWidth?: number; 21 | brackets?: BracketType | BracketType[]; // defaults to 'right' 22 | } 23 | 24 | export interface Annotation extends RoughNotationProperties { 25 | hide?: () => void; 26 | remove?: () => void; 27 | show?: () => void; 28 | } 29 | -------------------------------------------------------------------------------- /projects/ngx-rough-notation/src/lib/rough-notation.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RoughNotationComponent } from './components/rough-notation'; 3 | import { RoughNotationGroupComponent } from './components/rough-notation-group'; 4 | 5 | 6 | 7 | @NgModule({ 8 | declarations: [RoughNotationComponent, RoughNotationGroupComponent], 9 | imports: [ 10 | ], 11 | exports: [RoughNotationComponent, RoughNotationGroupComponent] 12 | }) 13 | export class RoughNotationModule { } 14 | -------------------------------------------------------------------------------- /projects/ngx-rough-notation/src/public-api.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Public API Surface of ngx-rough-notation 3 | */ 4 | 5 | export * from './lib/components/rough-notation'; 6 | export * from './lib/components/rough-notation-group'; 7 | export * from './lib/components/rough-notation/types'; 8 | export * from './lib/rough-notation.module'; 9 | -------------------------------------------------------------------------------- /projects/ngx-rough-notation/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone'; 4 | import 'zone.js/dist/zone-testing'; 5 | import { getTestBed } from '@angular/core/testing'; 6 | import { 7 | BrowserDynamicTestingModule, 8 | platformBrowserDynamicTesting 9 | } from '@angular/platform-browser-dynamic/testing'; 10 | 11 | declare const require: any; 12 | 13 | // First, initialize the Angular testing environment. 14 | getTestBed().initTestEnvironment( 15 | BrowserDynamicTestingModule, 16 | platformBrowserDynamicTesting() 17 | ); 18 | // Then we find all the tests. 19 | const context = require.context('./', true, /\.spec\.ts$/); 20 | // And load the modules. 21 | context.keys().map(context); 22 | -------------------------------------------------------------------------------- /projects/ngx-rough-notation/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/lib", 5 | "target": "es2015", 6 | "declaration": true, 7 | "inlineSources": true, 8 | "types": [], 9 | "lib": [ 10 | "dom", 11 | "es2018" 12 | ] 13 | }, 14 | "angularCompilerOptions": { 15 | "annotateForClosureCompiler": true, 16 | "skipTemplateCodegen": true, 17 | "strictMetadataEmit": true, 18 | "fullTemplateTypeCheck": true, 19 | "strictInjectionParameters": true, 20 | "enableResourceInlining": true 21 | }, 22 | "exclude": [ 23 | "src/test.ts", 24 | "**/*.spec.ts" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /projects/ngx-rough-notation/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts" 12 | ], 13 | "include": [ 14 | "**/*.spec.ts", 15 | "**/*.d.ts" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /projects/ngx-rough-notation/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "lib", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "lib", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "experimentalDecorators": true, 10 | "module": "esnext", 11 | "moduleResolution": "node", 12 | "importHelpers": true, 13 | "target": "es2015", 14 | "typeRoots": [ 15 | "node_modules/@types" 16 | ], 17 | "lib": [ 18 | "es2018", 19 | "dom" 20 | ], 21 | "paths": { 22 | "ngx-rough-notation": [ 23 | "dist/ngx-rough-notation" 24 | ], 25 | "ngx-rough-notation/*": [ 26 | "dist/ngx-rough-notation/*" 27 | ] 28 | } 29 | }, 30 | "angularCompilerOptions": { 31 | "fullTemplateTypeCheck": true, 32 | "strictInjectionParameters": true 33 | } 34 | } -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint:recommended", 3 | "rulesDirectory": [ 4 | "codelyzer" 5 | ], 6 | "rules": { 7 | "array-type": false, 8 | "arrow-parens": false, 9 | "deprecation": { 10 | "severity": "warning" 11 | }, 12 | "import-blacklist": [ 13 | true, 14 | "rxjs/Rx" 15 | ], 16 | "interface-name": false, 17 | "max-classes-per-file": false, 18 | "max-line-length": [ 19 | true, 20 | 140 21 | ], 22 | "member-access": false, 23 | "member-ordering": [ 24 | true, 25 | { 26 | "order": [ 27 | "static-field", 28 | "instance-field", 29 | "static-method", 30 | "instance-method" 31 | ] 32 | } 33 | ], 34 | "no-consecutive-blank-lines": false, 35 | "no-console": [ 36 | true, 37 | "debug", 38 | "info", 39 | "time", 40 | "timeEnd", 41 | "trace" 42 | ], 43 | "no-empty": false, 44 | "no-inferrable-types": [ 45 | true, 46 | "ignore-params" 47 | ], 48 | "no-non-null-assertion": true, 49 | "no-redundant-jsdoc": true, 50 | "no-switch-case-fall-through": true, 51 | "no-var-requires": false, 52 | "object-literal-key-quotes": [ 53 | true, 54 | "as-needed" 55 | ], 56 | "object-literal-sort-keys": false, 57 | "ordered-imports": false, 58 | "quotemark": [ 59 | true, 60 | "single" 61 | ], 62 | "trailing-comma": false, 63 | "component-class-suffix": true, 64 | "contextual-lifecycle": true, 65 | "directive-class-suffix": true, 66 | "no-conflicting-lifecycle": true, 67 | "no-host-metadata-property": true, 68 | "no-input-rename": true, 69 | "no-inputs-metadata-property": true, 70 | "no-output-native": true, 71 | "no-output-on-prefix": true, 72 | "no-output-rename": true, 73 | "no-outputs-metadata-property": true, 74 | "template-banana-in-box": true, 75 | "template-no-negated-async": true, 76 | "use-lifecycle-interface": true, 77 | "use-pipe-transform-interface": true, 78 | "variable-name": { 79 | "options": [ 80 | "check-format", 81 | "allow-leading-underscore" 82 | ] 83 | } 84 | } 85 | } 86 | --------------------------------------------------------------------------------