├── src ├── assets │ └── .gitkeep ├── favicon.ico ├── environments │ ├── environment.prod.ts │ └── environment.ts ├── libs │ └── angular-signature-pad │ │ ├── public_api.ts │ │ ├── ng-package.json │ │ ├── .gitignore │ │ ├── src │ │ ├── interfaces │ │ │ ├── signature-segment.interfcae.ts │ │ │ └── signature-pad-config.interface.ts │ │ ├── tokens │ │ │ └── global-config.token.ts │ │ ├── angular-signature-pad.module.spec.ts │ │ ├── validators │ │ │ ├── is-array.validation.ts │ │ │ ├── min-lines.validation.ts │ │ │ ├── consists-of-arrays.validation.ts │ │ │ ├── min-points-in-each-n-lines.validator.ts │ │ │ └── constists-of-object.validation.ts │ │ ├── pipes │ │ │ └── obj-to-array.pipe.ts │ │ ├── components │ │ │ ├── signature-pad │ │ │ │ ├── signature-pad.component.spec.ts │ │ │ │ └── signature-pad.component.ts │ │ │ ├── signature-pad-card-group │ │ │ │ ├── signature-pad-card-group.component.ts │ │ │ │ └── signature-pad-card-group.component.html │ │ │ ├── signature-pad-card │ │ │ │ ├── signature-pad-card.component.html │ │ │ │ └── signature-pad-card.component.ts │ │ │ └── signature-pad-control │ │ │ │ └── signature-pad-control.component.ts │ │ ├── angular-signature-pad.module.ts │ │ └── styles.scss │ │ ├── package.json │ │ ├── README.md │ │ └── CHANGELOG.md ├── typings.d.ts ├── app │ ├── pages │ │ ├── signature-pad-card │ │ │ ├── signature-pad-card.component.html │ │ │ ├── signature-pad-card-routing.module.ts │ │ │ ├── signature-pad-card.module.ts │ │ │ └── signature-pad-card.component.ts │ │ ├── signature-pad-card-group │ │ │ ├── signature-pad-card-group.component.html │ │ │ ├── signature-pad-card-group-routing.module.ts │ │ │ ├── signature-pad-card-group.module.ts │ │ │ └── signature-pad-card-group.component.ts │ │ ├── signature-pad │ │ │ ├── signature-pad.component.ts │ │ │ ├── signature-pad.component.html │ │ │ ├── signature-pad-routing.module.ts │ │ │ └── signature-pad.module.ts │ │ ├── signature-pad-control │ │ │ ├── signature-pad-control-routing.module.ts │ │ │ ├── signature-pad-control.module.ts │ │ │ ├── signature-pad-control.component.ts │ │ │ └── signature-pad-control.component.html │ │ ├── demo │ │ │ ├── demo.component.ts │ │ │ ├── demo.routing.module.ts │ │ │ ├── demo.module.ts │ │ │ └── demo.component.html │ │ ├── signature-pad-configuration │ │ │ ├── signature-pad-configuration-routing.module.ts │ │ │ ├── signature-pad-configuration.module.ts │ │ │ ├── signature-pad-configuration.component.ts │ │ │ └── signature-pad-configuration.component.html │ │ └── signature-pad-control-validation │ │ │ ├── signature-pad-control-validation-routing.module.ts │ │ │ ├── signature-pad-control-validation.module.ts │ │ │ ├── signature-pad-control-validation.component.html │ │ │ └── signature-pad-control-validation.component.ts │ ├── layout │ │ ├── layout.scss │ │ └── vendors.scss │ ├── shared │ │ ├── shared.module.ts │ │ └── components │ │ │ └── control-state │ │ │ ├── control-state.component.ts │ │ │ └── control-state.component.html │ ├── core │ │ └── core.module.ts │ ├── app.component.ts │ ├── app.module.ts │ ├── app.routing.module.ts │ └── app.component.html ├── styles.scss ├── index.html ├── tsconfig.app.json ├── tsconfig.spec.json ├── main.ts ├── test.ts └── polyfills.ts ├── docs ├── favicon.ico ├── fontawesome-webfont.674f50d287a8c48dc19b.eot ├── fontawesome-webfont.b06871f281fee6b241d6.ttf ├── fontawesome-webfont.fee66e712a8a08eef580.woff ├── fontawesome-webfont.af7ae505a9eed503f8b8.woff2 ├── index.html ├── inline.f7fd537c847050bbfb16.bundle.js ├── 1.522f1586c79936db9acc.chunk.js ├── 5.94af90d1b03e5075fb46.chunk.js ├── 4.0aca6a203232d2b2acf4.chunk.js ├── 3rdpartylicenses.txt ├── 3.86da506e6b0a467403f8.chunk.js ├── 2.eec02abcb26b78e315fd.chunk.js └── main.18646811113195bff36f.bundle.js ├── resources ├── demo.WMV └── demo.gif ├── e2e ├── app.po.ts ├── tsconfig.e2e.json └── app.e2e-spec.ts ├── .editorconfig ├── .travis.yml ├── chore ├── README.md ├── config.js └── scripts │ ├── tasks │ ├── ci-check.js │ ├── release-npm.js │ ├── refresh.js │ ├── release-github.js │ ├── build.js │ ├── version-bump.js │ └── changelog.js │ ├── release.js │ └── utils.js ├── tsconfig.json ├── .gitignore ├── protractor.conf.js ├── karma.conf.js ├── LICENSE ├── .angular-cli.json ├── README.md ├── package.json └── tslint.json /src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BioPhoton/angular-signature-pad/HEAD/src/favicon.ico -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BioPhoton/angular-signature-pad/HEAD/docs/favicon.ico -------------------------------------------------------------------------------- /resources/demo.WMV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BioPhoton/angular-signature-pad/HEAD/resources/demo.WMV -------------------------------------------------------------------------------- /resources/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BioPhoton/angular-signature-pad/HEAD/resources/demo.gif -------------------------------------------------------------------------------- /src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/public_api.ts: -------------------------------------------------------------------------------- 1 | export * from './src/angular-signature-pad.module'; 2 | -------------------------------------------------------------------------------- /src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /docs/fontawesome-webfont.674f50d287a8c48dc19b.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BioPhoton/angular-signature-pad/HEAD/docs/fontawesome-webfont.674f50d287a8c48dc19b.eot -------------------------------------------------------------------------------- /docs/fontawesome-webfont.b06871f281fee6b241d6.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BioPhoton/angular-signature-pad/HEAD/docs/fontawesome-webfont.b06871f281fee6b241d6.ttf -------------------------------------------------------------------------------- /docs/fontawesome-webfont.fee66e712a8a08eef580.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BioPhoton/angular-signature-pad/HEAD/docs/fontawesome-webfont.fee66e712a8a08eef580.woff -------------------------------------------------------------------------------- /docs/fontawesome-webfont.af7ae505a9eed503f8b8.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BioPhoton/angular-signature-pad/HEAD/docs/fontawesome-webfont.af7ae505a9eed503f8b8.woff2 -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "lib": { 4 | "entryFile": "./public_api.ts" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /.ng_build/ 5 | /dist/ 6 | /tmp 7 | /out-tsc 8 | 9 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad-card/signature-pad-card.component.html: -------------------------------------------------------------------------------- 1 |

2 | SignaturePad Card 3 |

4 | 5 |
6 | 7 |
8 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/src/interfaces/signature-segment.interfcae.ts: -------------------------------------------------------------------------------- 1 | export interface ISignatureSegment { 2 | x: number; 3 | y: number; 4 | time: number; 5 | color: string; 6 | } 7 | 8 | export type signatureData = ISignatureSegment[][]; 9 | -------------------------------------------------------------------------------- /e2e/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css('app-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | @import "app/layout/layout"; 3 | 4 | @import "../node_modules/angular-signature-pad/styles"; 5 | 6 | .signature-pad-canvas { 7 | border: 2px dashed $signature-pad-border; 8 | } 9 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad-card-group/signature-pad-card-group.component.html: -------------------------------------------------------------------------------- 1 |

2 | SignaturePad Card Group 3 |

4 | 5 |
6 | 7 |
8 | -------------------------------------------------------------------------------- /src/app/layout/layout.scss: -------------------------------------------------------------------------------- 1 | @import "vendors"; 2 | 3 | #main-container, html, body { 4 | height:100%; 5 | margin:0; 6 | } 7 | body { 8 | padding-top: 3.5rem; 9 | } 10 | #main-container { 11 | display: flex; 12 | flex-direction: column; 13 | } 14 | 15 | #main-content { 16 | flex-grow: 1; 17 | } 18 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "baseUrl": "./", 6 | "module": "commonjs", 7 | "target": "es5", 8 | "types": [ 9 | "jasmine", 10 | "jasminewd2", 11 | "node" 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/src/tokens/global-config.token.ts: -------------------------------------------------------------------------------- 1 | import {InjectionToken} from '@angular/core'; 2 | import {ISignaturePadConfig} from '../interfaces/signature-pad-config.interface'; 3 | 4 | export const GlobalSignaturePadConfig = new InjectionToken('Global SignaturePad default config'); 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | sudo: false 3 | node_js: 4 | - '8.6.0' 5 | 6 | cache: 7 | directories: 8 | 9 | install: 10 | - npm i 11 | 12 | before_script: 13 | 14 | script: 15 | - npm run coverage 16 | 17 | after_success: 18 | - cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js 19 | - rm -rf ./coverage 20 | -------------------------------------------------------------------------------- /chore/README.md: -------------------------------------------------------------------------------- 1 | # Preconditions 2 | 3 | node modules to install globally: 4 | - conventional-recommended-bump 5 | - conventional-changelog 6 | - conventional-github-releaser 7 | - conventional-commits-detector 8 | 9 | `npm i -g color conventional-recommended-bump conventional-changelog conventional-github-releaser conventional-commits-detector` 10 | -------------------------------------------------------------------------------- /e2e/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | 3 | describe('ng-pack-test App', () => { 4 | let page: AppPage; 5 | 6 | beforeEach(() => { 7 | page = new AppPage(); 8 | }); 9 | 10 | it('should display welcome message', () => { 11 | page.navigateTo(); 12 | expect(page.getParagraphText()).toEqual('Welcome to app!'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Angular Signature Pad 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "baseUrl": "./", 6 | "module": "es2015", 7 | "types": [], 8 | "paths": { 9 | "@angular-signature-pad/lib": [ "../dist/my-lib" ] 10 | } 11 | }, 12 | "exclude": [ 13 | "test.ts", 14 | "**/*.spec.ts" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /chore/config.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | global.__base = __dirname + '/../' 4 | 5 | const path = require('path') 6 | const util = require('util') 7 | 8 | const config = {} 9 | config.libPath = path.join(__base, 'src', 'libs', 'angular-signature-pad') 10 | config.debugMode = true 11 | config.validPreset = 'angular' 12 | config.ci = {} 13 | config.ci.validState = 'passed' 14 | 15 | module.exports = config 16 | -------------------------------------------------------------------------------- /src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "baseUrl": "./", 6 | "module": "commonjs", 7 | "target": "es5", 8 | "types": [ 9 | "jasmine", 10 | "node" 11 | ] 12 | }, 13 | "files": [ 14 | "test.ts" 15 | ], 16 | "include": [ 17 | "**/*.spec.ts", 18 | "**/*.d.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad/signature-pad.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-signature-pad', 5 | templateUrl: './signature-pad.component.html' 6 | }) 7 | export class SignaturePadComponent { 8 | 9 | lastChange = []; 10 | 11 | constructor() { 12 | } 13 | 14 | setLastChange(value): void { 15 | this.lastChange = value; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/app/shared/shared.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import {ControlStateComponent} from './components/control-state/control-state.component'; 4 | 5 | @NgModule({ 6 | imports: [ 7 | CommonModule 8 | ], 9 | declarations: [ControlStateComponent], 10 | exports: [ControlStateComponent] 11 | }) 12 | export class SharedModule { } 13 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad/signature-pad.component.html: -------------------------------------------------------------------------------- 1 |

2 | SignaturePad 3 |

4 | 5 | 6 | 7 | value: 8 |
 9 |   {{sigPad.value | json}}
10 | 
11 | valueChanged to: 12 |
13 |   {{lastChange | json}}
14 | 
15 | 16 | 17 | -------------------------------------------------------------------------------- /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.log(err)); 13 | -------------------------------------------------------------------------------- /src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false 8 | }; 9 | -------------------------------------------------------------------------------- /src/app/core/core.module.ts: -------------------------------------------------------------------------------- 1 | import {CommonModule} from '@angular/common'; 2 | import {HttpClientModule} from '@angular/common/http'; 3 | import {ModuleWithProviders, NgModule} from '@angular/core'; 4 | 5 | @NgModule({ 6 | imports: [ 7 | HttpClientModule, 8 | CommonModule 9 | ] 10 | }) 11 | export class CoreModule { 12 | static forRoot(): ModuleWithProviders { 13 | return { 14 | ngModule: CoreModule, 15 | providers: [] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html' 6 | }) 7 | export class AppComponent { 8 | navBarCollapsed = true; 9 | 10 | constructor() { 11 | } 12 | 13 | toggleNav(closeOnly?: boolean) { 14 | if (closeOnly) { 15 | this.navBarCollapsed = true; 16 | } else { 17 | this.navBarCollapsed = !this.navBarCollapsed; 18 | } 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "outDir": "./dist/out-tsc", 5 | "sourceMap": true, 6 | "allowJs": true, 7 | "declaration": false, 8 | "moduleResolution": "node", 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "target": "es5", 12 | "typeRoots": [ 13 | "node_modules/@types" 14 | ], 15 | "lib": [ 16 | "es2017", 17 | "dom" 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/src/angular-signature-pad.module.spec.ts: -------------------------------------------------------------------------------- 1 | import { AngularSignaturePadModule } from './angular-signature-pad.module'; 2 | 3 | describe('AngularSignaturePadModule', () => { 4 | let angularSignaturePadModule: AngularSignaturePadModule; 5 | 6 | beforeEach(() => { 7 | angularSignaturePadModule = new AngularSignaturePadModule(); 8 | }); 9 | 10 | it('should create an instance', () => { 11 | expect(angularSignaturePadModule).toBeTruthy(); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad/signature-pad-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | import {SignaturePadComponent} from './signature-pad.component'; 4 | 5 | const routes: Routes = [ 6 | { 7 | path: '', 8 | component: SignaturePadComponent 9 | } 10 | ]; 11 | 12 | @NgModule({ 13 | imports: [RouterModule.forChild(routes)], 14 | exports: [RouterModule] 15 | }) 16 | export class SignaturePadRoutingModule { } 17 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad-card/signature-pad-card-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | import {SignaturePadCardComponent} from './signature-pad-card.component'; 4 | 5 | const routes: Routes = [ 6 | { 7 | path: '', 8 | component: SignaturePadCardComponent 9 | } 10 | ]; 11 | 12 | @NgModule({ 13 | imports: [RouterModule.forChild(routes)], 14 | exports: [RouterModule] 15 | }) 16 | export class SignaturePadCardRoutingModule { } 17 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/src/validators/is-array.validation.ts: -------------------------------------------------------------------------------- 1 | import {AbstractControl, ValidationErrors} from '@angular/forms'; 2 | 3 | export function isArray(c: AbstractControl): null | ValidationErrors { 4 | if (c.value) { 5 | const error = { 6 | isArray: { 7 | message: 'signature is no array' 8 | } 9 | }; 10 | 11 | const arrayConstructor = [].constructor; 12 | if (c.value.constructor !== arrayConstructor) { 13 | return error; 14 | } 15 | } 16 | return null; 17 | } 18 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad-control/signature-pad-control-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | import {SignaturePadControlComponent} from './signature-pad-control.component'; 4 | 5 | const routes: Routes = [ 6 | { 7 | path: '', 8 | component: SignaturePadControlComponent 9 | } 10 | ]; 11 | 12 | @NgModule({ 13 | imports: [RouterModule.forChild(routes)], 14 | exports: [RouterModule] 15 | }) 16 | export class SignaturePadControlRoutingModule { } 17 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/src/pipes/obj-to-array.pipe.ts: -------------------------------------------------------------------------------- 1 | import {Pipe, PipeTransform} from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'objToArray' 5 | }) 6 | export class ObjToArrayPipe implements PipeTransform { 7 | 8 | transform(value: any, args?: any): any { 9 | const objCtor = {}.constructor; 10 | if (value && value.constructor === objCtor) { 11 | return Object.keys(value) 12 | .map(key => { 13 | return {key, value: value[key]}; 14 | }); 15 | } 16 | return value; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad-card-group/signature-pad-card-group-routing.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {RouterModule, Routes} from '@angular/router'; 3 | import {SignaturePadCardGroupComponent} from './signature-pad-card-group.component'; 4 | 5 | const routes: Routes = [ 6 | { 7 | path: '', 8 | component: SignaturePadCardGroupComponent 9 | } 10 | ]; 11 | 12 | @NgModule({ 13 | imports: [RouterModule.forChild(routes)], 14 | exports: [RouterModule] 15 | }) 16 | export class SignaturePadCardGroupRoutingModule { } 17 | -------------------------------------------------------------------------------- /src/app/pages/demo/demo.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {FormBuilder, FormGroup} from '@angular/forms'; 3 | 4 | @Component({ 5 | selector: 'app-demo', 6 | templateUrl: './demo.component.html' 7 | }) 8 | export class DemoComponent implements OnInit { 9 | 10 | testForm: FormGroup; 11 | 12 | constructor(private fb: FormBuilder) { 13 | } 14 | 15 | ngOnInit() { 16 | this.testForm = this.fb.group({ 17 | firstName: [], 18 | lastName: [], 19 | signature: [[]] 20 | }); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad-configuration/signature-pad-configuration-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | import {SignaturePadConfigurationComponent} from './signature-pad-configuration.component'; 4 | 5 | const routes: Routes = [ 6 | { 7 | path: '', 8 | component: SignaturePadConfigurationComponent 9 | } 10 | ]; 11 | 12 | @NgModule({ 13 | imports: [RouterModule.forChild(routes)], 14 | exports: [RouterModule] 15 | }) 16 | export class SignaturePadConfigurationRoutingModule { } 17 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad-control-validation/signature-pad-control-validation-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | import {SignaturePadControlValidationComponent} from './signature-pad-control-validation.component'; 4 | 5 | const routes: Routes = [ 6 | { 7 | path: '', 8 | component: SignaturePadControlValidationComponent 9 | } 10 | ]; 11 | 12 | @NgModule({ 13 | imports: [RouterModule.forChild(routes)], 14 | exports: [RouterModule] 15 | }) 16 | export class SignaturePadControlValidationRoutingModule { } 17 | -------------------------------------------------------------------------------- /src/app/pages/demo/demo.routing.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {ExtraOptions, RouterModule, Routes} from '@angular/router'; 3 | import {DemoComponent} from './demo.component'; 4 | 5 | const BASIC_IMPLEMENTATION_ROUTES: Routes = [ 6 | { 7 | path: '', 8 | component: DemoComponent } 9 | ]; 10 | 11 | const extraOptions: ExtraOptions = { 12 | useHash: true 13 | }; 14 | 15 | @NgModule({ 16 | imports: [ 17 | RouterModule.forChild(BASIC_IMPLEMENTATION_ROUTES) 18 | ], 19 | exports: [ 20 | RouterModule 21 | ] 22 | }) 23 | export class DemoRouterModule { 24 | } 25 | -------------------------------------------------------------------------------- /src/app/pages/demo/demo.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { DemoComponent } from './demo.component'; 4 | import {DemoRouterModule} from './demo.routing.module'; 5 | import {ReactiveFormsModule} from '@angular/forms'; 6 | import {SharedModule} from '../../shared/shared.module'; 7 | import {AngularSignaturePadModule} from 'angular-signature-pad'; 8 | 9 | @NgModule({ 10 | imports: [ 11 | CommonModule, 12 | DemoRouterModule, 13 | AngularSignaturePadModule.forRoot(), 14 | ReactiveFormsModule, 15 | SharedModule 16 | ], 17 | declarations: [DemoComponent] 18 | }) 19 | export class DemoModule { } 20 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | Angular Signature Pad -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {BrowserModule} from '@angular/platform-browser'; 3 | 4 | import {AppComponent} from './app.component'; 5 | import {AppRouterModule} from './app.routing.module'; 6 | import {CoreModule} from './core/core.module'; 7 | import {SharedModule} from './shared/shared.module'; 8 | import {DemoModule} from './pages/demo/demo.module'; 9 | 10 | @NgModule({ 11 | declarations: [ 12 | AppComponent 13 | ], 14 | imports: [ 15 | BrowserModule, 16 | AppRouterModule, 17 | SharedModule, 18 | CoreModule.forRoot(), 19 | DemoModule 20 | ], 21 | providers: [], 22 | bootstrap: [AppComponent] 23 | }) 24 | export class AppModule { } 25 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/src/validators/min-lines.validation.ts: -------------------------------------------------------------------------------- 1 | import {AbstractControl, ValidationErrors, ValidatorFn} from '@angular/forms'; 2 | 3 | export function minLines(minLineCount: number): ValidatorFn { 4 | 5 | return (c: AbstractControl): null | ValidationErrors => { 6 | 7 | if (c.value) { 8 | const lineCount = c.value.length; 9 | 10 | if (lineCount < minLineCount) { 11 | return { 12 | minLines: { 13 | lineCount: lineCount, 14 | minLineCount: minLineCount, 15 | message: `Signature must have a minimum line count of ${minLineCount}.` 16 | } 17 | }; 18 | } 19 | return null; 20 | } 21 | return null; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # development files 4 | /coverage 5 | /example-dist 6 | 7 | # compiled output 8 | /dist 9 | /tmp 10 | /out-tsc 11 | 12 | # dependencies 13 | /node_modules 14 | 15 | # IDEs and editors 16 | /.idea 17 | .project 18 | .classpath 19 | .c9/ 20 | *.launch 21 | .settings/ 22 | *.sublime-workspace 23 | 24 | # IDE - VSCode 25 | .vscode/* 26 | !.vscode/settings.json 27 | !.vscode/tasks.json 28 | !.vscode/launch.json 29 | !.vscode/extensions.json 30 | 31 | # misc 32 | /.sass-cache 33 | /connect.lock 34 | /coverage 35 | /libpeerconnection.log 36 | npm-debug.log 37 | testem.log 38 | /typings 39 | 40 | # e2e 41 | /e2e/*.js 42 | /e2e/*.map 43 | 44 | # System Files 45 | .DS_Store 46 | Thumbs.db 47 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad/signature-pad.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { SignaturePadRoutingModule } from './signature-pad-routing.module'; 5 | import { SignaturePadComponent } from './signature-pad.component'; 6 | import {SharedModule} from '../../shared/shared.module'; 7 | import {ReactiveFormsModule} from '@angular/forms'; 8 | import {AngularSignaturePadModule} from 'angular-signature-pad'; 9 | 10 | @NgModule({ 11 | imports: [ 12 | CommonModule, 13 | SignaturePadRoutingModule, 14 | AngularSignaturePadModule.forRoot(), 15 | ReactiveFormsModule, 16 | SharedModule 17 | ], 18 | declarations: [SignaturePadComponent] 19 | }) 20 | export class SignaturePadModule { } 21 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-signature-pad", 3 | "version": "0.0.14", 4 | "license": "MIT", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/BioPhoton/angular-signature-pad" 8 | }, 9 | "author": { 10 | "name": "Michael Hladky", 11 | "email": "michael@hladky.at" 12 | }, 13 | "keywords": [ 14 | "angular", 15 | "signature pad", 16 | "canvas", 17 | "signature" 18 | ], 19 | "bugs": { 20 | "url": "https://github.com/BioPhoton/angular-signature-pad/issues" 21 | }, 22 | "peerDependencies": { 23 | "@angular/core": "^4.2.4", 24 | "@angular/forms": "^4.2.4", 25 | "rxjs": "^5.4.2", 26 | "zone.js": "^0.8.14", 27 | "signature_pad": "^2.3.2" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/app/pages/demo/demo.component.html: -------------------------------------------------------------------------------- 1 |

2 | Basic Implementation of the angular signature pad library 3 |

4 | 5 |
6 | 7 |
8 | 9 | 13 |
14 | 15 |
16 | 17 | 21 |
22 | 23 | 24 |
25 | -------------------------------------------------------------------------------- /chore/scripts/tasks/ci-check.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const path = require('path') 4 | const util = require('util') 5 | const exec = util.promisify(require('child_process').exec) 6 | 7 | const config = require(path.join('..', '..', 'config')) 8 | 9 | module.exports = ciCheck 10 | 11 | // checks the status of the last build of the current repository 12 | // --no-interactive disables the interactive mode 13 | // source: https://github.com/travis-ci/travis.rb/blob/master/README.md 14 | function ciCheck() { 15 | return exec('travis status --no-interactive', {cwd: path.join(config.libPath, 'dist')}) 16 | .then((result) => { 17 | if (result.stdout === config.ci.validState) { 18 | return Promise.resolve(result) 19 | } else { 20 | return Promise.reject(result) 21 | } 22 | }) 23 | } 24 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad-card/signature-pad-card.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { SignaturePadCardRoutingModule } from './signature-pad-card-routing.module'; 5 | import { SignaturePadCardComponent } from './signature-pad-card.component'; 6 | import {AngularSignaturePadModule} from 'angular-signature-pad'; 7 | import {SharedModule} from '../../shared/shared.module'; 8 | import {ReactiveFormsModule} from '@angular/forms'; 9 | 10 | @NgModule({ 11 | imports: [ 12 | CommonModule, 13 | SignaturePadCardRoutingModule, 14 | ReactiveFormsModule, 15 | SharedModule, 16 | AngularSignaturePadModule.forRoot() 17 | ], 18 | declarations: [SignaturePadCardComponent] 19 | }) 20 | export class SignaturePadCardModule { } 21 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad-control/signature-pad-control.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { SignaturePadControlRoutingModule } from './signature-pad-control-routing.module'; 5 | import { SignaturePadControlComponent } from './signature-pad-control.component'; 6 | import {SharedModule} from '../../shared/shared.module'; 7 | import {ReactiveFormsModule} from '@angular/forms'; 8 | import {AngularSignaturePadModule} from 'angular-signature-pad'; 9 | 10 | @NgModule({ 11 | imports: [ 12 | CommonModule, 13 | SignaturePadControlRoutingModule, 14 | ReactiveFormsModule, 15 | SharedModule, 16 | AngularSignaturePadModule.forRoot() 17 | ], 18 | declarations: [SignaturePadControlComponent] 19 | }) 20 | export class SignaturePadControlModule { } 21 | -------------------------------------------------------------------------------- /protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | './e2e/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome' 13 | }, 14 | directConnect: true, 15 | baseUrl: 'http://localhost:4200/', 16 | framework: 'jasmine', 17 | jasmineNodeOpts: { 18 | showColors: true, 19 | defaultTimeoutInterval: 30000, 20 | print: function() {} 21 | }, 22 | onPrepare() { 23 | require('ts-node').register({ 24 | project: 'e2e/tsconfig.e2e.json' 25 | }); 26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad-card-group/signature-pad-card-group.module.ts: -------------------------------------------------------------------------------- 1 | import {CommonModule} from '@angular/common'; 2 | import {NgModule} from '@angular/core'; 3 | import {ReactiveFormsModule} from '@angular/forms'; 4 | import {SharedModule} from '../../shared/shared.module'; 5 | 6 | import {SignaturePadCardGroupRoutingModule} from './signature-pad-card-group-routing.module'; 7 | import {SignaturePadCardGroupComponent} from './signature-pad-card-group.component'; 8 | import {AngularSignaturePadModule} from 'angular-signature-pad'; 9 | 10 | @NgModule({ 11 | imports: [ 12 | CommonModule, 13 | SignaturePadCardGroupRoutingModule, 14 | ReactiveFormsModule, 15 | SharedModule, 16 | AngularSignaturePadModule.forRoot() 17 | ], 18 | declarations: [SignaturePadCardGroupComponent] 19 | }) 20 | export class SignaturePadCardGroupModule { } 21 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/src/components/signature-pad/signature-pad.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { SignaturePadComponent } from './signature-pad.component'; 4 | 5 | describe('SignaturePadComponent', () => { 6 | let component: SignaturePadComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ SignaturePadComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(SignaturePadComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad-card-group/signature-pad-card-group.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {FormBuilder, FormControl, FormGroup} from '@angular/forms'; 3 | import {minLines, minPointsInEachNLines} from 'angular-signature-pad'; 4 | 5 | @Component({ 6 | selector: 'app-signature-pad-card-group', 7 | templateUrl: './signature-pad-card-group.component.html' 8 | }) 9 | export class SignaturePadCardGroupComponent implements OnInit { 10 | 11 | testForm: FormGroup; 12 | signatureControl: FormControl; 13 | 14 | constructor(fb: FormBuilder) { 15 | this.testForm = fb.group({ 16 | signature: ['', [ 17 | minLines(1), 18 | minPointsInEachNLines(4, 1) 19 | ]] 20 | }); 21 | this.signatureControl = this.testForm.get('signature') as FormControl; 22 | } 23 | 24 | ngOnInit() { 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /chore/scripts/tasks/release-npm.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const path = require('path') 4 | const util = require('util') 5 | const exec = util.promisify(require('child_process').exec) 6 | 7 | const config = require(path.join('..','..', 'config')) 8 | const utils = require(path.join('..', 'utils')) 9 | 10 | module.exports = releaseNpm 11 | 12 | function releaseNpm () { 13 | 14 | // release on git and npm 15 | 16 | // Make a new GitHub release from git metadata based on your commit-convention. In this case angular convention 17 | // source: https://github.com/conventional-changelog/conventional-github-releaser/blob/master/README.md 18 | console.info('start npm release'.gray) 19 | return utils.getPreset() 20 | .then((preset) => { 21 | return exec('npm publish', {cwd: path.join(config.libPath, 'dist')}) 22 | .then(() => { 23 | console.info('published on npm'.green) 24 | }) 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad-control/signature-pad-control.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {FormBuilder, FormGroup} from '@angular/forms'; 3 | 4 | @Component({ 5 | selector: 'app-signature-pad-control', 6 | templateUrl: './signature-pad-control.component.html' 7 | }) 8 | export class SignaturePadControlComponent implements OnInit { 9 | 10 | testForm: FormGroup; 11 | 12 | initialSignature = () => [ 13 | [ 14 | { 15 | x: 11.328125, 16 | y: 30, 17 | time: 1506167092932, 18 | color: 'red' 19 | } 20 | ] 21 | ] 22 | 23 | constructor(private fb: FormBuilder) { 24 | this.testForm = this.fb.group({ 25 | signature: [this.initialSignature()] 26 | }); 27 | } 28 | 29 | fill() { 30 | this.testForm.get('signature').setValue(this.initialSignature()); 31 | } 32 | 33 | ngOnInit() { 34 | 35 | } 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad-control-validation/signature-pad-control-validation.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { SignaturePadControlValidationRoutingModule } from './signature-pad-control-validation-routing.module'; 5 | import { SignaturePadControlValidationComponent } from './signature-pad-control-validation.component'; 6 | import {SharedModule} from '../../shared/shared.module'; 7 | import {ReactiveFormsModule} from '@angular/forms'; 8 | import {AngularSignaturePadModule} from 'angular-signature-pad'; 9 | 10 | @NgModule({ 11 | imports: [ 12 | CommonModule, 13 | SignaturePadControlValidationRoutingModule, 14 | ReactiveFormsModule, 15 | SharedModule, 16 | AngularSignaturePadModule.forRoot(), 17 | ], 18 | declarations: [SignaturePadControlValidationComponent] 19 | }) 20 | export class SignaturePadControlValidationModule { } 21 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad-control/signature-pad-control.component.html: -------------------------------------------------------------------------------- 1 |

2 | SignaturePad Control 3 |

4 | 5 |
6 |
7 |
8 | 9 | 11 | 12 |
13 | 14 | 15 | 18 | 19 | 20 |
21 |
22 |
23 | 24 | 25 | SignaturePad Control State 26 | 27 | 28 |
29 |
30 |
31 | Component value: 32 |
{{sigPad.value | json}}
33 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad-card/signature-pad-card.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {FormBuilder, FormControl, FormGroup} from '@angular/forms'; 3 | import {isArray, consistOfArrays, consistOfObjects, minLines, minPointsInEachNLines} from 'angular-signature-pad'; 4 | 5 | @Component({ 6 | selector: 'app-signature-pad-card', 7 | templateUrl: './signature-pad-card.component.html' 8 | }) 9 | export class SignaturePadCardComponent implements OnInit { 10 | 11 | testForm: FormGroup; 12 | signatureControl: FormControl; 13 | 14 | constructor(fb: FormBuilder) { 15 | this.testForm = fb.group({ 16 | signature: ['', [ 17 | isArray, 18 | consistOfArrays, 19 | consistOfObjects, 20 | minLines(1), 21 | minPointsInEachNLines(4, 1) 22 | ]] 23 | }); 24 | this.signatureControl = this.testForm.get('signature') as FormControl; 25 | } 26 | 27 | ngOnInit() { 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /chore/scripts/tasks/refresh.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const path = require('path') 4 | const util = require('util') 5 | const exec = util.promisify(require('child_process').exec) 6 | 7 | const config = require(path.join('..', '..', 'config')) 8 | const utils = require(path.join(__base, 'chore', 'scripts', 'utils')) 9 | 10 | module.exports = refresh 11 | 12 | function refresh () { 13 | // utils.deleteFile(path.join(__base, 'node_modules')) 14 | return Promise.resolve() 15 | // pulls the latest version and rebases 16 | .then(() => { 17 | console.info('start git pull --rebase'.gray) 18 | return exec('git pull --rebase', {cwd: __base}) 19 | }) 20 | // installs the node dependencies 21 | .then(() => { 22 | console.info('done git pull --rebase'.green) 23 | console.info('start npm install'.gray) 24 | return exec('npm install', {cwd: __base}) 25 | }) 26 | .then(() => { 27 | console.info('end npm install'.green) 28 | }) 29 | } 30 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/src/validators/consists-of-arrays.validation.ts: -------------------------------------------------------------------------------- 1 | import {AbstractControl} from '@angular/forms'; 2 | 3 | export function consistOfArrays(c: AbstractControl) { 4 | 5 | if (c.value) { 6 | const arrayConstructor = [].constructor; 7 | 8 | const error = { 9 | consistOfArrays: { 10 | numOfItemsThatAreNoArray: 0, 11 | message: 'Signature don\'t consist of arrays' 12 | } 13 | }; 14 | 15 | if (c.value.constructor !== arrayConstructor) { 16 | return null; 17 | } 18 | 19 | const countOfNonArrays = 20 | c.value.filter(function (i) { 21 | // filter non arrays 22 | return i.constructor !== arrayConstructor; 23 | }).length; 24 | 25 | // return error if a non array is contained 26 | if (countOfNonArrays > 0) { 27 | error.consistOfArrays.numOfItemsThatAreNoArray = countOfNonArrays; 28 | return error; 29 | } 30 | return null; 31 | } 32 | return null; 33 | } 34 | -------------------------------------------------------------------------------- /chore/scripts/release.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const path = require('path') 4 | 5 | const config = require('../config') 6 | const base = path.join(__base, 'chore', 'scripts', 'tasks') 7 | 8 | const ciCheck = require(path.join(base, 'ci-check')) 9 | const refresh = require(path.join(base, 'refresh')) 10 | const build = require(path.join(base, 'build')) 11 | const changelog = require(path.join(base, 'changelog')) 12 | const versionBump = require(path.join(base, 'version-bump')) 13 | const releaseGithub = require(path.join(base, 'release-github')) 14 | const releaseNpm = require(path.join(base, 'release-npm')) 15 | /**/ 16 | process.env.DEBUG = config.debugMode 17 | 18 | console.info('Start release'.gray) 19 | return Promise.resolve() 20 | //.then(() => ciCheck()) 21 | .then(() => refresh()) 22 | .then(() => build()) 23 | .then(() => changelog()) 24 | .then(() => versionBump()) 25 | .then(() => releaseGithub()) 26 | //.then(() => releaseNpm()) 27 | .catch((err) => console.info('release error'.red, err.red)) 28 | -------------------------------------------------------------------------------- /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/cli'], 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/cli/plugins/karma') 14 | ], 15 | client:{ 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | reports: [ 'html', 'lcovonly' ], 20 | fixWebpackSourcePaths: true 21 | }, 22 | angularCli: { 23 | environment: 'dev' 24 | }, 25 | reporters: ['progress', 'kjhtml'], 26 | port: 9876, 27 | colors: true, 28 | logLevel: config.LOG_INFO, 29 | autoWatch: true, 30 | browsers: ['Chrome'], 31 | singleRun: false 32 | }); 33 | }; 34 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad-configuration/signature-pad-configuration.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { SignaturePadConfigurationRoutingModule } from './signature-pad-configuration-routing.module'; 5 | import { SignaturePadConfigurationComponent } from './signature-pad-configuration.component'; 6 | import {SharedModule} from '../../shared/shared.module'; 7 | import {ReactiveFormsModule} from '@angular/forms'; 8 | import {AngularSignaturePadModule} from 'angular-signature-pad'; 9 | import {GlobalSignaturePadConfig} from 'angular-signature-pad'; 10 | 11 | @NgModule({ 12 | imports: [ 13 | CommonModule, 14 | SignaturePadConfigurationRoutingModule, 15 | ReactiveFormsModule, 16 | SharedModule, 17 | AngularSignaturePadModule.forRoot(), 18 | ], 19 | declarations: [SignaturePadConfigurationComponent], 20 | providers: [ 21 | { provide: GlobalSignaturePadConfig, useValue: { penColor: '#f00'}} 22 | ] 23 | }) 24 | export class SignaturePadConfigurationModule { } 25 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/src/components/signature-pad-card-group/signature-pad-card-group.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input, OnInit, ViewChild} from '@angular/core'; 2 | import {AbstractControl, FormControl} from '@angular/forms'; 3 | import {SignaturePadControlComponent} from '../signature-pad-control/signature-pad-control.component'; 4 | 5 | @Component({ 6 | selector: 'signature-pad-card-group', 7 | templateUrl: './signature-pad-card-group.component.html', 8 | providers: [] 9 | }) 10 | export class SignaturePadCardGroupComponent implements OnInit { 11 | 12 | @Input() 13 | theme: string; 14 | 15 | @Input() 16 | group: AbstractControl; 17 | 18 | @Input() 19 | config: any; 20 | 21 | control: FormControl; 22 | 23 | @ViewChild('signaturePad') 24 | signaturePadControl: SignaturePadControlComponent; 25 | 26 | constructor() { 27 | 28 | } 29 | 30 | ngOnInit() { 31 | this.control = this.group.get(this.config.name) as FormControl; 32 | } 33 | 34 | clear() { 35 | this.signaturePadControl.clear(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/src/components/signature-pad-card-group/signature-pad-card-group.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | 6 |
7 |
8 |
9 | 12 |
13 | 14 | 30 |
31 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/src/components/signature-pad-card/signature-pad-card.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 10 | 11 |
12 |
13 |
14 | 17 |
18 | 19 | 35 |
36 | -------------------------------------------------------------------------------- /chore/scripts/tasks/release-github.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const path = require('path') 4 | const util = require('util') 5 | const exec = util.promisify(require('child_process').exec) 6 | 7 | const utils = require(path.join('..', 'utils')) 8 | 9 | module.exports = releaseGithub 10 | 11 | function releaseGithub () { 12 | // release on git and npm 13 | 14 | // Make a new GitHub release from git metadata based on your commit-convention. In this case angular convention 15 | // source: https://github.com/conventional-changelog/conventional-github-releaser/blob/master/README.md 16 | console.info('start github release'.gray) 17 | return utils.getPreset() 18 | .then((preset) => { 19 | return new Promise((resolve, reject) => { 20 | exec('conventional-github-releaser -p ' + preset, (err, responses) => { 21 | if(err !== undefined) { 22 | console.log('error in github release'.red, err); 23 | reject(err) 24 | } else { 25 | console.log('released on github'.green); 26 | resolve(responses) 27 | } 28 | }) 29 | }) 30 | }) 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Michael Hladky 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 | -------------------------------------------------------------------------------- /src/app/shared/components/control-state/control-state.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Component, 3 | Input, 4 | OnChanges, 5 | OnInit, 6 | SimpleChanges 7 | } from '@angular/core'; 8 | 9 | @Component({ 10 | selector: 'control-state', 11 | templateUrl: './control-state.component.html', 12 | styles: [` 13 | ul { 14 | list-style: none; 15 | margin-bottom: 0; 16 | } 17 | 18 | .control-value { 19 | max-height: 200px; 20 | overflow-y: scroll; 21 | } 22 | `] 23 | }) 24 | export class ControlStateComponent implements OnChanges, OnInit { 25 | 26 | @Input() 27 | control; 28 | 29 | @Input() 30 | errorColor = 'danger'; 31 | 32 | ngOnChanges(changes: SimpleChanges): void { 33 | 34 | console.log(changes); 35 | 36 | if ('errorColor' in changes) { 37 | this.errorColor = changes.errorColor.currentValue || 'danger' 38 | } 39 | } 40 | 41 | ngOnInit() { 42 | 43 | } 44 | 45 | getErrors(): any[] { 46 | return Object.keys(this.control.errors) 47 | .map((key) => { 48 | return { 49 | name: key, 50 | value: this.control.errors[key] 51 | } 52 | }) 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/src/validators/min-points-in-each-n-lines.validator.ts: -------------------------------------------------------------------------------- 1 | import {AbstractControl, ValidationErrors, ValidatorFn} from '@angular/forms'; 2 | 3 | export function minPointsInEachNLines(minPointCount: number, minLineCount: number): ValidatorFn { 4 | 5 | return (c: AbstractControl): null | ValidationErrors => { 6 | 7 | if (c.value) { 8 | const arrayConstructor = [].constructor; 9 | if (c.value.constructor !== arrayConstructor) { 10 | return null; 11 | } 12 | const lineCountWithValidPointCount = c.value.filter((i) => { 13 | if (i.constructor !== arrayConstructor) { 14 | return true; 15 | } 16 | return i.length >= minPointCount; 17 | }).length; 18 | 19 | if (lineCountWithValidPointCount < minLineCount) { 20 | return { 21 | minPointsInNLines: { 22 | pointCount: lineCountWithValidPointCount, 23 | minPointCount: minPointCount, 24 | message: `Signature must have at least ${minPointCount} points in at least ${minLineCount} lines.` 25 | } 26 | }; 27 | } 28 | return null; 29 | } 30 | return null; 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad-configuration/signature-pad-configuration.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {FormBuilder, FormGroup} from '@angular/forms'; 3 | import 'rxjs/Rx'; 4 | 5 | @Component({ 6 | selector: 'app-signature-pad-configuration', 7 | templateUrl: './signature-pad-configuration.component.html' 8 | }) 9 | export class SignaturePadConfigurationComponent { 10 | 11 | configForm: FormGroup; 12 | valueChanges; 13 | 14 | initialConfig = { 15 | dotSize: 1.5, 16 | minWidth: 1, 17 | maxWidth: 3, 18 | throttle: 16, 19 | backgroundColor: '#ffff80', 20 | penColor: '#000', 21 | velocityFilterWeight: 0.7 22 | }; 23 | 24 | constructor(private fb: FormBuilder) { 25 | this.configForm = this.fb.group({ 26 | dotSize: [], 27 | minWidth: [], 28 | maxWidth: [], 29 | throttle: [], 30 | backgroundColor: [], 31 | penColor: [], 32 | velocityFilterWeight: [] 33 | }); 34 | 35 | this.configForm.reset(this.initialConfig); 36 | // ugly hack to init subscription with values 37 | this.valueChanges = this.configForm.valueChanges.startWith(this.configForm.value); 38 | } 39 | 40 | reset() { 41 | this.configForm.reset(this.initialConfig); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/src/validators/constists-of-object.validation.ts: -------------------------------------------------------------------------------- 1 | import {AbstractControl, ValidationErrors} from '@angular/forms'; 2 | 3 | export function consistOfObjects(c: AbstractControl): null | ValidationErrors { 4 | if (c.value) { 5 | const objectConstructor = {}.constructor; 6 | const arrayConstructor = [].constructor; 7 | 8 | const error = { 9 | consistOfObjects: { 10 | numOfItemsThatAreNoObject: 0, 11 | message: 'Signature segments don\'t contain of objects' 12 | } 13 | }; 14 | 15 | if (c.value.constructor !== arrayConstructor) { 16 | return null; 17 | } 18 | 19 | const countOfNonObjects = 20 | c.value.reduce((nonObjCount, line) => { 21 | if (line.constructor !== arrayConstructor) { 22 | return false; 23 | } 24 | nonObjCount += line.filter((i) => { 25 | // filter non objects 26 | return i.constructor !== objectConstructor; 27 | }).length; 28 | }, 0); 29 | 30 | // return error if a non object is contained 31 | if (countOfNonObjects > 0) { 32 | error.consistOfObjects.numOfItemsThatAreNoObject = countOfNonObjects; 33 | return error; 34 | } 35 | return null; 36 | } 37 | return null; 38 | } 39 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/src/interfaces/signature-pad-config.interface.ts: -------------------------------------------------------------------------------- 1 | export interface ISignaturePadConfig { 2 | // (float or function) Radius of a single dot. 3 | dotSize?: number | Function; 4 | // (float) Minimum width of a line. Defaults to 0.5. 5 | minWidth?: number; 6 | // (float) Maximum width of a line. Defaults to 2.5. 7 | maxWidth?: number; 8 | // (integer) Draw the next point at most once per every x milliseconds. Set it to 0 to turn off throttling. Defaults to 16. 9 | throttle?: number; 10 | // (string) Color used to clear the background. 11 | // Can be any color format accepted by context.fillStyle. 12 | // Defaults to "rgba(0,0,0,0)" (transparent black). 13 | // Use a non-transparent color e.g. "rgb(255,255,255)" (opaque white) if you'd like to save signatures as JPEG images. 14 | backgroundColor?: string; 15 | // (string) Color used to draw the lines. Can be any color format accepted by context.fillStyle. Defaults to "black". 16 | penColor?: string; 17 | // (float) Weight used to modify new velocity based on the previous velocity. Defaults to 0.7. 18 | velocityFilterWeight?: number; 19 | // (function) Callback when stroke begin. 20 | onBegin?: (value: any) => {}; 21 | // (function) Callback when stroke end. 22 | onEnd?: (value: any) => {}; 23 | } 24 | -------------------------------------------------------------------------------- /.angular-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "project": { 4 | "name": "angular-signature-pad" 5 | }, 6 | "apps": [ 7 | { 8 | "root": "src", 9 | "outDir": "example-dist", 10 | "assets": [ 11 | "assets", 12 | "favicon.ico" 13 | ], 14 | "index": "index.html", 15 | "main": "main.ts", 16 | "polyfills": "polyfills.ts", 17 | "test": "test.ts", 18 | "tsconfig": "tsconfig.app.json", 19 | "testTsconfig": "tsconfig.spec.json", 20 | "prefix": "app", 21 | "styles": [ 22 | "styles.scss" 23 | ], 24 | "scripts": [], 25 | "environmentSource": "environments/environment.ts", 26 | "environments": { 27 | "dev": "environments/environment.ts", 28 | "prod": "environments/environment.prod.ts" 29 | } 30 | } 31 | ], 32 | "e2e": { 33 | "protractor": { 34 | "config": "./protractor.conf.js" 35 | } 36 | }, 37 | "lint": [ 38 | { 39 | "project": "src/tsconfig.app.json" 40 | }, 41 | { 42 | "project": "src/tsconfig.spec.json" 43 | }, 44 | { 45 | "project": "e2e/tsconfig.e2e.json" 46 | } 47 | ], 48 | "test": { 49 | "karma": { 50 | "config": "./karma.conf.js" 51 | } 52 | }, 53 | "defaults": { 54 | "styleExt": "scss", 55 | "component": {} 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /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/long-stack-trace-zone'; 4 | import 'zone.js/dist/proxy.js'; 5 | import 'zone.js/dist/sync-test'; 6 | import 'zone.js/dist/jasmine-patch'; 7 | import 'zone.js/dist/async-test'; 8 | import 'zone.js/dist/fake-async-test'; 9 | import { getTestBed } from '@angular/core/testing'; 10 | import { 11 | BrowserDynamicTestingModule, 12 | platformBrowserDynamicTesting 13 | } from '@angular/platform-browser-dynamic/testing'; 14 | 15 | // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any. 16 | declare const __karma__: any; 17 | declare const require: any; 18 | 19 | // Prevent Karma from running prematurely. 20 | __karma__.loaded = function () {}; 21 | 22 | // First, initialize the Angular testing environment. 23 | getTestBed().initTestEnvironment( 24 | BrowserDynamicTestingModule, 25 | platformBrowserDynamicTesting() 26 | ); 27 | // Then we find all the tests. 28 | const context = require.context('./', true, /\.spec\.ts$/); 29 | // And load the modules. 30 | context.keys().map(context); 31 | /* 32 | // Then we find all the lib tests. 33 | const libContext = require.context('../libs/angular-signature-pad/src/components/signature-pad/', true, /\.spec\.ts$/); 34 | // And load the lib modules. 35 | libContext.keys().map(libContext); 36 | console.log(context.keys(), libContext.keys()); 37 | */ 38 | 39 | // Finally, start Karma to run the tests. 40 | __karma__.start(); 41 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/src/components/signature-pad-card/signature-pad-card.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AfterViewInit, 3 | Component, 4 | forwardRef, 5 | Host, 6 | Inject, 7 | Input, 8 | OnChanges, 9 | OnInit, 10 | Optional, 11 | Renderer2, 12 | SkipSelf 13 | } from '@angular/core'; 14 | import {ControlContainer, FormControl, NG_VALUE_ACCESSOR} from '@angular/forms'; 15 | import {ISignaturePadConfig} from '../../interfaces/signature-pad-config.interface'; 16 | import {GlobalSignaturePadConfig} from '../../tokens/global-config.token'; 17 | import {SignaturePadControlComponent} from '../signature-pad-control/signature-pad-control.component'; 18 | 19 | @Component({ 20 | selector: 'signature-pad-card', 21 | templateUrl: './signature-pad-card.component.html', 22 | providers: [ 23 | { 24 | provide: NG_VALUE_ACCESSOR, 25 | useExisting: forwardRef(() => SignaturePadCardComponent), 26 | multi: true 27 | } 28 | ] 29 | }) 30 | export class SignaturePadCardComponent extends SignaturePadControlComponent implements OnChanges, OnInit, AfterViewInit { 31 | 32 | @Input() 33 | theme: string = 'raised'; 34 | 35 | @Input() 36 | formControlName: string; 37 | 38 | control: FormControl; 39 | 40 | constructor( 41 | renderer: Renderer2, 42 | @Optional() @Host() @SkipSelf() parentFormContainer: ControlContainer, 43 | @Optional() @Inject(GlobalSignaturePadConfig) defaultConfig?: ISignaturePadConfig 44 | ) { 45 | super(renderer, parentFormContainer, defaultConfig); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /docs/inline.f7fd537c847050bbfb16.bundle.js: -------------------------------------------------------------------------------- 1 | !function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,a,c){for(var f,u,i,d=0,l=[];d { 21 | return packaging() 22 | }) 23 | .then((r) => { 24 | return copyStyles() 25 | }) 26 | .catch((e) => { 27 | console.error('BuildProcessError: '.red, e) 28 | }) 29 | } 30 | 31 | // build scripts 32 | // ============================================================================= 33 | 34 | async function packaging () { 35 | await ngPackagr.ngPackage({project: path.join(config.libPath, 'ng-package.json')}) 36 | .then((res) => { 37 | console.info('done packaging'.green) 38 | }) 39 | .catch((err) => { 40 | console.error('Build failed: '.red, err) 41 | process.exit(1) 42 | }) 43 | const {stdout, stderr} = await exec('npm pack', {cwd: path.join(config.libPath, 'dist')}) 44 | console.info('done npm pack'.green) 45 | return {stdout, stderr} 46 | } 47 | 48 | function copyStyles () { 49 | const source = path.join(config.libPath, 'src', 'styles.scss') 50 | const target = path.join(config.libPath, 'dist', 'styles.scss') 51 | return utils.copyFile(source, target, (r) => console.log('copy styles done')) 52 | } 53 | -------------------------------------------------------------------------------- /src/app/app.routing.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {ExtraOptions, RouterModule, Routes} from '@angular/router'; 3 | import {DemoComponent} from './pages/demo/demo.component'; 4 | 5 | const APP_ROUTES: Routes = [ 6 | { 7 | path: '', 8 | pathMatch: 'full', 9 | redirectTo: 'demo' 10 | }, 11 | { 12 | path: 'demo', 13 | component: DemoComponent, 14 | }, 15 | { 16 | path: 'signature-pad', 17 | loadChildren: 'app/pages/signature-pad/signature-pad.module#SignaturePadModule' 18 | }, 19 | { 20 | path: 'signature-pad-control', 21 | loadChildren: 'app/pages/signature-pad-control/signature-pad-control.module#SignaturePadControlModule' 22 | }, 23 | { 24 | path: 'signature-pad-configuration', 25 | loadChildren: 'app/pages/signature-pad-configuration/signature-pad-configuration.module#SignaturePadConfigurationModule' 26 | }, 27 | { 28 | path: 'signature-pad-control-validation', 29 | loadChildren: 'app/pages/signature-pad-control-validation/signature-pad-control-validation.module#SignaturePadControlValidationModule' 30 | }, 31 | { 32 | path: 'signature-pad-card', 33 | loadChildren: 'app/pages/signature-pad-card/signature-pad-card.module#SignaturePadCardModule' 34 | }, 35 | { 36 | path: 'signature-pad-card-group', 37 | loadChildren: 'app/pages/signature-pad-card-group/signature-pad-card-group.module#SignaturePadCardGroupModule' 38 | } 39 | ]; 40 | 41 | const extraOptions: ExtraOptions = { 42 | useHash: true 43 | }; 44 | 45 | @NgModule({ 46 | imports: [ 47 | RouterModule.forRoot(APP_ROUTES, extraOptions) 48 | ], 49 | exports: [ 50 | RouterModule 51 | ] 52 | }) 53 | export class AppRouterModule { 54 | } 55 | -------------------------------------------------------------------------------- /chore/scripts/tasks/version-bump.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const util = require('util') 4 | const path = require('path') 5 | const exec = util.promisify(require('child_process').exec) 6 | 7 | const utils = require(path.join('..', 'utils')) 8 | const config = require(path.join('..', '..', 'config')) 9 | 10 | // create version bump 11 | let detectedBump 12 | let detectedVersion 13 | 14 | module.exports = versionBump 15 | 16 | function versionBump () { 17 | console.info('start versionBump'.gray) 18 | return utils.getBump() 19 | .then((bump) => { 20 | detectedBump = bump 21 | console.info('detected bump type: '+detectedBump.gray) 22 | return Promise.resolve() 23 | }) 24 | // npm version [detectedBump] bumps the version specified in detectedBump 25 | // and write the new data back to package.json 26 | .then(() => exec('npm --no-git-tag-version version ' + detectedBump, {cwd: config.libPath})) 27 | .then(() => exec('git add .\\package.json', {cwd: config.libPath})) 28 | .then(() => utils.getPackageVersion()) 29 | .then((version) => { 30 | detectedVersion = version 31 | console.info('detected version: '+detectedVersion.green) 32 | return Promise.resolve() 33 | }) 34 | .then(() => exec('git commit -m "chore(release): ' + detectedVersion + ' (' + detectedBump + ')"', {cwd: __base})) 35 | .then(() => exec('git tag ' + detectedVersion) , {cwd: __base}) 36 | // push the commit 37 | // --follow-tags also pushes the new tags 38 | // source: https://git-scm.com/docs/git-push 39 | .then(() => { 40 | console.info('start git push --follow-tags'.gray) 41 | return exec('git push --follow-tags',{cwd: __base}) 42 | .then(() => { 43 | console.info('pushed repo and created tag'.green) 44 | }) 45 | }) 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/src/angular-signature-pad.module.ts: -------------------------------------------------------------------------------- 1 | import {CommonModule} from '@angular/common'; 2 | import {ModuleWithProviders, NgModule} from '@angular/core'; 3 | import {ReactiveFormsModule} from '@angular/forms'; 4 | import {SignaturePadCardGroupComponent} from './components/signature-pad-card-group/signature-pad-card-group.component'; 5 | import {SignaturePadCardComponent} from './components/signature-pad-card/signature-pad-card.component'; 6 | import {SignaturePadControlComponent} from './components/signature-pad-control/signature-pad-control.component'; 7 | import {SignaturePadComponent} from './components/signature-pad/signature-pad.component'; 8 | import {ObjToArrayPipe} from './pipes/obj-to-array.pipe'; 9 | import {GlobalSignaturePadConfig} from './tokens/global-config.token'; 10 | 11 | export {GlobalSignaturePadConfig} from './tokens/global-config.token'; 12 | 13 | export {isArray} from './validators/is-array.validation'; 14 | export {consistOfArrays} from './validators/consists-of-arrays.validation'; 15 | export {consistOfObjects} from './validators/constists-of-object.validation'; 16 | export {minLines} from './validators/min-lines.validation'; 17 | export {minPointsInEachNLines} from './validators/min-points-in-each-n-lines.validator'; 18 | 19 | @NgModule({ 20 | imports: [CommonModule, ReactiveFormsModule], 21 | declarations: [SignaturePadComponent, SignaturePadControlComponent, SignaturePadCardComponent, SignaturePadCardGroupComponent, ObjToArrayPipe], 22 | exports: [SignaturePadComponent, SignaturePadControlComponent, SignaturePadCardComponent, SignaturePadCardGroupComponent] 23 | }) 24 | export class AngularSignaturePadModule { 25 | static forRoot(): ModuleWithProviders { 26 | return { 27 | providers: [ 28 | ObjToArrayPipe 29 | ], 30 | ngModule: AngularSignaturePadModule 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/src/styles.scss: -------------------------------------------------------------------------------- 1 | $signature-pad-color: rgba(0, 0, 0, 0.4); 2 | 3 | $signature-pad-border: rgba(0, 0, 0, 0.08); 4 | 5 | $signature-pad-background-light: rgba(255, 255, 255, 1); 6 | $signature-pad-background-dark: rgba(252, 252, 252, 1); 7 | 8 | $signature-pad-shadow-dark: $signature-pad-color; 9 | $signature-pad-shadow-light: $signature-pad-border; 10 | 11 | $signature-clear-button-width: 150px; 12 | $signature-clear-button-height: 60px; 13 | 14 | $signature-space: 15px; 15 | 16 | .signature-pad { 17 | width: 100%; 18 | min-height: 200px; 19 | display: block; 20 | } 21 | 22 | .signature-pad-card { 23 | display: flex; 24 | flex-direction: row; 25 | flex-flow: row wrap; 26 | 27 | .signature-pad { 28 | width: 100%; 29 | } 30 | 31 | .actions { 32 | flex: 1 1 auto; 33 | } 34 | 35 | .feedback { 36 | flex: 1 1 auto; 37 | } 38 | } 39 | 40 | .signature-pad-card.raised { 41 | border: 1px solid $signature-pad-border; 42 | background-color: $signature-pad-background-dark; 43 | box-shadow: 0 1px 4px $signature-pad-shadow-dark, 0 0 40px $signature-pad-shadow-light inset; 44 | border-radius: 4px; 45 | padding: $signature-space * 2; 46 | 47 | .signature-pad { 48 | min-height: 400px; 49 | width: 100%; 50 | margin-bottom: $signature-space; 51 | } 52 | 53 | .signature-pad-canvas { 54 | border: 2px dashed $signature-pad-border; 55 | background-color: $signature-pad-background-light; 56 | } 57 | 58 | .actions { 59 | flex: 0 1 auto; 60 | padding-right: $signature-space; 61 | 62 | .clear { 63 | height: $signature-clear-button-height; 64 | width: $signature-clear-button-width; 65 | line-height: $signature-space * 3; 66 | color: rgba(0, 0, 0, 0.6); 67 | text-shadow: 1px 1px 0px #fcfcfc; 68 | border-color: $signature-pad-shadow-dark; 69 | border-radius: 4px; 70 | border-width: 1px; 71 | box-shadow: 0px 1px 0px rgba(0, 0, 0, 0.4); 72 | } 73 | } 74 | 75 | .feedback { 76 | display:flex; 77 | align-items: center; 78 | 79 | color: rgba(0, 0, 0, 0.4); 80 | text-shadow: 1px 1px 0px #fcfcfc; 81 | font-size: 28px; 82 | text-align: right; 83 | 84 | overflow: hidden; 85 | white-space: nowrap; 86 | text-overflow: ellipsis; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 |
2 | 49 |
50 |
51 | 52 |
53 |
54 |
55 | -------------------------------------------------------------------------------- /src/app/pages/signature-pad-configuration/signature-pad-configuration.component.html: -------------------------------------------------------------------------------- 1 |

2 | SignaturePad Configuration 3 |

4 | 5 |
6 | 7 | 8 |
9 | Override default config for all components: 10 | 11 |
12 | 13 |
14 | Override config by using the config property binding: 15 | 17 |
18 | 19 |
20 | 21 | 23 |
24 |
25 | 26 | 28 |
29 |
30 | 31 | 33 |
34 |
35 | 36 | 38 |
39 |
40 | 41 | 42 |
43 |
44 | 45 | 46 |
47 |
48 | 49 | 51 |
52 | 53 | 54 | 57 |
58 | -------------------------------------------------------------------------------- /docs/1.522f1586c79936db9acc.chunk.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([1],{m3E1:function(l,n,u){"use strict";function t(l){return e._43(0,[(l()(),e._19(0,null,null,1,"h1",[],null,null,null,null,null)),(l()(),e._41(null,["\n SignaturePad\n"])),(l()(),e._41(null,["\n\n"])),(l()(),e._19(0,null,null,1,"signature-pad",[],null,[[null,"valueChange"]],function(l,n,u){var t=!0,a=l.component;if("valueChange"===n){t=!1!==a.setLastChange(u)&&t}return t},o.e,o.a)),e._17(4833280,[["sigPad",4]],0,c.h,[e.O,[2,c.b]],null,{valueChange:"valueChange"}),(l()(),e._41(null,["\n\n"])),(l()(),e._19(0,null,null,1,"b",[],null,null,null,null,null)),(l()(),e._41(null,["value:"])),(l()(),e._41(null,["\n"])),(l()(),e._19(0,null,null,2,"pre",[],null,null,null,null,null)),(l()(),e._41(null,[" ","\n"])),e._35(0,i.f,[]),(l()(),e._41(null,["\n"])),(l()(),e._19(0,null,null,1,"b",[],null,null,null,null,null)),(l()(),e._41(null,["valueChanged to:"])),(l()(),e._41(null,["\n"])),(l()(),e._19(0,null,null,2,"pre",[],null,null,null,null,null)),(l()(),e._41(null,[" ","\n"])),e._35(0,i.f,[]),(l()(),e._41(null,["\n\n"])),(l()(),e._19(0,null,null,1,"button",[["class","btn btn-outline-secondary"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==e._33(l,4).clear()&&t}return t},null,null)),(l()(),e._41(null,["Clear"])),(l()(),e._41(null,["\n"]))],function(l,n){l(n,4,0)},function(l,n){var u=n.component;l(n,10,0,e._42(n,10,0,e._33(n,11).transform(e._33(n,4).value))),l(n,17,0,e._42(n,17,0,e._33(n,18).transform(u.lastChange)))})}function a(l){return e._43(0,[(l()(),e._19(0,null,null,1,"app-signature-pad",[],null,null,null,t,f)),e._17(49152,null,0,r,[],null,null)],null,null)}Object.defineProperty(n,"__esModule",{value:!0});var e=u("/oeL"),_=function(){function l(){}return l}(),r=function(){function l(){this.lastChange=[]}return l.prototype.setLastChange=function(l){this.lastChange=l},l.ctorParameters=function(){return[]},l}(),o=u("yID4"),c=u("yprN"),i=u("qbdv"),s=[],f=e._16({encapsulation:2,styles:s,data:{}}),p=e._14("app-signature-pad",r,a,{},{},[]),g=u("bm2B"),d=u("BkNc"),h=function(){function l(){}return l}(),v=u("T2Au");u.d(n,"SignaturePadModuleNgFactory",function(){return C});var C=e._15(_,[],function(l){return e._30([e._31(512,e.l,e._11,[[8,[p]],[3,e.l],e.F]),e._31(4608,i.n,i.m,[e.B]),e._31(4608,g.d,g.d,[]),e._31(4608,g.o,g.o,[]),e._31(4608,c.l,c.l,[]),e._31(512,i.c,i.c,[]),e._31(512,d.n,d.n,[[2,d.s],[2,d.k]]),e._31(512,h,h,[]),e._31(512,g.l,g.l,[]),e._31(512,g.k,g.k,[]),e._31(512,c.a,c.a,[]),e._31(512,v.a,v.a,[]),e._31(512,_,_,[]),e._31(1024,d.i,function(){return[[{path:"",component:r}]]},[])])})}}); -------------------------------------------------------------------------------- /docs/5.94af90d1b03e5075fb46.chunk.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([5],{Jidj:function(n,l,u){"use strict";function t(n){return e._43(0,[(n()(),e._19(0,null,null,1,"h1",[],null,null,null,null,null)),(n()(),e._41(null,["\n SignaturePad Card Group\n"])),(n()(),e._41(null,["\n\n"])),(n()(),e._19(0,null,null,8,"div",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,l,u){var t=!0;if("submit"===l){t=!1!==e._33(n,4).onSubmit(u)&&t}if("reset"===l){t=!1!==e._33(n,4).onReset()&&t}return t},null,null)),e._17(540672,null,0,o.f,[[8,null],[8,null]],{form:[0,"form"]},null),e._38(2048,null,o.b,null,[o.f]),e._17(16384,null,0,o.j,[o.b],null,null),(n()(),e._41(null,["\n "])),(n()(),e._19(0,null,null,2,"signature-pad-card-group",[],null,null,null,a.h,a.d)),e._17(114688,null,0,_.k,[],{theme:[0,"theme"],group:[1,"group"],config:[2,"config"]},null),e._36({name:0}),(n()(),e._41(null,["\n"])),(n()(),e._41(null,["\n"]))],function(n,l){var u=l.component;n(l,4,0,u.testForm);n(l,9,0,"raised",u.testForm,n(l,10,0,"signature"))},function(n,l){n(l,3,0,e._33(l,6).ngClassUntouched,e._33(l,6).ngClassTouched,e._33(l,6).ngClassPristine,e._33(l,6).ngClassDirty,e._33(l,6).ngClassValid,e._33(l,6).ngClassInvalid,e._33(l,6).ngClassPending)})}function r(n){return e._43(0,[(n()(),e._19(0,null,null,1,"app-signature-pad-card-group",[],null,null,null,t,g)),e._17(114688,null,0,s,[o.d],null,null)],function(n,l){n(l,1,0)},null)}Object.defineProperty(l,"__esModule",{value:!0});var e=u("/oeL"),i=function(){function n(){}return n}(),o=u("bm2B"),a=u("yID4"),_=u("yprN"),s=function(){function n(n){this.testForm=n.group({signature:["",[Object(_.f)(1),Object(_.g)(4,1)]]}),this.signatureControl=this.testForm.get("signature")}return n.prototype.ngOnInit=function(){},n.ctorParameters=function(){return[{type:o.d}]},n}(),c=[],g=e._16({encapsulation:2,styles:c,data:{}}),d=e._14("app-signature-pad-card-group",s,r,{},{},[]),f=u("qbdv"),p=u("BkNc"),m=function(){function n(){}return n}(),h=u("T2Au");u.d(l,"SignaturePadCardGroupModuleNgFactory",function(){return b});var b=e._15(i,[],function(n){return e._30([e._31(512,e.l,e._11,[[8,[d]],[3,e.l],e.F]),e._31(4608,f.n,f.m,[e.B]),e._31(4608,o.d,o.d,[]),e._31(4608,o.o,o.o,[]),e._31(4608,_.l,_.l,[]),e._31(512,f.c,f.c,[]),e._31(512,p.n,p.n,[[2,p.s],[2,p.k]]),e._31(512,m,m,[]),e._31(512,o.l,o.l,[]),e._31(512,o.k,o.k,[]),e._31(512,h.a,h.a,[]),e._31(512,_.a,_.a,[]),e._31(512,i,i,[]),e._31(1024,p.i,function(){return[[{path:"",component:s}]]},[])])})}}); -------------------------------------------------------------------------------- /src/app/pages/signature-pad-control-validation/signature-pad-control-validation.component.html: -------------------------------------------------------------------------------- 1 |

2 | SignaturePad Control Validation 3 |

4 | 5 | 6 |
7 |
8 |
9 |
10 | 13 | 16 | 19 | 23 | 26 | 30 |
31 | 32 |
33 |
34 | 35 |
36 | 37 |
38 | 39 | Value:
40 |
{{signatureControl.value | json}}
41 |
42 |
43 | 45 | 46 | Signature is no array 48 | Signature don't consist of array 50 | Signature segments don't consist of objects 52 | Signature have wrong line coun't 54 | Signature have wrong point count in segments 56 |
57 |
58 |
59 | -------------------------------------------------------------------------------- /src/app/layout/vendors.scss: -------------------------------------------------------------------------------- 1 | // FONT-AWESOME 4.7.0 ----------------------------------------------------------------- 2 | $fa-font-path : '../node_modules/font-awesome/fonts'; 3 | 4 | @import "~font-awesome/scss/variables"; 5 | @import "~font-awesome/scss/mixins"; 6 | @import "~font-awesome/scss/path"; 7 | @import "~font-awesome/scss/core"; 8 | @import "~font-awesome/scss/larger"; 9 | @import "~font-awesome/scss/fixed-width"; 10 | @import "~font-awesome/scss/list"; 11 | @import "~font-awesome/scss/bordered-pulled"; 12 | @import "~font-awesome/scss/animated"; 13 | @import "~font-awesome/scss/rotated-flipped"; 14 | @import "~font-awesome/scss/stacked"; 15 | @import "~font-awesome/scss/icons"; 16 | @import "~font-awesome/scss/screen-reader"; 17 | 18 | // ----------------------------------------------------------------- FONT-AWESOME 4.7.0 19 | 20 | // BOOTSTRAP 4.0.0-beta ----------------------------------------------------------------- 21 | @import '~bootstrap/scss/bootstrap'; 22 | 23 | /* 24 | // Core variables and mixins 25 | @import '~bootstrap/scss/functions'; 26 | @import '~bootstrap/scss/variables'; 27 | @import '~bootstrap/scss/mixins'; 28 | @import '~bootstrap/scss/transitions'; 29 | 30 | // Print 31 | @import '~bootstrap/scss/print'; 32 | 33 | 34 | // Core CSS 35 | @import '~bootstrap/scss/reboot'; 36 | @import '~bootstrap/scss/type'; 37 | @import '~bootstrap/scss/images'; 38 | @import '~bootstrap/scss/code'; 39 | @import '~bootstrap/scss/grid'; 40 | @import '~bootstrap/scss/tables'; 41 | @import '~bootstrap/scss/forms'; 42 | @import '~bootstrap/scss/buttons'; 43 | 44 | // Components 45 | @import '~bootstrap/scss/dropdown'; 46 | @import '~bootstrap/scss/button-group'; 47 | @import '~bootstrap/scss/input-group'; 48 | @import '~bootstrap/scss/custom-forms'; 49 | @import '~bootstrap/scss/nav'; 50 | @import '~bootstrap/scss/navbar'; 51 | @import '~bootstrap/scss/card'; 52 | @import '~bootstrap/scss/breadcrumb'; 53 | @import '~bootstrap/scss/pagination'; 54 | @import '~bootstrap/scss/badge'; 55 | @import '~bootstrap/scss/jumbotron'; 56 | @import '~bootstrap/scss/alert'; 57 | @import '~bootstrap/scss/progress'; 58 | @import '~bootstrap/scss/media'; 59 | @import '~bootstrap/scss/list-group'; 60 | @import '~bootstrap/scss/close'; 61 | 62 | // Components w/ JavaScript 63 | @import '~bootstrap/scss/modal'; 64 | @import '~bootstrap/scss/tooltip'; 65 | @import '~bootstrap/scss/popover'; 66 | @import '~bootstrap/scss/carousel'; 67 | 68 | // Utility classes 69 | @import '~bootstrap/scss/utilities'; 70 | */ 71 | // ----------------------------------------------------------------- BOOTSTRAP 4.0.0-beta 72 | -------------------------------------------------------------------------------- /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/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 22 | // import 'core-js/es6/symbol'; 23 | // import 'core-js/es6/object'; 24 | // import 'core-js/es6/function'; 25 | // import 'core-js/es6/parse-int'; 26 | // import 'core-js/es6/parse-float'; 27 | // import 'core-js/es6/number'; 28 | // import 'core-js/es6/math'; 29 | // import 'core-js/es6/string'; 30 | // import 'core-js/es6/date'; 31 | // import 'core-js/es6/array'; 32 | // import 'core-js/es6/regexp'; 33 | // import 'core-js/es6/map'; 34 | // import 'core-js/es6/weak-map'; 35 | // import 'core-js/es6/set'; 36 | 37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 38 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 39 | 40 | /** Evergreen browsers require these. **/ 41 | import 'core-js/es6/reflect'; 42 | import 'core-js/es7/reflect'; 43 | 44 | 45 | /** 46 | * Required to support Web Animations `@angular/animation`. 47 | * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation 48 | **/ 49 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 50 | 51 | 52 | 53 | /*************************************************************************************************** 54 | * Zone JS is required by Angular itself. 55 | */ 56 | import 'zone.js/dist/zone'; // Included with Angular CLI. 57 | 58 | 59 | 60 | /*************************************************************************************************** 61 | * APPLICATION IMPORTS 62 | */ 63 | 64 | /** 65 | * Date, currency, decimal and percent pipes. 66 | * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10 67 | */ 68 | // import 'intl'; // Run `npm install --save intl`. 69 | /** 70 | * Need to import at least one locale-data with intl. 71 | */ 72 | // import 'intl/locale-data/jsonp/en'; 73 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Angular SignaturePad 2 | 3 | This project provides components and utils for digital signatures. 4 | Use it to draw smooth signatures based on HTML5 canvas and uses variable width Bézier curve interpolation. 5 | [SignaturePad](https://github.com/szimek/signature_pad) is used as the vanilla implementation. 6 | 7 | ![Angular-Signature-Pad](https://raw.githubusercontent.com/BioPhoton/angular-signature-pad/master/resources/demo.gif) 8 | 9 | # DEMO 10 | 11 | - [ ] [Live Demo](https://biophoton.github.io/angular-signature-pad) 12 | - [ ] [cli-project](https://github.io/BioPhoton/angular-signature-pad) 13 | 14 | ## Quick code example 15 | 16 | ``` html 17 | // app.component.html 18 | 19 | 20 | ``` 21 | 22 | ## Installing 23 | 24 | 1. Load library 25 | ``` bash 26 | $ npm install angular-signature-pad --save 27 | ``` 28 | 29 | 2. Import module 30 | ``` typescript 31 | // src/app/app.module.ts 32 | ... 33 | // IMPORT YOUR LIBRARY 34 | import { AngularSignaturePadModule } from 'angular-signature-pad'; 35 | 36 | @NgModule({ 37 | imports: [ 38 | ... 39 | AngularSignaturePadModule.forRoot() 40 | ] 41 | ... 42 | }) 43 | export class AppModule { } 44 | 45 | ``` 46 | 47 | 3. Use Component 48 | ```typescript 49 | // src/app/app.component.html 50 | 51 | 52 | value: 53 |
 54 |   {{sigPad.value | json}}
 55 | 
56 | 57 | 58 | ``` 59 | 60 | ## Styles 61 | To apply the default styles just import the `styles.scss` file from the `node_modules/angular-signature-pad` folder. 62 | 63 | ```scss 64 | // src/styles.scss 65 | 66 | @import "../node_modules/angular-signature-pad/styles"; 67 | ``` 68 | 69 | ### Custom styles 70 | The SignaturePadCard and SignaturePadCardGroup component have a default styling set over the `[theme]` property. 71 | It is applied over the `.raised` class internally. 72 | 73 | To create your own theme create a class i.e. `.my-theme` and combine 74 | it with the default class of the signature pad. `.signature-pad-card.my-theme`. 75 | Apply it to the component over the `[theme]` property binding. 76 | 77 | 1. Create styles 78 | ```scss 79 | .signature-pad-card.my-theme { 80 | ... 81 | 82 | .signature-pad { 83 | ... 84 | } 85 | 86 | .signature-pad-canvas { 87 | ... 88 | } 89 | 90 | .actions { 91 | ... 92 | .clear { 93 | ... 94 | } 95 | } 96 | 97 | .feedback { 98 | ... 99 | } 100 | } 101 | 102 | ``` 103 | 104 | 2. Apply styles to the theme property binding 105 | ```html 106 | 107 | ``` 108 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/src/components/signature-pad-control/signature-pad-control.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AfterViewInit, 3 | Component, 4 | forwardRef, 5 | Host, 6 | Inject, 7 | Input, 8 | OnChanges, 9 | OnInit, 10 | Optional, 11 | Renderer2, 12 | SkipSelf 13 | } from '@angular/core'; 14 | import { 15 | ControlContainer, 16 | ControlValueAccessor, 17 | FormControl, 18 | NG_VALUE_ACCESSOR 19 | } from '@angular/forms'; 20 | import {ISignaturePadConfig} from '../../interfaces/signature-pad-config.interface'; 21 | import {GlobalSignaturePadConfig} from '../../tokens/global-config.token'; 22 | import {SignaturePadComponent} from '../signature-pad/signature-pad.component'; 23 | 24 | @Component({ 25 | selector: 'signature-pad-control', 26 | template: ` 27 | 33 | 34 | `, 35 | providers: [ 36 | { 37 | provide: NG_VALUE_ACCESSOR, 38 | useExisting: forwardRef(() => SignaturePadControlComponent), 39 | multi: true 40 | } 41 | ] 42 | }) 43 | export class SignaturePadControlComponent extends SignaturePadComponent implements OnChanges, OnInit, AfterViewInit, ControlValueAccessor { 44 | 45 | @Input() 46 | formControlName: string; 47 | 48 | control: FormControl; 49 | 50 | onTouch = () => { 51 | } 52 | 53 | onModelChange = (value: any) => { 54 | } 55 | 56 | constructor(renderer: Renderer2, 57 | @Optional() @Host() @SkipSelf() private parentFormContainer: ControlContainer, 58 | @Optional() @Inject(GlobalSignaturePadConfig) defaultConfig?: ISignaturePadConfig) { 59 | super(renderer, defaultConfig); 60 | } 61 | 62 | ngOnInit() { 63 | super.ngOnInit(); 64 | if (this.parentFormContainer) { 65 | this.control = this.parentFormContainer['form'].controls[this.formControlName]; 66 | } 67 | } 68 | 69 | writeValue(signatureData: any): void { 70 | this.renderViewValue(signatureData); 71 | } 72 | 73 | registerOnChange(fn: any): void { 74 | this.onModelChange = fn; 75 | } 76 | 77 | registerOnTouched(fn: any): void { 78 | this.onTouch = fn; 79 | } 80 | 81 | // overrides 82 | 83 | /** 84 | * 85 | * @param isFocus 86 | */ 87 | handleFocus(isFocus: boolean): void { 88 | super.handleFocus(isFocus); 89 | if (!isFocus) { 90 | this.onTouch(); 91 | } 92 | } 93 | 94 | /** 95 | * 96 | * @param signatureData 97 | */ 98 | handleInput(signatureData: any) { 99 | super.handleInput(signatureData); 100 | this.onModelChange(signatureData); 101 | } 102 | 103 | clear() { 104 | super.clear(); 105 | this.onModelChange([]); 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/README.md: -------------------------------------------------------------------------------- 1 | # Angular SignaturePad 2 | 3 | This project provides components and utils for digital signatures. 4 | Use it to draw smooth signatures based on HTML5 canvas and uses variable width Bézier curve interpolation. 5 | [SignaturePad](https://github.com/szimek/signature_pad) is used a the vanilla implementation. 6 | 7 | ![Angular-Signature-Pad](https://raw.githubusercontent.com/BioPhoton/angular-signature-pad/master/resources/demo.gif) 8 | 9 | 10 | # DEMO 11 | 12 | - [ ] [Live Demo](https://biophoton.github.io/angular-signature-pad) 13 | - [ ] [cli-project](https://github.io/BioPhoton/angular-signature-pad) 14 | 15 | ## Quick code example 16 | 17 | ``` html 18 | // app.component.html 19 | 20 | 21 | ``` 22 | 23 | ## Installing 24 | 25 | 1. Load library 26 | ``` bash 27 | $ npm install angular-signature-pad --save 28 | ``` 29 | 30 | 2. Import module 31 | ``` typescript 32 | // src/app/app.module.ts 33 | ... 34 | // IMPORT YOUR LIBRARY 35 | import { AngularSignaturePadModule } from 'angular-signature-pad'; 36 | 37 | @NgModule({ 38 | imports: [ 39 | ... 40 | AngularSignaturePadModule.forRoot() 41 | ] 42 | ... 43 | }) 44 | export class AppModule { } 45 | 46 | ``` 47 | 48 | 3. Use Component 49 | ```typescript 50 | // src/app/app.component.html 51 | 52 | 53 | value: 54 |
 55 |   {{sigPad.value | json}}
 56 | 
57 | 58 | 59 | ``` 60 | 61 | ## Styles 62 | To apply the default styles just import the `styles.scss` file from the `node_modules/angular-signature-pad` folder. 63 | 64 | ```scss 65 | // src/styles.scss 66 | 67 | @import "../node_modules/angular-signature-pad/styles"; 68 | ``` 69 | 70 | ### Custom styles 71 | The SignaturePadCard and SignaturePadCardGroup component have a default styling set over the `[theme]` property. 72 | It is applied over the `.raised` class internally. 73 | 74 | To create your own theme create a class i.e. `.my-theme` and combine 75 | it with the default class of the signature pad. `.signature-pad-card.my-theme`. 76 | Apply it to the component over the `[theme]` property binding. 77 | 78 | 1. Create styles 79 | ```scss 80 | .signature-pad-card.my-theme { 81 | ... 82 | 83 | .signature-pad { 84 | ... 85 | } 86 | 87 | .signature-pad-canvas { 88 | ... 89 | } 90 | 91 | .actions { 92 | ... 93 | .clear { 94 | ... 95 | } 96 | } 97 | 98 | .feedback { 99 | ... 100 | } 101 | } 102 | 103 | ``` 104 | 105 | 2. Apply styles to the theme property binding 106 | ```html 107 | 108 | ``` 109 | 110 | ## Components 111 | 112 | 113 | ## Validators 114 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dev-angular-signature-pad", 3 | "version": "0.0.0", 4 | "license": "MIT", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/BioPhoton/angular-signature-pad" 8 | }, 9 | "author": { 10 | "name": "Michael Hladky", 11 | "email": "michael@hladky.at" 12 | }, 13 | "keywords": [ 14 | "angular", 15 | "signature pad", 16 | "canvas", 17 | "signature" 18 | ], 19 | "bugs": { 20 | "url": "https://github.com/BioPhoton/angular-signature-pad/issues" 21 | }, 22 | "scripts": { 23 | "ng": "ng", 24 | "start": "ng serve", 25 | "build": "ng build", 26 | "test": "ng test", 27 | "lint": "ng lint", 28 | "e2e": "ng e2e", 29 | "build:package": "node ./chore/scripts/tasks/build", 30 | "update-node_modules": "npm run build:package && copyfiles -u 4 src/libs/angular-signature-pad/dist/**/* node_modules/angular-signature-pad/", 31 | "build:github-page": "ng build --prod --output-path docs --base-href /angular-signature-pad/", 32 | "coverage": "ng test --progress=false --watch=false --code-coverage", 33 | "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0", 34 | "docs": "npm run docs:build", 35 | "docs:build": "compodoc ./src/libs -p tsconfig.json -n angular-signature-pad -d docs --hideGenerator", 36 | "docs:serve": "npm run docs:build -- -s", 37 | "docs:watch": "npm run docs:build -- -s -w" 38 | }, 39 | "private": true, 40 | "dependencies": { 41 | "@angular/animations": "^4.2.4", 42 | "@angular/common": "^4.2.4", 43 | "@angular/compiler": "^4.2.4", 44 | "@angular/core": "^4.2.4", 45 | "@angular/forms": "^4.2.4", 46 | "@angular/http": "^4.2.4", 47 | "@angular/platform-browser": "^4.2.4", 48 | "@angular/platform-browser-dynamic": "^4.2.4", 49 | "@angular/router": "^4.2.4", 50 | "angular-signature-pad": "0.0.1", 51 | "bootstrap": "^4.0.0-beta", 52 | "core-js": "^2.4.1", 53 | "font-awesome": "^4.7.0", 54 | "rxjs": "^5.4.2", 55 | "signature_pad": "^2.3.2", 56 | "zone.js": "^0.8.14" 57 | }, 58 | "devDependencies": { 59 | "@angular/cli": "1.4.0", 60 | "@angular/compiler-cli": "^4.2.4", 61 | "@angular/language-service": "^4.2.4", 62 | "@types/jasmine": "~2.5.53", 63 | "@types/jasminewd2": "~2.0.2", 64 | "@types/node": "~6.0.60", 65 | "codelyzer": "~3.1.1", 66 | "copyfiles": "^1.2.0", 67 | "jasmine-core": "~2.6.2", 68 | "jasmine-spec-reporter": "~4.1.0", 69 | "karma": "~1.7.0", 70 | "karma-chrome-launcher": "~2.1.1", 71 | "karma-cli": "~1.0.1", 72 | "karma-coverage-istanbul-reporter": "^1.2.1", 73 | "karma-jasmine": "~1.1.0", 74 | "karma-jasmine-html-reporter": "^0.2.2", 75 | "ng-packagr": "^1.0.1", 76 | "protractor": "~5.1.2", 77 | "rimraf": "^2.6.2", 78 | "ts-node": "~3.2.0", 79 | "tslint": "~5.3.2", 80 | "typescript": "~2.3.3" 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/app/shared/components/control-state/control-state.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 | 5 |

6 |
7 | 8 |
    10 |
  • 11 | {{error.name}} 12 |
  • 13 |
14 | 15 |
16 |
17 |
value
18 |
20 | {{control.value | json}} 21 |
22 | 23 |
valid
24 |
26 | {{control.valid }} 27 |
28 | 29 |
invalid
30 |
32 | {{control.invalid }} 33 |
34 | 35 |
status
36 |
{{control.status}} 41 |
42 | 43 |
pending
44 |
46 | {{control.pending}} 47 |
48 | 49 |
pristine
50 |
52 | {{control.pristine}} 53 |
54 |
dirty
55 |
57 | {{control.dirty}} 58 |
59 | 60 |
touched
61 |
63 | {{control.touched}} 64 |
65 | 66 |
untouched
67 |
69 | {{control.untouched}} 70 |
71 | 72 |
focus
73 |
75 | {{control?.focus}} 76 |
77 | 78 |
disabled
79 |
81 | {{control.disabled}} 82 |
83 | 84 |
errors
85 |
87 |
{{control.errors | json}}
88 |
89 | 90 |
91 | 92 |
93 |
94 | -------------------------------------------------------------------------------- /docs/4.0aca6a203232d2b2acf4.chunk.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([4],{fBD8:function(n,l,u){"use strict";function t(n){return r._43(0,[(n()(),r._19(0,null,null,1,"h1",[],null,null,null,null,null)),(n()(),r._41(null,["\n SignaturePad Card\n"])),(n()(),r._41(null,["\n\n"])),(n()(),r._19(0,null,null,11,"div",[],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(n,l,u){var t=!0;if("submit"===l){t=!1!==r._33(n,4).onSubmit(u)&&t}if("reset"===l){t=!1!==r._33(n,4).onReset()&&t}return t},null,null)),r._17(540672,null,0,a.f,[[8,null],[8,null]],{form:[0,"form"]},null),r._38(2048,null,a.b,null,[a.f]),r._17(16384,null,0,a.j,[a.b],null,null),(n()(),r._41(null,["\n"])),(n()(),r._19(0,null,null,5,"signature-pad-card",[["formControlName","signature"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],null,null,o.g,o.c)),r._17(4833280,null,0,s.j,[r.O,[3,a.b],[2,s.b]],{formControlName:[0,"formControlName"],theme:[1,"theme"]},null),r._38(1024,null,a.g,function(n){return[n]},[s.j]),r._17(671744,null,0,a.e,[[3,a.b],[8,null],[8,null],[2,a.g]],{name:[0,"name"]},null),r._38(2048,null,a.h,null,[a.e]),r._17(16384,null,0,a.i,[a.h],null,null),(n()(),r._41(null,["\n"])),(n()(),r._41(null,["\n"]))],function(n,l){n(l,4,0,l.component.testForm);n(l,9,0,"signature","raised");n(l,11,0,"signature")},function(n,l){n(l,3,0,r._33(l,6).ngClassUntouched,r._33(l,6).ngClassTouched,r._33(l,6).ngClassPristine,r._33(l,6).ngClassDirty,r._33(l,6).ngClassValid,r._33(l,6).ngClassInvalid,r._33(l,6).ngClassPending),n(l,8,0,r._33(l,13).ngClassUntouched,r._33(l,13).ngClassTouched,r._33(l,13).ngClassPristine,r._33(l,13).ngClassDirty,r._33(l,13).ngClassValid,r._33(l,13).ngClassInvalid,r._33(l,13).ngClassPending)})}function e(n){return r._43(0,[(n()(),r._19(0,null,null,1,"app-signature-pad-card",[],null,null,null,t,c)),r._17(114688,null,0,_,[a.d],null,null)],function(n,l){n(l,1,0)},null)}Object.defineProperty(l,"__esModule",{value:!0});var r=u("/oeL"),i=function(){function n(){}return n}(),a=u("bm2B"),o=u("yID4"),s=u("yprN"),_=function(){function n(n){this.testForm=n.group({signature:["",[s.e,s.c,s.d,Object(s.f)(1),Object(s.g)(4,1)]]}),this.signatureControl=this.testForm.get("signature")}return n.prototype.ngOnInit=function(){},n.ctorParameters=function(){return[{type:a.d}]},n}(),g=[],c=r._16({encapsulation:2,styles:g,data:{}}),d=r._14("app-signature-pad-card",_,e,{},{},[]),f=u("qbdv"),m=u("BkNc"),p=function(){function n(){}return n}(),C=u("T2Au");u.d(l,"SignaturePadCardModuleNgFactory",function(){return h});var h=r._15(i,[],function(n){return r._30([r._31(512,r.l,r._11,[[8,[d]],[3,r.l],r.F]),r._31(4608,f.n,f.m,[r.B]),r._31(4608,a.d,a.d,[]),r._31(4608,a.o,a.o,[]),r._31(4608,s.l,s.l,[]),r._31(512,f.c,f.c,[]),r._31(512,m.n,m.n,[[2,m.s],[2,m.k]]),r._31(512,p,p,[]),r._31(512,a.l,a.l,[]),r._31(512,a.k,a.k,[]),r._31(512,C.a,C.a,[]),r._31(512,s.a,s.a,[]),r._31(512,i,i,[]),r._31(1024,m.i,function(){return[[{path:"",component:_}]]},[])])})}}); -------------------------------------------------------------------------------- /chore/scripts/tasks/changelog.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const util = require('util') 4 | const path = require('path') 5 | const exec = util.promisify(require('child_process').exec) 6 | 7 | const utils = require('../utils') 8 | const config = require('../../config') 9 | 10 | let detectedPreset 11 | let detectedBump 12 | let detectedVersion 13 | 14 | module.exports = changelog 15 | 16 | function changelog () { 17 | // create changelog 18 | 19 | // backup the src/package.json file 20 | // we copy it to have the initial state saved. 21 | // we bump the version update the changelog 22 | // after doing this we use the real package.json and do another version bump 23 | // there to have change log and version bump in separate commits 24 | return utils.backupPackageJson() 25 | // ensures that the right convention was detected 26 | .then(() => utils.getPreset()) 27 | .then((preset) => { 28 | detectedPreset = preset 29 | return (detectedPreset === config.validPreset) ? Promise.resolve(detectedPreset) : Promise.reject(detectedPreset) 30 | }) 31 | // ensures that a bump type was detected 32 | .then(() => utils.getBump()) 33 | .then((bump) => { 34 | detectedBump = bump 35 | console.info('detectedBump'.gray, detectedBump) 36 | return (detectedBump) ? Promise.resolve(detectedBump) : Promise.reject(detectedBump) 37 | }) 38 | // npm version [detectedBump] bumps the version specified in detectedBump 39 | // and writes the new data back to package.json 40 | // If you run npm version in a git repo, it will also create a version commit and tag. 41 | // This behavior is disabled by --no-git-tag-version 42 | // the var detectedBump specifies the segment of the version code to bump 43 | .then((bump) => { 44 | console.info('bump version without git '.green, detectedBump) 45 | return exec('npm --no-git-tag-version version ' + detectedBump, {cwd: config.libPath}) 46 | }) 47 | // conventional-changelog creates a chagnelog markdown from commits 48 | // -i Read the CHANGELOG from this file 49 | // CHANGELOG.md it the name of the file to read from 50 | // -s Outputting to the infile so you don't need to specify the same file as outfile 51 | // -p Name of the preset you want to use. In this case it is angular that is stored in $preset 52 | .then(() => exec('conventional-changelog -i CHANGELOG.md -s -p ' + detectedPreset, {cwd: config.libPath})) 53 | // add CHANGELOG.md to the commit 54 | .then(() => exec('git add CHANGELOG.md', {cwd: config.libPath})) 55 | // get the version number of package.json 56 | .then(() => { 57 | const packageJson = require(path.join(config.libPath, 'package.json')) 58 | detectedVersion = packageJson.version 59 | console.log('new version ', detectedVersion); 60 | }) 61 | // copy package.json into dist because we want to have the new version in the dist folder also 62 | .then(() => utils.copyFile(path.join(config.libPath, 'package.json'), path.join(config.libPath, 'dist', 'package.json'))) 63 | // Replace the already bumped package.json with the _package.json initial copy 64 | .then(() => { 65 | return utils.restorePackageJson().then(() => { 66 | console.info('restored package files'.green) 67 | }) 68 | }) 69 | // commit with comment 70 | .then(() => exec(`git commit -m"docs(CHANGELOG): ${detectedVersion}"`, {cwd: config.libPath})) 71 | } 72 | -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | ## [0.0.14](https://github.com/BioPhoton/angular-signature-pad/compare/0.0.13...0.0.14) (2017-10-08) 3 | 4 | 5 | 6 | 7 | ## [0.0.6](https://github.com/BioPhoton/angular-signature-pad/compare/0.0.5...0.0.6) (2017-10-08) 8 | 9 | 10 | 11 | 12 | ## [0.0.5](https://github.com/BioPhoton/angular-signature-pad/compare/0.0.4...0.0.5) (2017-10-08) 13 | 14 | 15 | 16 | 17 | ## [0.0.4](https://github.com/BioPhoton/angular-signature-pad/compare/0.0.3...0.0.4) (2017-10-08) 18 | 19 | 20 | 21 | 22 | ## [0.0.2](https://github.com/BioPhoton/angular-signature-pad/compare/0.1.0...0.0.2) (2017-10-08) 23 | 24 | 25 | ### Bug Fixes 26 | 27 | * **gitignore:** edit ([a9a06e1](https://github.com/BioPhoton/angular-signature-pad/commit/a9a06e1)) 28 | * **README:** edit ([d7c66e3](https://github.com/BioPhoton/angular-signature-pad/commit/d7c66e3)) 29 | * **version:** edit ([22c350b](https://github.com/BioPhoton/angular-signature-pad/commit/22c350b)) 30 | 31 | 32 | 33 | 34 | ## [0.0.2](https://github.com/BioPhoton/angular-signature-pad/compare/0.1.0...0.0.2) (2017-10-08) 35 | 36 | 37 | ### Bug Fixes 38 | 39 | * **gitignore:** edit ([a9a06e1](https://github.com/BioPhoton/angular-signature-pad/commit/a9a06e1)) 40 | * **README:** edit ([d7c66e3](https://github.com/BioPhoton/angular-signature-pad/commit/d7c66e3)) 41 | * **version:** edit ([22c350b](https://github.com/BioPhoton/angular-signature-pad/commit/22c350b)) 42 | 43 | 44 | 45 | 46 | ## [0.0.2](https://github.com/BioPhoton/angular-signature-pad/compare/0.1.0...0.0.2) (2017-10-08) 47 | 48 | 49 | ### Bug Fixes 50 | 51 | * **gitignore:** edit ([a9a06e1](https://github.com/BioPhoton/angular-signature-pad/commit/a9a06e1)) 52 | * **README:** edit ([d7c66e3](https://github.com/BioPhoton/angular-signature-pad/commit/d7c66e3)) 53 | * **version:** edit ([22c350b](https://github.com/BioPhoton/angular-signature-pad/commit/22c350b)) 54 | 55 | 56 | 57 | 58 | ## [0.0.2](https://github.com/BioPhoton/angular-signature-pad/compare/0.1.0...0.0.2) (2017-10-08) 59 | 60 | 61 | ### Bug Fixes 62 | 63 | * **gitignore:** edit ([a9a06e1](https://github.com/BioPhoton/angular-signature-pad/commit/a9a06e1)) 64 | * **README:** edit ([d7c66e3](https://github.com/BioPhoton/angular-signature-pad/commit/d7c66e3)) 65 | * **version:** edit ([22c350b](https://github.com/BioPhoton/angular-signature-pad/commit/22c350b)) 66 | 67 | 68 | 69 | 70 | ## [0.0.2](https://github.com/BioPhoton/angular-signature-pad/compare/0.1.0...0.0.2) (2017-10-08) 71 | 72 | 73 | ### Bug Fixes 74 | 75 | * **gitignore:** edit ([a9a06e1](https://github.com/BioPhoton/angular-signature-pad/commit/a9a06e1)) 76 | * **README:** edit ([d7c66e3](https://github.com/BioPhoton/angular-signature-pad/commit/d7c66e3)) 77 | * **version:** edit ([22c350b](https://github.com/BioPhoton/angular-signature-pad/commit/22c350b)) 78 | 79 | 80 | 81 | 82 | ## [0.0.2](https://github.com/BioPhoton/angular-signature-pad/compare/0.1.0...0.0.2) (2017-10-08) 83 | 84 | 85 | ### Bug Fixes 86 | 87 | * **gitignore:** edit ([a9a06e1](https://github.com/BioPhoton/angular-signature-pad/commit/a9a06e1)) 88 | * **README:** edit ([d7c66e3](https://github.com/BioPhoton/angular-signature-pad/commit/d7c66e3)) 89 | * **version:** edit ([22c350b](https://github.com/BioPhoton/angular-signature-pad/commit/22c350b)) 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "arrow-return-shorthand": true, 7 | "callable-types": true, 8 | "class-name": true, 9 | "comment-format": [ 10 | true, 11 | "check-space" 12 | ], 13 | "curly": true, 14 | "eofline": true, 15 | "forin": true, 16 | "import-blacklist": [ 17 | true, 18 | "rxjs" 19 | ], 20 | "import-spacing": true, 21 | "indent": [ 22 | true, 23 | "spaces" 24 | ], 25 | "interface-over-type-literal": true, 26 | "label-position": true, 27 | "max-line-length": [ 28 | true, 29 | 140 30 | ], 31 | "member-access": false, 32 | "member-ordering": [ 33 | true, 34 | { 35 | "order": [ 36 | "static-field", 37 | "instance-field", 38 | "static-method", 39 | "instance-method" 40 | ] 41 | } 42 | ], 43 | "no-arg": true, 44 | "no-bitwise": true, 45 | "no-console": [ 46 | true, 47 | "debug", 48 | "info", 49 | "time", 50 | "timeEnd", 51 | "trace" 52 | ], 53 | "no-construct": true, 54 | "no-debugger": true, 55 | "no-duplicate-super": true, 56 | "no-empty": false, 57 | "no-empty-interface": true, 58 | "no-eval": true, 59 | "no-inferrable-types": [ 60 | true, 61 | "ignore-params" 62 | ], 63 | "no-misused-new": true, 64 | "no-non-null-assertion": true, 65 | "no-shadowed-variable": true, 66 | "no-string-literal": false, 67 | "no-string-throw": true, 68 | "no-switch-case-fall-through": true, 69 | "no-trailing-whitespace": true, 70 | "no-unnecessary-initializer": true, 71 | "no-unused-expression": true, 72 | "no-use-before-declare": true, 73 | "no-var-keyword": true, 74 | "object-literal-sort-keys": false, 75 | "one-line": [ 76 | true, 77 | "check-open-brace", 78 | "check-catch", 79 | "check-else", 80 | "check-whitespace" 81 | ], 82 | "prefer-const": true, 83 | "quotemark": [ 84 | true, 85 | "single" 86 | ], 87 | "radix": true, 88 | "semicolon": [ 89 | true, 90 | "always" 91 | ], 92 | "triple-equals": [ 93 | true, 94 | "allow-null-check" 95 | ], 96 | "typedef-whitespace": [ 97 | true, 98 | { 99 | "call-signature": "nospace", 100 | "index-signature": "nospace", 101 | "parameter": "nospace", 102 | "property-declaration": "nospace", 103 | "variable-declaration": "nospace" 104 | } 105 | ], 106 | "typeof-compare": true, 107 | "unified-signatures": true, 108 | "variable-name": false, 109 | "whitespace": [ 110 | true, 111 | "check-branch", 112 | "check-decl", 113 | "check-operator", 114 | "check-separator", 115 | "check-type" 116 | ], 117 | "directive-selector": [ 118 | false, 119 | "attribute", 120 | "app", 121 | "camelCase" 122 | ], 123 | "component-selector": [ 124 | false, 125 | "element", 126 | "app", 127 | "kebab-case" 128 | ], 129 | "use-input-property-decorator": true, 130 | "use-output-property-decorator": true, 131 | "use-host-property-decorator": true, 132 | "no-input-rename": true, 133 | "no-output-rename": true, 134 | "use-life-cycle-interface": true, 135 | "use-pipe-transform-interface": true, 136 | "component-class-suffix": true, 137 | "directive-class-suffix": true, 138 | "no-access-missing-member": true, 139 | "templates-use-public": true, 140 | "invoke-injectable": true 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /docs/3rdpartylicenses.txt: -------------------------------------------------------------------------------- 1 | core-js@2.5.1 2 | MIT 3 | Copyright (c) 2014-2017 Denis Pushkarev 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 13 | all 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 21 | THE SOFTWARE. 22 | 23 | webpack@3.5.6 24 | MIT 25 | Copyright JS Foundation and other contributors 26 | 27 | Permission is hereby granted, free of charge, to any person obtaining 28 | a copy of this software and associated documentation files (the 29 | 'Software'), to deal in the Software without restriction, including 30 | without limitation the rights to use, copy, modify, merge, publish, 31 | distribute, sublicense, and/or sell copies of the Software, and to 32 | permit persons to whom the Software is furnished to do so, subject to 33 | the following conditions: 34 | 35 | The above copyright notice and this permission notice shall be 36 | included in all copies or substantial portions of the Software. 37 | 38 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 39 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 40 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 41 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 42 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 43 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 44 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 45 | 46 | zone.js@0.8.18 47 | MIT 48 | The MIT License 49 | 50 | Copyright (c) 2016 Google, Inc. 51 | 52 | Permission is hereby granted, free of charge, to any person obtaining a copy 53 | of this software and associated documentation files (the "Software"), to deal 54 | in the Software without restriction, including without limitation the rights 55 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 56 | copies of the Software, and to permit persons to whom the Software is 57 | furnished to do so, subject to the following conditions: 58 | 59 | The above copyright notice and this permission notice shall be included in 60 | all copies or substantial portions of the Software. 61 | 62 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 63 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 64 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 65 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 66 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 67 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 68 | THE SOFTWARE. 69 | 70 | @angular/core@4.4.4 71 | MIT 72 | MIT 73 | 74 | @angular/router@4.4.4 75 | MIT 76 | MIT 77 | 78 | @angular/common@4.4.4 79 | MIT 80 | MIT 81 | 82 | @angular/forms@4.4.4 83 | MIT 84 | MIT 85 | 86 | @angular/platform-browser@4.4.4 87 | MIT 88 | MIT 89 | 90 | angular-signature-pad@0.0.1 91 | MIT 92 | MIT -------------------------------------------------------------------------------- /src/app/pages/signature-pad-control-validation/signature-pad-control-validation.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | import {FormBuilder, FormControl, FormGroup} from '@angular/forms'; 3 | import {isArray, consistOfArrays, consistOfObjects, minLines, minPointsInEachNLines} from 'angular-signature-pad'; 4 | 5 | @Component({ 6 | selector: 'app-signature-pad-control-validation', 7 | templateUrl: './signature-pad-control-validation.component.html' 8 | }) 9 | export class SignaturePadControlValidationComponent implements OnInit { 10 | 11 | testForm: FormGroup; 12 | signatureControl: FormControl; 13 | 14 | constructor(private fb: FormBuilder) { 15 | } 16 | 17 | ngOnInit() { 18 | this.testForm = this.fb.group({ 19 | signature: ['', [ 20 | isArray, 21 | consistOfArrays, 22 | consistOfObjects, 23 | minLines(2), 24 | minPointsInEachNLines(4, 1) 25 | ]] 26 | }); 27 | this.signatureControl = this.testForm.get('signature') as FormControl; 28 | } 29 | 30 | assignValidSignature() { 31 | this.signatureControl.setValue([ 32 | [ 33 | { 34 | x: 531.328125, 35 | y: 130, 36 | time: 1506167092932, 37 | color: 'red' 38 | }, 39 | { 40 | x: 431.328125, 41 | y: 100, 42 | time: 1506167093932, 43 | color: 'red' 44 | } 45 | ], 46 | [ 47 | { 48 | x: 131.328125, 49 | y: 30, 50 | time: 1506167094932, 51 | color: 'red' 52 | }, 53 | { 54 | x: 231.328125, 55 | y: 50, 56 | time: 1506167095932, 57 | color: 'red' 58 | }, 59 | { 60 | x: 31.328125, 61 | y: 10, 62 | time: 1506167096932, 63 | color: 'red' 64 | }, 65 | { 66 | x: 61.328125, 67 | y: 110, 68 | time: 1506167097932, 69 | color: 'red' 70 | } 71 | ] 72 | ]); 73 | } 74 | 75 | assignNonArray() { 76 | this.signatureControl.setValue('thisIsNoArray'); 77 | } 78 | 79 | assignArrayOfNonArrays() { 80 | this.signatureControl.setValue(['thisIsNoArray']); 81 | } 82 | 83 | assignArrayArraysOfNonObjects() { 84 | this.signatureControl.setValue([['thisIsNoObject']]); 85 | } 86 | 87 | assignSignatureOf1Line() { 88 | this.signatureControl.setValue([[ 89 | { 90 | x: 131.328125, 91 | y: 30, 92 | time: 1506167094932, 93 | color: 'red' 94 | }, 95 | { 96 | x: 231.328125, 97 | y: 50, 98 | time: 1506167095932, 99 | color: 'red' 100 | }, 101 | { 102 | x: 31.328125, 103 | y: 10, 104 | time: 1506167096932, 105 | color: 'red' 106 | }, 107 | { 108 | x: 61.328125, 109 | y: 110, 110 | time: 1506167097932, 111 | color: 'red' 112 | } 113 | ]]); 114 | } 115 | 116 | assignSignatureOf2LineEach2Points() { 117 | this.signatureControl.setValue([ 118 | [ 119 | { 120 | x: 531.328125, 121 | y: 130, 122 | time: 1506167092932, 123 | color: 'red' 124 | }, 125 | { 126 | x: 431.328125, 127 | y: 100, 128 | time: 1506167093932, 129 | color: 'red' 130 | } 131 | ], 132 | [ 133 | { 134 | x: 131.328125, 135 | y: 30, 136 | time: 1506167094932, 137 | color: 'red' 138 | }, 139 | { 140 | x: 231.328125, 141 | y: 50, 142 | time: 1506167095932, 143 | color: 'red' 144 | } 145 | ] 146 | ]); 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /chore/scripts/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const colors = require('colors'); 4 | const fs = require('fs') 5 | const path = require('path') 6 | const util = require('util') 7 | const exec = util.promisify(require('child_process').exec) 8 | 9 | const config = require('../config') 10 | const utils = {} 11 | 12 | utils.deleteFile = deleteFile 13 | utils.copyFile = copyFile 14 | utils.copyFilePromise = copyFilePromise 15 | utils.copyMultiFilePromise = copyMultiFilePromise 16 | utils.backupPackageJson = backupPackageJson 17 | utils.restorePackageJson = restorePackageJson 18 | utils.getPreset = getPreset 19 | utils.getBump = getBump 20 | utils.getPackageVersion = getPackageVersion 21 | 22 | module.exports = utils 23 | 24 | function deleteFile (source) { 25 | console.info('start deleting ', source) 26 | return exec('rimraf ' + source, {cwd: __base}) 27 | .then(() => { 28 | console.info('remove files done') 29 | }) 30 | .catch((err) => { 31 | console.error('remove files error: ', err) 32 | }) 33 | 34 | } 35 | function copyFile (source, target, cb) { 36 | 37 | cb = cb || function () { 38 | } 39 | 40 | return new Promise((resolve, reject) => { 41 | console.info('copyFile', source, target) 42 | 43 | let ensureDirectoryExistence = function (filePath) { 44 | let dirname = path.dirname(filePath) 45 | if (fs.existsSync(dirname)) { 46 | return true 47 | } 48 | ensureDirectoryExistence(dirname) 49 | fs.mkdirSync(dirname) 50 | } 51 | ensureDirectoryExistence(target) 52 | 53 | let rd = fs.createReadStream(source) 54 | rd.on('error', function (err) { 55 | reject(err) 56 | }) 57 | let wr = fs.createWriteStream(target) 58 | wr.on('error', function (err) { 59 | reject(err) 60 | }) 61 | wr.on('close', function (ex) { 62 | resolve() 63 | }) 64 | rd.pipe(wr) 65 | 66 | }) 67 | } 68 | 69 | function copyFilePromise (source, target) { 70 | return new Promise(function (accept, reject) { 71 | copyFile(source, target, function (data) { 72 | if (data === undefined) { 73 | accept() 74 | } else { 75 | reject(data) 76 | } 77 | }) 78 | }) 79 | } 80 | 81 | function copyMultiFilePromise (srcTgtPairArr) { 82 | let copyFilePromiseArr = new Array() 83 | srcTgtPairArr.forEach(function (srcTgtPair) { 84 | copyFilePromiseArr.push(copyFilePromise(srcTgtPair[0], srcTgtPair[1])) 85 | }) 86 | return Promise.all(copyFilePromiseArr) 87 | } 88 | 89 | function backupPackageJson () { 90 | const source1 = path.join(config.libPath, 'package.json') 91 | const target1 = path.join(config.libPath, '_package.json') 92 | 93 | const source2 = path.join(config.libPath, 'package-lock.json') 94 | const target2 = path.join(config.libPath, '_package-lock.json') 95 | return copyFile(source1, target1) 96 | //.then(() => copyFile(source2, target2)) 97 | } 98 | 99 | function restorePackageJson () { 100 | const source1 = path.join(config.libPath, '_package.json') 101 | const target1 = path.join(config.libPath, 'package.json') 102 | 103 | const source2 = path.join(config.libPath, '_package-lock.json') 104 | const target2 = path.join(config.libPath, 'package-lock.json') 105 | 106 | return copyFile(source1, target1) 107 | .then(() => utils.deleteFile(source1)) 108 | //.then(() => copyFile(source2, target2)) 109 | //.then(() => utils.deleteFile(source2)) 110 | } 111 | 112 | function getPreset () { 113 | // Detect what commit message convention your repository is using 114 | // source: https://github.com/conventional-changelog/conventional-commits-detector/blob/master/README.md 115 | return exec('conventional-commits-detector', {cwd: __base}) 116 | .then((presetRes) => { 117 | if (!presetRes.stdout || presetRes.stderr) { 118 | return Promise.reject(presetRes.stderr || false) 119 | } else { 120 | const preset = presetRes.stdout.split('\n')[0] 121 | return Promise.resolve(preset) 122 | } 123 | }) 124 | } 125 | 126 | function getBump () { 127 | // Detect the recommended bump type by the conventional-commit standard 128 | // source: https://github.com/conventional-changelog-archived-repos/conventional-recommended-bump/blob/master/README.md 129 | return exec('conventional-recommended-bump -p angular', {cwd: __base}).then((bumpRes) => { 130 | if (!bumpRes.stdout || bumpRes.stderr) { 131 | return Promise.reject(bumpRes.stderr || false) 132 | } else { 133 | const bump = bumpRes.stdout.split('\n')[0] 134 | return Promise.resolve(bump) 135 | } 136 | }) 137 | } 138 | 139 | function getPackageVersion () { 140 | const packageJson = require(path.join(config.libPath, 'package.json')) 141 | return Promise.resolve(packageJson.version) 142 | } 143 | -------------------------------------------------------------------------------- /docs/3.86da506e6b0a467403f8.chunk.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([3],{uD5q:function(l,n,u){"use strict";function t(l){return c._43(0,[(l()(),c._19(0,null,null,1,"span",[["class","form-text text-danger"]],null,null,null,null,null)),(l()(),c._41(null,["Signature is no array"]))],null,null)}function r(l){return c._43(0,[(l()(),c._19(0,null,null,1,"span",[["class","form-text text-danger"]],null,null,null,null,null)),(l()(),c._41(null,["Signature don't consist of array"]))],null,null)}function o(l){return c._43(0,[(l()(),c._19(0,null,null,1,"span",[["class","form-text text-danger"]],null,null,null,null,null)),(l()(),c._41(null,["Signature segments don't consist of objects"]))],null,null)}function e(l){return c._43(0,[(l()(),c._19(0,null,null,1,"span",[["class","form-text text-danger"]],null,null,null,null,null)),(l()(),c._41(null,["Signature have wrong line coun't"]))],null,null)}function i(l){return c._43(0,[(l()(),c._19(0,null,null,1,"span",[["class","form-text text-danger"]],null,null,null,null,null)),(l()(),c._41(null,["Signature have wrong point count in segments"]))],null,null)}function s(l){return c._43(0,[(l()(),c._19(0,null,null,1,"h1",[],null,null,null,null,null)),(l()(),c._41(null,["\n SignaturePad Control Validation\n"])),(l()(),c._41(null,["\n\n\n"])),(l()(),c._19(0,null,null,75,"form",[["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,u){var t=!0;if("submit"===n){t=!1!==c._33(l,5).onSubmit(u)&&t}if("reset"===n){t=!1!==c._33(l,5).onReset()&&t}return t},null,null)),c._17(16384,null,0,g.n,[],null,null),c._17(540672,null,0,g.f,[[8,null],[8,null]],{form:[0,"form"]},null),c._38(2048,null,g.b,null,[g.f]),c._17(16384,null,0,g.j,[g.b],null,null),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,68,"div",[["class","row"]],null,null,null,null,null)),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,40,"div",[["class","col-4"]],null,null,null,null,null)),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,19,"div",[["class","btn-group-vertical"],["style","width: 100%"]],null,null,null,null,null)),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,1,"button",[["class","btn btn-outline-secondary"]],null,[[null,"click"]],function(l,n,u){var t=!0,r=l.component;if("click"===n){t=!1!==r.assignValidSignature()&&t}return t},null,null)),(l()(),c._41(null,["\n assignValidSignature\n "])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,1,"button",[["class","btn btn-outline-secondary"]],null,[[null,"click"]],function(l,n,u){var t=!0,r=l.component;if("click"===n){t=!1!==r.assignNonArray()&&t}return t},null,null)),(l()(),c._41(null,["\n assignNonArray\n "])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,1,"button",[["class","btn btn-outline-secondary"]],null,[[null,"click"]],function(l,n,u){var t=!0,r=l.component;if("click"===n){t=!1!==r.assignArrayOfNonArrays()&&t}return t},null,null)),(l()(),c._41(null,["\n assignArrayOfNonArrays\n "])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,1,"button",[["class","btn btn-outline-secondary"]],null,[[null,"click"]],function(l,n,u){var t=!0,r=l.component;if("click"===n){t=!1!==r.assignArrayArraysOfNonObjects()&&t}return t},null,null)),(l()(),c._41(null,["\n assignArrayArraysOfNonObjects\n "])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,1,"button",[["class","btn btn-outline-secondary"]],null,[[null,"click"]],function(l,n,u){var t=!0,r=l.component;if("click"===n){t=!1!==r.assignSignatureOf1Line()&&t}return t},null,null)),(l()(),c._41(null,["\n assignSignatureOf1Line\n "])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,1,"button",[["class","btn btn-outline-secondary"]],null,[[null,"click"]],function(l,n,u){var t=!0,r=l.component;if("click"===n){t=!1!==r.assignSignatureOf2LineEach2Points()&&t}return t},null,null)),(l()(),c._41(null,["\n assignSignatureOf2LineEach2Points\n "])),(l()(),c._41(null,["\n "])),(l()(),c._41(null,["\n\n "])),(l()(),c._19(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),c._41(null,["\n\n "])),(l()(),c._19(0,null,null,4,"div",[["class","btn-group-vertical"],["style","width: 100%"]],null,null,null,null,null)),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,1,"button",[["class","btn btn-outline-secondary"],["type","reset"]],null,null,null,null,null)),(l()(),c._41(null,["Reset"])),(l()(),c._41(null,["\n "])),(l()(),c._41(null,["\n\n "])),(l()(),c._19(0,null,null,1,"b",[],null,null,null,null,null)),(l()(),c._41(null,["Value: "])),(l()(),c._19(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,2,"pre",[],null,null,null,null,null)),(l()(),c._41(null,["",""])),c._35(0,y.f,[]),(l()(),c._41(null,["\n "])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,23,"div",[["class","col-8"]],null,null,null,null,null)),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,5,"signature-pad-control",[["formControlName","signature"],["style","width: 100%; height:400px"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],null,null,m.f,m.b)),c._17(4833280,[["sigPad",4]],0,f.i,[c.O,[3,g.b],[2,f.b]],{formControlName:[0,"formControlName"]},null),c._38(1024,null,g.g,function(l){return[l]},[f.i]),c._17(671744,null,0,g.e,[[3,g.b],[8,null],[8,null],[2,g.g]],{name:[0,"name"]},null),c._38(2048,null,g.h,null,[g.e]),c._17(16384,null,0,g.i,[g.h],null,null),(l()(),c._41(null,["\n\n "])),(l()(),c._13(16777216,null,null,1,null,t)),c._17(16384,null,0,y.l,[c._1,c.X],{ngIf:[0,"ngIf"]},null),(l()(),c._41(null,["\n "])),(l()(),c._13(16777216,null,null,1,null,r)),c._17(16384,null,0,y.l,[c._1,c.X],{ngIf:[0,"ngIf"]},null),(l()(),c._41(null,["\n "])),(l()(),c._13(16777216,null,null,1,null,o)),c._17(16384,null,0,y.l,[c._1,c.X],{ngIf:[0,"ngIf"]},null),(l()(),c._41(null,["\n "])),(l()(),c._13(16777216,null,null,1,null,e)),c._17(16384,null,0,y.l,[c._1,c.X],{ngIf:[0,"ngIf"]},null),(l()(),c._41(null,["\n "])),(l()(),c._13(16777216,null,null,1,null,i)),c._17(16384,null,0,y.l,[c._1,c.X],{ngIf:[0,"ngIf"]},null),(l()(),c._41(null,["\n "])),(l()(),c._41(null,["\n "])),(l()(),c._41(null,["\n"])),(l()(),c._41(null,["\n"]))],function(l,n){var u=n.component;l(n,5,0,u.testForm);l(n,56,0,"signature");l(n,58,0,"signature"),l(n,63,0,u.signatureControl.hasError("isArray")),l(n,66,0,u.signatureControl.hasError("consistOfArrays")),l(n,69,0,u.signatureControl.hasError("consistOfObjects")),l(n,72,0,u.signatureControl.hasError("minLines")),l(n,75,0,u.signatureControl.hasError("minPointsInNLines"))},function(l,n){var u=n.component;l(n,3,0,c._33(n,7).ngClassUntouched,c._33(n,7).ngClassTouched,c._33(n,7).ngClassPristine,c._33(n,7).ngClassDirty,c._33(n,7).ngClassValid,c._33(n,7).ngClassInvalid,c._33(n,7).ngClassPending),l(n,49,0,c._42(n,49,0,c._33(n,50).transform(u.signatureControl.value))),l(n,55,0,c._33(n,60).ngClassUntouched,c._33(n,60).ngClassTouched,c._33(n,60).ngClassPristine,c._33(n,60).ngClassDirty,c._33(n,60).ngClassValid,c._33(n,60).ngClassInvalid,c._33(n,60).ngClassPending)})}function a(l){return c._43(0,[(l()(),c._19(0,null,null,1,"app-signature-pad-control-validation",[],null,null,null,s,b)),c._17(114688,null,0,d,[g.d],null,null)],function(l,n){l(n,1,0)},null)}Object.defineProperty(n,"__esModule",{value:!0});var c=u("/oeL"),_=function(){function l(){}return l}(),g=u("bm2B"),f=u("yprN"),d=function(){function l(l){this.fb=l}return l.prototype.ngOnInit=function(){this.testForm=this.fb.group({signature:["",[f.e,f.c,f.d,Object(f.f)(2),Object(f.g)(4,1)]]}),this.signatureControl=this.testForm.get("signature")},l.prototype.assignValidSignature=function(){this.signatureControl.setValue([[{x:531.328125,y:130,time:1506167092932,color:"red"},{x:431.328125,y:100,time:1506167093932,color:"red"}],[{x:131.328125,y:30,time:1506167094932,color:"red"},{x:231.328125,y:50,time:1506167095932,color:"red"},{x:31.328125,y:10,time:1506167096932,color:"red"},{x:61.328125,y:110,time:1506167097932,color:"red"}]])},l.prototype.assignNonArray=function(){this.signatureControl.setValue("thisIsNoArray")},l.prototype.assignArrayOfNonArrays=function(){this.signatureControl.setValue(["thisIsNoArray"])},l.prototype.assignArrayArraysOfNonObjects=function(){this.signatureControl.setValue([["thisIsNoObject"]])},l.prototype.assignSignatureOf1Line=function(){this.signatureControl.setValue([[{x:131.328125,y:30,time:1506167094932,color:"red"},{x:231.328125,y:50,time:1506167095932,color:"red"},{x:31.328125,y:10,time:1506167096932,color:"red"},{x:61.328125,y:110,time:1506167097932,color:"red"}]])},l.prototype.assignSignatureOf2LineEach2Points=function(){this.signatureControl.setValue([[{x:531.328125,y:130,time:1506167092932,color:"red"},{x:431.328125,y:100,time:1506167093932,color:"red"}],[{x:131.328125,y:30,time:1506167094932,color:"red"},{x:231.328125,y:50,time:1506167095932,color:"red"}]])},l.ctorParameters=function(){return[{type:g.d}]},l}(),y=u("qbdv"),m=u("yID4"),p=[],b=c._16({encapsulation:2,styles:p,data:{}}),h=c._14("app-signature-pad-control-validation",d,a,{},{},[]),v=u("BkNc"),C=function(){function l(){}return l}(),x=u("T2Au");u.d(n,"SignaturePadControlValidationModuleNgFactory",function(){return O});var O=c._15(_,[],function(l){return c._30([c._31(512,c.l,c._11,[[8,[h]],[3,c.l],c.F]),c._31(4608,y.n,y.m,[c.B]),c._31(4608,g.d,g.d,[]),c._31(4608,g.o,g.o,[]),c._31(4608,f.l,f.l,[]),c._31(512,y.c,y.c,[]),c._31(512,v.n,v.n,[[2,v.s],[2,v.k]]),c._31(512,C,C,[]),c._31(512,g.l,g.l,[]),c._31(512,g.k,g.k,[]),c._31(512,x.a,x.a,[]),c._31(512,f.a,f.a,[]),c._31(512,_,_,[]),c._31(1024,v.i,function(){return[[{path:"",component:d}]]},[])])})}}); -------------------------------------------------------------------------------- /src/libs/angular-signature-pad/src/components/signature-pad/signature-pad.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AfterViewInit, 3 | Component, 4 | ElementRef, 5 | EventEmitter, 6 | Inject, 7 | Input, 8 | OnChanges, 9 | OnInit, 10 | Optional, 11 | Output, 12 | Renderer2, 13 | SimpleChanges, 14 | ViewChild 15 | } from '@angular/core'; 16 | import SignaturePad from 'signature_pad'; 17 | import {ISignaturePadConfig} from '../../interfaces/signature-pad-config.interface'; 18 | import {GlobalSignaturePadConfig} from '../../tokens/global-config.token'; 19 | 20 | @Component({ 21 | selector: 'signature-pad', 22 | template: ` 23 | 29 | 30 | ` 31 | }) 32 | export class SignaturePadComponent implements OnInit, OnChanges, AfterViewInit { 33 | 34 | protected container: HTMLElement; 35 | 36 | @ViewChild('signatureCanvas') 37 | protected canvasRef: ElementRef; 38 | protected canvas: HTMLCanvasElement; 39 | 40 | protected signaturePad; 41 | 42 | protected value: any = []; 43 | 44 | @Output() 45 | protected valueChange: EventEmitter = new EventEmitter(); 46 | 47 | public disabled: boolean; 48 | public focus: boolean; 49 | 50 | @Input() 51 | protected config: ISignaturePadConfig; 52 | 53 | onEndWrapper = (value) => { 54 | // configurable onEnd 55 | if (this.isObject(this.config) 56 | && 'onEnd' in this.config 57 | && typeof this.config.onEnd === 'function') { 58 | this.config.onEnd(value); 59 | } 60 | 61 | // default onEnd function 62 | // sync form control 63 | this.handleInput(this.signaturePad.toData()); 64 | } 65 | 66 | onBeginWrapper = (value) => { 67 | // configurable onBegin 68 | if (this.isObject(this.config) 69 | && 'onBegin' in this.config 70 | && typeof this.config.onBegin === 'function') { 71 | this.config.onBegin(value); 72 | } 73 | 74 | // default onBegin function here 75 | } 76 | 77 | constructor( 78 | protected renderer: Renderer2, 79 | @Optional() @Inject(GlobalSignaturePadConfig) private defaultConfig?: ISignaturePadConfig 80 | ) { 81 | } 82 | 83 | ngOnChanges(changes: SimpleChanges): void { 84 | if ('config' in changes) { 85 | this.updateConfig(changes.config.currentValue); 86 | } 87 | } 88 | 89 | ngOnInit() { 90 | this.initializeSignaturePad(); 91 | } 92 | 93 | ngAfterViewInit(): void { 94 | // listen to focus 95 | this.renderer.listen(this.canvas, 'focus', ($event) => { 96 | this.handleFocus(true); 97 | }); 98 | 99 | // listen to blur 100 | this.renderer.listen(this.canvas, 'blur', ($event) => { 101 | this.handleFocus(false); 102 | }); 103 | 104 | // handle resize 105 | this.resizeSignaturePad(); 106 | this.renderer.listen('window', 'resize', ($event) => { 107 | this.resizeSignaturePad(); 108 | }); 109 | } 110 | 111 | getValue(): number { 112 | return this.value; 113 | } 114 | 115 | setValue(signatureData: any) { 116 | if (signatureData && signatureData.constructor === [].constructor) { 117 | this.value = [...signatureData]; 118 | } else { 119 | this.value = null; 120 | } 121 | 122 | this.valueChange.next(this.value); 123 | } 124 | 125 | setDisabledState(isDisabled: boolean): void { 126 | this.disabled = isDisabled; 127 | this.renderViewDisabled(); 128 | } 129 | 130 | clear() { 131 | this.signaturePad.clear(); 132 | this.setValue(null); 133 | } 134 | 135 | resizeSignaturePad = (): void => { 136 | if (this.canvas) { 137 | 138 | this.resizeCanvas(); 139 | 140 | // When the width or height of a canvas gets modified, 141 | // it will be automatically cleared by the browser. 142 | // How ever the data of the signature are still stores in the model value => this.value. 143 | // Because of this we have to reassign the value from this.value to the signaturePad. 144 | this.renderViewValue(this.value); 145 | } 146 | } 147 | 148 | /* 149 | * Depending on the compositionMode and the composing state it 150 | */ 151 | protected handleInput(signatureData: any): void { 152 | this.setValue(signatureData); 153 | } 154 | 155 | /* 156 | * Sets the internal focus state and renders it to the view 157 | */ 158 | public handleFocus(isFocus: boolean): void { 159 | this.focus = isFocus; 160 | this.renderViewFocus(); 161 | } 162 | 163 | // render functions ================================================================== 164 | 165 | renderViewDisabled() { 166 | this.renderer.setProperty(this.canvas, 'disabled', this.disabled); 167 | 168 | if (this.disabled) { 169 | this.renderer.addClass(this.canvas, 'disabled'); 170 | } else { 171 | this.renderer.removeClass(this.canvas, 'disabled'); 172 | } 173 | } 174 | 175 | renderViewFocus(): void { 176 | this.renderer.setProperty(this.canvas, 'focus', this.focus); 177 | 178 | if (this.focus) { 179 | this.renderer.addClass(this.canvas, 'focus'); 180 | } else { 181 | this.renderer.removeClass(this.canvas, 'focus'); 182 | } 183 | } 184 | 185 | renderViewValue(signatureData: any) { 186 | if (signatureData && signatureData.constructor === [].constructor) { 187 | this.signaturePad.fromData([...signatureData]); 188 | } else { 189 | this.signaturePad.clear(); 190 | } 191 | } 192 | 193 | 194 | // helper ================================================================== 195 | 196 | protected updateConfig(config?: ISignaturePadConfig): void { 197 | 198 | if (!config || config.constructor !== {}.constructor || !this.signaturePad) { 199 | return; 200 | } 201 | 202 | if ('dotSize' in config && config.dotSize) { 203 | this.signaturePad.dotSize = config.dotSize; 204 | } 205 | 206 | if ('minWidth' in config && config.minWidth >= 0) { 207 | this.signaturePad.minWidth = config.minWidth; 208 | console.log('minWidth', this.signaturePad.minWidth, config.minWidth); 209 | } 210 | 211 | if ('maxWidth' in config && config.maxWidth >= 0) { 212 | this.signaturePad.maxWidth = config.maxWidth; 213 | } 214 | 215 | if ('throttle' in config && config.throttle >= 0) { 216 | this.signaturePad.throttle = config.throttle; 217 | } 218 | 219 | if ('backgroundColor' in config && config.backgroundColor) { 220 | this.signaturePad.backgroundColor = config.backgroundColor; 221 | this.resizeSignaturePad(); 222 | } 223 | 224 | if ('penColor' in config && config.penColor) { 225 | this.signaturePad.penColor = config.penColor; 226 | } 227 | 228 | if ('velocityFilterWeight' in config && config.velocityFilterWeight >= 0) { 229 | this.signaturePad.velocityFilterWeight = config.velocityFilterWeight; 230 | } 231 | 232 | // callbacks are registered when creating signaturePad instance in initializeSignaturePad 233 | // onBegin 234 | // onEnd 235 | 236 | } 237 | 238 | protected resizeCanvas() { 239 | interface ICssWidthHeight {top: number; bottom: number; left: number; right: number; fullHeight: number; fullWidth: number; 240 | } 241 | 242 | // When zoomed out to less than 100%, for some very strange reason, 243 | // some browsers report devicePixelRatio as less than 1 244 | // and only part of the canvas is cleared then. 245 | // So we will have at least 1 as ration. 246 | const ratio = 1; // @TODO fix offset on ratios > 1. => Math.max(window.devicePixelRatio || 1, 1); 247 | 248 | // information needed to calculate the available width and height 249 | const canvasStyles = window.getComputedStyle(this.canvas, null); 250 | const canvasBorder: ICssWidthHeight = {} as ICssWidthHeight; 251 | canvasBorder.top = parseInt(canvasStyles.borderTopWidth, null) || 0; 252 | canvasBorder.bottom = parseInt(canvasStyles.borderBottomWidth, null) || 0; 253 | canvasBorder.left = parseInt(canvasStyles.borderLeftWidth, null) || 0; 254 | canvasBorder.right = parseInt(canvasStyles.borderRightWidth, null) || 0; 255 | canvasBorder.fullHeight = canvasBorder.top + canvasBorder.bottom; 256 | canvasBorder.fullWidth = canvasBorder.left + canvasBorder.right; 257 | 258 | const containerStyles = window.getComputedStyle(this.container, null); 259 | const parentPadding: ICssWidthHeight = {} as ICssWidthHeight; 260 | parentPadding.top = parseInt(containerStyles.paddingTop, null) || 0; 261 | parentPadding.bottom = parseInt(containerStyles.paddingBottom, null) || 0; 262 | parentPadding.left = parseInt(containerStyles.paddingLeft, null) || 0; 263 | parentPadding.right = parseInt(containerStyles.paddingRight, null) || 0; 264 | parentPadding.fullHeight = parentPadding.top + parentPadding.bottom; 265 | parentPadding.fullWidth = parentPadding.left + parentPadding.right; 266 | 267 | const withToSubtract = parentPadding.fullWidth + canvasBorder.fullWidth; 268 | const heightToSubtract = parentPadding.fullHeight + canvasBorder.fullHeight; 269 | 270 | // resize canvas 271 | 272 | // get most right point of signature 273 | let signatureWidth = 0; 274 | if (this.value && [].constructor === this.value.constructor) { 275 | signatureWidth = this.value 276 | .reduce((concated, arr) => concated.concat(arr), []) 277 | .reduce((mR, segment) => mR < segment.x ? segment.x : mR, 0); 278 | } 279 | 280 | // get most left point of signature 281 | let signatureHeight = 0; 282 | if (this.value && [].constructor === this.value.constructor) { 283 | signatureHeight = this.value 284 | .reduce((concated, arr) => concated.concat(arr), []) 285 | .reduce((mL, segment) => mL < segment.y ? segment.y : mL, 0); 286 | } 287 | 288 | // calc new width and height 289 | const newCanvasWidth = Math.max(this.container.clientWidth, signatureWidth); 290 | const newCanvasHeight = Math.max(this.container.clientHeight, signatureHeight); 291 | 292 | // adopt canvas scales 293 | this.canvas.width = (newCanvasWidth - withToSubtract) * ratio; 294 | this.canvas.height = (newCanvasHeight - heightToSubtract - 6) * ratio; // @TODO find the 6px 295 | this.canvas.getContext('2d').scale(ratio, ratio); 296 | 297 | // adopt show/hide scroll of vertical canvas container 298 | this.container.style.overflowX = 'inherit'; 299 | if (this.canvas.width + withToSubtract > this.container.clientWidth) { 300 | this.container.style.overflowX = 'scroll'; 301 | } 302 | 303 | // adopt show/hide scroll of horizontal canvas container 304 | this.container.style.overflowY = 'inherit'; 305 | if (this.canvas.height > this.container.clientHeight) { 306 | this.container.style.overflowY = 'scroll'; 307 | } 308 | 309 | // When the width or height of a canvas gets modified, 310 | // it will be automatically cleared by the browser. 311 | // So we have to call signaturePad.clear() to make sure 312 | // that signaturePad.isEmpty() returns correct value in this case. 313 | this.signaturePad.clear(); 314 | } 315 | 316 | protected initializeSignaturePad() { 317 | this.canvas = this.canvasRef.nativeElement; 318 | this.container = this.canvas.parentElement; 319 | this.container.className = this.container.className + ' signature-pad'; 320 | 321 | this.signaturePad = new SignaturePad(this.canvas, this.defaultConfig); 322 | // onBegin 323 | this.signaturePad.onBegin = this.onBeginWrapper; 324 | // onEnd 325 | this.signaturePad.onEnd = this.onEndWrapper; 326 | 327 | this.updateConfig(this.config); 328 | } 329 | 330 | protected isObject(val: any) { 331 | const objectConstructor = {}.constructor; 332 | return val && val.constructor === objectConstructor; 333 | } 334 | 335 | } 336 | -------------------------------------------------------------------------------- /docs/2.eec02abcb26b78e315fd.chunk.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([2],{LQIJ:function(l,n,u){"use strict";function t(l){return c._43(0,[(l()(),c._19(0,null,null,4,"li",[["class","text-white"]],null,null,null,null,null)),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,1,"b",[],null,null,null,null,null)),(l()(),c._41(null,["",""])),(l()(),c._41(null,["\n "]))],null,function(l,n){l(n,3,0,n.context.$implicit.name)})}function o(l){return c._43(0,[(l()(),c._19(0,null,null,4,"ul",[],[[8,"className",0]],null,null,null,null)),(l()(),c._41(null,["\n "])),(l()(),c._13(16777216,null,null,1,null,t)),c._17(802816,null,0,v.k,[c._1,c.X,c.z],{ngForOf:[0,"ngForOf"]},null),(l()(),c._41(null,["\n "]))],function(l,n){l(n,3,0,n.component.getErrors())},function(l,n){var u=n.component;l(n,0,0,c._22(1,"card-block ","bg-"+u.errorColor,""))})}function r(l){return c._43(0,[(l()(),c._19(0,null,null,112,"div",[["class","card"]],null,null,null,null,null)),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,6,"div",[["class","card-header"]],null,null,null,null,null)),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,3,"h4",[],null,null,null,null,null)),(l()(),c._41(null,["\n "])),c._32(null,0),(l()(),c._41(null,["\n "])),(l()(),c._41(null,["\n "])),(l()(),c._41(null,["\n\n "])),(l()(),c._13(16777216,null,null,1,null,o)),c._17(16384,null,0,v.l,[c._1,c.X],{ngIf:[0,"ngIf"]},null),(l()(),c._41(null,["\n\n "])),(l()(),c._19(0,null,null,98,"div",[["class","card-block col"]],null,null,null,null,null)),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,95,"div",[["class","row"]],null,null,null,null,null)),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,2,"div",[["class","col-3"]],null,null,null,null,null)),(l()(),c._19(0,null,null,1,"b",[],null,null,null,null,null)),(l()(),c._41(null,["value"])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,5,"div",[["class","col-9 text-primary control-value"]],null,null,null,null,null)),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,2,"b",[],null,null,null,null,null)),(l()(),c._41(null,["",""])),c._35(0,v.f,[]),(l()(),c._41(null,["\n "])),(l()(),c._41(null,["\n\n "])),(l()(),c._19(0,null,null,2,"div",[["class","col-3"]],null,null,null,null,null)),(l()(),c._19(0,null,null,1,"b",[],null,null,null,null,null)),(l()(),c._41(null,["valid"])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,1,"div",[],[[8,"className",0]],null,null,null,null)),(l()(),c._41(null,["\n ","\n "])),(l()(),c._41(null,["\n\n "])),(l()(),c._19(0,null,null,2,"div",[["class","col-3"]],null,null,null,null,null)),(l()(),c._19(0,null,null,1,"b",[],null,null,null,null,null)),(l()(),c._41(null,["invalid"])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,1,"div",[],[[8,"className",0]],null,null,null,null)),(l()(),c._41(null,["\n ","\n "])),(l()(),c._41(null,["\n\n "])),(l()(),c._19(0,null,null,2,"div",[["class","col-3"]],null,null,null,null,null)),(l()(),c._19(0,null,null,1,"b",[],null,null,null,null,null)),(l()(),c._41(null,["status"])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,3,"div",[["class","col-3"]],null,null,null,null,null)),c._17(278528,null,0,v.j,[c.z,c.A,c.o,c.N],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),c._36({"text-success":0,"text-danger":1,"text-info":2}),(l()(),c._41(null,["","\n "])),(l()(),c._41(null,["\n\n "])),(l()(),c._19(0,null,null,2,"div",[["class","col-3"]],null,null,null,null,null)),(l()(),c._19(0,null,null,1,"b",[],null,null,null,null,null)),(l()(),c._41(null,["pending"])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,1,"div",[],[[8,"className",0]],null,null,null,null)),(l()(),c._41(null,["\n ","\n "])),(l()(),c._41(null,["\n\n "])),(l()(),c._19(0,null,null,2,"div",[["class","col-3"]],null,null,null,null,null)),(l()(),c._19(0,null,null,1,"b",[],null,null,null,null,null)),(l()(),c._41(null,["pristine"])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,1,"div",[],[[8,"className",0]],null,null,null,null)),(l()(),c._41(null,["\n ","\n "])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,2,"div",[["class","col-3"]],null,null,null,null,null)),(l()(),c._19(0,null,null,1,"b",[],null,null,null,null,null)),(l()(),c._41(null,["dirty"])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,1,"div",[],[[8,"className",0]],null,null,null,null)),(l()(),c._41(null,["\n ","\n "])),(l()(),c._41(null,["\n\n "])),(l()(),c._19(0,null,null,2,"div",[["class","col-3"]],null,null,null,null,null)),(l()(),c._19(0,null,null,1,"b",[],null,null,null,null,null)),(l()(),c._41(null,["touched"])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,1,"div",[],[[8,"className",0]],null,null,null,null)),(l()(),c._41(null,["\n ","\n "])),(l()(),c._41(null,["\n\n "])),(l()(),c._19(0,null,null,2,"div",[["class","col-3"]],null,null,null,null,null)),(l()(),c._19(0,null,null,1,"b",[],null,null,null,null,null)),(l()(),c._41(null,["untouched"])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,1,"div",[],[[8,"className",0]],null,null,null,null)),(l()(),c._41(null,["\n ","\n "])),(l()(),c._41(null,["\n\n "])),(l()(),c._19(0,null,null,2,"div",[["class","col-3"]],null,null,null,null,null)),(l()(),c._19(0,null,null,1,"b",[],null,null,null,null,null)),(l()(),c._41(null,["focus"])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,1,"div",[],[[8,"className",0]],null,null,null,null)),(l()(),c._41(null,["\n ","\n "])),(l()(),c._41(null,["\n\n "])),(l()(),c._19(0,null,null,2,"div",[["class","col-3"]],null,null,null,null,null)),(l()(),c._19(0,null,null,1,"b",[],null,null,null,null,null)),(l()(),c._41(null,["disabled"])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,1,"div",[],[[8,"className",0]],null,null,null,null)),(l()(),c._41(null,["\n ","\n "])),(l()(),c._41(null,["\n\n "])),(l()(),c._19(0,null,null,2,"div",[["class","col-12"]],null,null,null,null,null)),(l()(),c._19(0,null,null,1,"b",[],null,null,null,null,null)),(l()(),c._41(null,["errors"])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,5,"div",[["class","col-12 text-danger"]],null,null,null,null,null)),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,2,"pre",[],null,null,null,null,null)),(l()(),c._41(null,["",""])),c._35(0,v.f,[]),(l()(),c._41(null,["\n "])),(l()(),c._41(null,["\n\n "])),(l()(),c._41(null,["\n\n "])),(l()(),c._41(null,["\n"])),(l()(),c._41(null,["\n"]))],function(l,n){var u=n.component;l(n,11,0,u.control.errors);l(n,47,0,"col-3",l(n,48,0,"VALID"===u.control.status,"INVALID"===u.control.status,"PENDING"===u.control.status))},function(l,n){var u=n.component;l(n,24,0,c._42(n,24,0,c._33(n,25).transform(u.control.value))),l(n,32,0,c._22(1,"col-3 ",u.control.valid?"text-success":"text-danger","")),l(n,33,0,u.control.valid),l(n,39,0,c._22(1,"col-3 ",u.control.invalid?"text-success":"text-danger","")),l(n,40,0,u.control.invalid),l(n,49,0,u.control.status),l(n,55,0,c._22(1,"col-3 ",u.control.pending?"text-success":"text-danger","")),l(n,56,0,u.control.pending),l(n,62,0,c._22(1,"col-3 ",u.control.pristine?"text-success":"text-danger","")),l(n,63,0,u.control.pristine),l(n,69,0,c._22(1,"col-3 ",u.control.dirty?"text-success":"text-danger","")),l(n,70,0,u.control.dirty),l(n,76,0,c._22(1,"col-3 ",u.control.touched?"text-success":"text-danger","")),l(n,77,0,u.control.touched),l(n,83,0,c._22(1,"col-3 ",u.control.untouched?"text-success":"text-danger","")),l(n,84,0,u.control.untouched),l(n,90,0,c._22(1,"col-3 ",(null==u.control?null:u.control.focus)?"text-success":"text-danger","")),l(n,91,0,null==u.control?null:u.control.focus),l(n,97,0,c._22(1,"col-3 ",u.control.disabled?"text-success":"text-danger","")),l(n,98,0,u.control.disabled),l(n,107,0,c._42(n,107,0,c._33(n,108).transform(u.control.errors)))})}function _(l){return c._43(0,[(l()(),c._19(0,null,null,1,"control-state",[],null,null,null,r,b)),c._17(638976,null,0,p,[],null,null)],function(l,n){l(n,1,0)},null)}function e(l){return c._43(0,[(l()(),c._19(0,null,null,1,"h1",[],null,null,null,null,null)),(l()(),c._41(null,["\n SignaturePad Control\n"])),(l()(),c._41(null,["\n\n"])),(l()(),c._19(0,null,null,36,"div",[["class","row"]],null,null,null,null,null)),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,26,"div",[["class","col"]],null,null,null,null,null)),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,23,"form",[["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,u){var t=!0;if("submit"===n){t=!1!==c._33(l,9).onSubmit(u)&&t}if("reset"===n){t=!1!==c._33(l,9).onReset()&&t}return t},null,null)),c._17(16384,null,0,a.n,[],null,null),c._17(540672,null,0,a.f,[[8,null],[8,null]],{form:[0,"form"]},null),c._38(2048,null,a.b,null,[a.f]),c._17(16384,null,0,a.j,[a.b],null,null),(l()(),c._41(null,["\n\n "])),(l()(),c._19(0,null,null,5,"signature-pad-control",[["formControlName","signature"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],null,null,d.f,d.b)),c._17(4833280,[["sigPad",4]],0,g.i,[c.O,[3,a.b],[2,g.b]],{formControlName:[0,"formControlName"]},null),c._38(1024,null,a.g,function(l){return[l]},[g.i]),c._17(671744,null,0,a.e,[[3,a.b],[8,null],[8,null],[2,a.g]],{name:[0,"name"]},null),c._38(2048,null,a.h,null,[a.e]),c._17(16384,null,0,a.i,[a.h],null,null),(l()(),c._41(null,["\n\n "])),(l()(),c._19(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),c._41(null,["\n\n "])),(l()(),c._19(0,null,null,1,"button",[["class","btn btn-outline-secondary"],["type","reset"]],null,null,null,null,null)),(l()(),c._41(null,["Reset Form"])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,1,"button",[["class","btn btn-outline-secondary"],["type","button"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==c._33(l,14).clear()&&t}return t},null,null)),(l()(),c._41(null,["Clear\n Component\n "])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,1,"button",[["class","btn btn-outline-secondary"],["type","button"]],null,[[null,"click"]],function(l,n,u){var t=!0,o=l.component;if("click"===n){t=!1!==o.fill()&&t}return t},null,null)),(l()(),c._41(null,["Fill"])),(l()(),c._41(null,["\n\n "])),(l()(),c._41(null,["\n "])),(l()(),c._41(null,["\n "])),(l()(),c._19(0,null,null,5,"div",[["class","col"]],null,null,null,null,null)),(l()(),c._41(null,["\n\n "])),(l()(),c._19(0,null,null,2,"control-state",[],null,null,null,r,b)),c._17(638976,null,0,p,[],{control:[0,"control"]},null),(l()(),c._41(0,["\n SignaturePad Control State\n "])),(l()(),c._41(null,["\n\n "])),(l()(),c._41(null,["\n"])),(l()(),c._41(null,["\n"])),(l()(),c._19(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),c._41(null,["\n"])),(l()(),c._19(0,null,null,1,"b",[],null,null,null,null,null)),(l()(),c._41(null,["Component value:"])),(l()(),c._41(null,["\n"])),(l()(),c._19(0,null,null,2,"pre",[],null,null,null,null,null)),(l()(),c._41(null,["",""])),c._35(0,v.f,[]),(l()(),c._41(null,["\n"]))],function(l,n){var u=n.component;l(n,9,0,u.testForm);l(n,14,0,"signature");l(n,16,0,"signature"),l(n,36,0,u.testForm.get("signature"))},function(l,n){l(n,7,0,c._33(n,11).ngClassUntouched,c._33(n,11).ngClassTouched,c._33(n,11).ngClassPristine,c._33(n,11).ngClassDirty,c._33(n,11).ngClassValid,c._33(n,11).ngClassInvalid,c._33(n,11).ngClassPending),l(n,13,0,c._33(n,18).ngClassUntouched,c._33(n,18).ngClassTouched,c._33(n,18).ngClassPristine,c._33(n,18).ngClassDirty,c._33(n,18).ngClassValid,c._33(n,18).ngClassInvalid,c._33(n,18).ngClassPending),l(n,47,0,c._42(n,47,0,c._33(n,48).transform(c._33(n,14).value)))})}function s(l){return c._43(0,[(l()(),c._19(0,null,null,1,"app-signature-pad-control",[],null,null,null,e,C)),c._17(114688,null,0,f,[a.d],null,null)],function(l,n){l(n,1,0)},null)}Object.defineProperty(n,"__esModule",{value:!0});var c=u("/oeL"),i=function(){function l(){}return l}(),a=u("bm2B"),d=u("yID4"),g=u("yprN"),f=function(){function l(l){this.fb=l,this.initialSignature=function(){return[[{x:11.328125,y:30,time:1506167092932,color:"red"}]]},this.testForm=this.fb.group({signature:[this.initialSignature()]})}return l.prototype.fill=function(){this.testForm.get("signature").setValue(this.initialSignature())},l.prototype.ngOnInit=function(){},l.ctorParameters=function(){return[{type:a.d}]},l}(),v=u("qbdv"),p=function(){function l(){this.errorColor="danger"}return l.prototype.ngOnChanges=function(l){console.log(l),"errorColor"in l&&(this.errorColor=l.errorColor.currentValue||"danger")},l.prototype.ngOnInit=function(){},l.prototype.getErrors=function(){var l=this;return Object.keys(this.control.errors).map(function(n){return{name:n,value:l.control.errors[n]}})},l}(),m=["ul[_ngcontent-%COMP%] {\n list-style: none;\n margin-bottom: 0;\n }\n\n .control-value[_ngcontent-%COMP%] {\n max-height: 200px;\n overflow-y: scroll;\n }"],b=c._16({encapsulation:0,styles:m,data:{}}),h=(c._14("control-state",p,_,{control:"control",errorColor:"errorColor"},{},["*"]),[]),C=c._16({encapsulation:2,styles:h,data:{}}),y=c._14("app-signature-pad-control",f,s,{},{},[]),x=u("BkNc"),N=function(){function l(){}return l}(),k=u("T2Au");u.d(n,"SignaturePadControlModuleNgFactory",function(){return P});var P=c._15(i,[],function(l){return c._30([c._31(512,c.l,c._11,[[8,[y]],[3,c.l],c.F]),c._31(4608,v.n,v.m,[c.B]),c._31(4608,a.d,a.d,[]),c._31(4608,a.o,a.o,[]),c._31(4608,g.l,g.l,[]),c._31(512,v.c,v.c,[]),c._31(512,x.n,x.n,[[2,x.s],[2,x.k]]),c._31(512,N,N,[]),c._31(512,a.l,a.l,[]),c._31(512,a.k,a.k,[]),c._31(512,k.a,k.a,[]),c._31(512,g.a,g.a,[]),c._31(512,i,i,[]),c._31(1024,x.i,function(){return[[{path:"",component:f}]]},[])])})}}); -------------------------------------------------------------------------------- /docs/main.18646811113195bff36f.bundle.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([7],{0:function(l,n,u){l.exports=u("cDNt")},T2Au:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=function(){function l(){}return l}()},cDNt:function(l,n,u){"use strict";function t(l){return r._43(0,[(l()(),r._19(0,null,null,1,"h1",[],null,null,null,null,null)),(l()(),r._41(null,["\n Basic Implementation of the angular signature pad library\n"])),(l()(),r._41(null,["\n\n"])),(l()(),r._19(0,null,null,37,"div",[["class","row"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"submit"],[null,"reset"]],function(l,n,u){var t=!0;if("submit"===n){t=!1!==r._33(l,4).onSubmit(u)&&t}if("reset"===n){t=!1!==r._33(l,4).onReset()&&t}return t},null,null)),r._17(540672,null,0,s.f,[[8,null],[8,null]],{form:[0,"form"]},null),r._38(2048,null,s.b,null,[s.f]),r._17(16384,null,0,s.j,[s.b],null,null),(l()(),r._41(null,["\n\n "])),(l()(),r._19(0,null,null,11,"div",[["class","form-group col"]],null,null,null,null,null)),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,1,"label",[["class","form-control-label"]],null,null,null,null,null)),(l()(),r._41(null,["Firstname"])),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,5,"input",[["autocomplete","false"],["class","form-control"],["formControlName","firstName"],["name","firstName"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0;if("input"===n){t=!1!==r._33(l,14)._handleInput(u.target.value)&&t}if("blur"===n){t=!1!==r._33(l,14).onTouched()&&t}if("compositionstart"===n){t=!1!==r._33(l,14)._compositionStart()&&t}if("compositionend"===n){t=!1!==r._33(l,14)._compositionEnd(u.target.value)&&t}return t},null,null)),r._17(16384,null,0,s.c,[r.O,r.o,[2,s.a]],null,null),r._38(1024,null,s.g,function(l){return[l]},[s.c]),r._17(671744,null,0,s.e,[[3,s.b],[8,null],[8,null],[2,s.g]],{name:[0,"name"]},null),r._38(2048,null,s.h,null,[s.e]),r._17(16384,null,0,s.i,[s.h],null,null),(l()(),r._41(null,["\n "])),(l()(),r._41(null,["\n\n "])),(l()(),r._19(0,null,null,11,"div",[["class","form-group col"]],null,null,null,null,null)),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,1,"label",[["class","form-control-label"]],null,null,null,null,null)),(l()(),r._41(null,["Lastname"])),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,5,"input",[["autocomplete","false"],["class","form-control"],["formControlName","lastName"],["name","lastName"],["type","text"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0;if("input"===n){t=!1!==r._33(l,27)._handleInput(u.target.value)&&t}if("blur"===n){t=!1!==r._33(l,27).onTouched()&&t}if("compositionstart"===n){t=!1!==r._33(l,27)._compositionStart()&&t}if("compositionend"===n){t=!1!==r._33(l,27)._compositionEnd(u.target.value)&&t}return t},null,null)),r._17(16384,null,0,s.c,[r.O,r.o,[2,s.a]],null,null),r._38(1024,null,s.g,function(l){return[l]},[s.c]),r._17(671744,null,0,s.e,[[3,s.b],[8,null],[8,null],[2,s.g]],{name:[0,"name"]},null),r._38(2048,null,s.h,null,[s.e]),r._17(16384,null,0,s.i,[s.h],null,null),(l()(),r._41(null,["\n "])),(l()(),r._41(null,["\n\n "])),(l()(),r._19(0,null,null,5,"signature-pad-card",[["class","form-group col-12"],["formControlName","signature"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],null,null,d.g,d.c)),r._17(4833280,null,0,g.j,[r.O,[3,s.b],[2,g.b]],{formControlName:[0,"formControlName"]},null),r._38(1024,null,s.g,function(l){return[l]},[g.j]),r._17(671744,null,0,s.e,[[3,s.b],[8,null],[8,null],[2,s.g]],{name:[0,"name"]},null),r._38(2048,null,s.h,null,[s.e]),r._17(16384,null,0,s.i,[s.h],null,null),(l()(),r._41(null,["\n"])),(l()(),r._41(null,["\n"]))],function(l,n){l(n,4,0,n.component.testForm);l(n,16,0,"firstName");l(n,29,0,"lastName");l(n,35,0,"signature");l(n,37,0,"signature")},function(l,n){l(n,3,0,r._33(n,6).ngClassUntouched,r._33(n,6).ngClassTouched,r._33(n,6).ngClassPristine,r._33(n,6).ngClassDirty,r._33(n,6).ngClassValid,r._33(n,6).ngClassInvalid,r._33(n,6).ngClassPending),l(n,13,0,r._33(n,18).ngClassUntouched,r._33(n,18).ngClassTouched,r._33(n,18).ngClassPristine,r._33(n,18).ngClassDirty,r._33(n,18).ngClassValid,r._33(n,18).ngClassInvalid,r._33(n,18).ngClassPending),l(n,26,0,r._33(n,31).ngClassUntouched,r._33(n,31).ngClassTouched,r._33(n,31).ngClassPristine,r._33(n,31).ngClassDirty,r._33(n,31).ngClassValid,r._33(n,31).ngClassInvalid,r._33(n,31).ngClassPending),l(n,34,0,r._33(n,39).ngClassUntouched,r._33(n,39).ngClassTouched,r._33(n,39).ngClassPristine,r._33(n,39).ngClassDirty,r._33(n,39).ngClassValid,r._33(n,39).ngClassInvalid,r._33(n,39).ngClassPending)})}function a(l){return r._43(0,[(l()(),r._19(0,null,null,1,"app-demo",[],null,null,null,t,m)),r._17(114688,null,0,p,[s.d],null,null)],function(l,n){l(n,1,0)},null)}function i(l){return r._43(0,[(l()(),r._19(0,null,null,106,"div",[["class","container-fluid"],["id","main-container"]],null,null,null,null,null)),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,94,"nav",[["class","navbar navbar-expand-md navbar-dark fixed-top bg-dark"],["id","main-menu"]],null,null,null,null,null)),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,1,"a",[["class","navbar-brand"],["href","#"]],null,null,null,null,null)),(l()(),r._41(null,["Angular Signature Pad"])),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,3,"button",[["aria-controls","mainNavbar"],["aria-expanded","false"],["aria-label","Toggle navigation"],["class","navbar-toggler d-lg-none"],["data-target","#mainNavbar"],["data-toggle","collapse"],["type","button"]],null,[[null,"click"]],function(l,n,u){var t=!0,a=l.component;if("click"===n){t=!1!==a.toggleNav()&&t}return t},null,null)),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,0,"span",[["class","navbar-toggler-icon"]],null,null,null,null,null)),(l()(),r._41(null,["\n "])),(l()(),r._41(null,["\n\n "])),(l()(),r._19(0,null,null,83,"div",[["class"," navbar-collapse"],["id","mainNavbar"]],null,null,null,null,null)),r._17(278528,null,0,k.j,[r.z,r.A,r.o,r.N],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),r._36({collapse:0}),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,78,"ul",[["class","navbar-nav mr-auto"]],null,null,null,null,null)),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,9,"li",[["class","nav-item"],["routerLinkActive","active"]],null,null,null,null,null)),r._17(1720320,null,2,h.l,[h.k,r.o,r.O,r.i],{routerLinkActive:[0,"routerLinkActive"]},null),r._39(603979776,1,{links:1}),r._39(603979776,2,{linksWithHrefs:1}),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,3,"a",[["class","nav-link"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0,a=l.component;if("click"===n){t=!1!==r._33(l,24).onClick(u.button,u.ctrlKey,u.metaKey,u.shiftKey)&&t}if("click"===n){t=!1!==a.toggleNav(!0)&&t}return t},null,null)),r._17(671744,[[2,4]],0,h.m,[h.k,h.a,k.i],{routerLink:[0,"routerLink"]},null),r._34(1),(l()(),r._41(null,["Demo"])),(l()(),r._41(null,["\n "])),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,9,"li",[["class","nav-item"],["routerLinkActive","active"]],null,null,null,null,null)),r._17(1720320,null,2,h.l,[h.k,r.o,r.O,r.i],{routerLinkActive:[0,"routerLinkActive"]},null),r._39(603979776,3,{links:1}),r._39(603979776,4,{linksWithHrefs:1}),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,3,"a",[["class","nav-link"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0,a=l.component;if("click"===n){t=!1!==r._33(l,35).onClick(u.button,u.ctrlKey,u.metaKey,u.shiftKey)&&t}if("click"===n){t=!1!==a.toggleNav(!0)&&t}return t},null,null)),r._17(671744,[[4,4]],0,h.m,[h.k,h.a,k.i],{routerLink:[0,"routerLink"]},null),r._34(1),(l()(),r._41(null,["SignaturePad"])),(l()(),r._41(null,["\n "])),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,9,"li",[["class","nav-item"],["routerLinkActive","active"]],null,null,null,null,null)),r._17(1720320,null,2,h.l,[h.k,r.o,r.O,r.i],{routerLinkActive:[0,"routerLinkActive"]},null),r._39(603979776,5,{links:1}),r._39(603979776,6,{linksWithHrefs:1}),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,3,"a",[["class","nav-link"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0,a=l.component;if("click"===n){t=!1!==r._33(l,46).onClick(u.button,u.ctrlKey,u.metaKey,u.shiftKey)&&t}if("click"===n){t=!1!==a.toggleNav(!0)&&t}return t},null,null)),r._17(671744,[[6,4]],0,h.m,[h.k,h.a,k.i],{routerLink:[0,"routerLink"]},null),r._34(1),(l()(),r._41(null,["Form Control"])),(l()(),r._41(null,["\n "])),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,9,"li",[["class","nav-item"],["routerLinkActive","active"]],null,null,null,null,null)),r._17(1720320,null,2,h.l,[h.k,r.o,r.O,r.i],{routerLinkActive:[0,"routerLinkActive"]},null),r._39(603979776,7,{links:1}),r._39(603979776,8,{linksWithHrefs:1}),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,3,"a",[["class","nav-link"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0,a=l.component;if("click"===n){t=!1!==r._33(l,57).onClick(u.button,u.ctrlKey,u.metaKey,u.shiftKey)&&t}if("click"===n){t=!1!==a.toggleNav(!0)&&t}return t},null,null)),r._17(671744,[[8,4]],0,h.m,[h.k,h.a,k.i],{routerLink:[0,"routerLink"]},null),r._34(1),(l()(),r._41(null,["Validation"])),(l()(),r._41(null,["\n "])),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,9,"li",[["class","nav-item"],["routerLinkActive","active"]],null,null,null,null,null)),r._17(1720320,null,2,h.l,[h.k,r.o,r.O,r.i],{routerLinkActive:[0,"routerLinkActive"]},null),r._39(603979776,9,{links:1}),r._39(603979776,10,{linksWithHrefs:1}),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,3,"a",[["class","nav-link"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0,a=l.component;if("click"===n){t=!1!==r._33(l,68).onClick(u.button,u.ctrlKey,u.metaKey,u.shiftKey)&&t}if("click"===n){t=!1!==a.toggleNav(!0)&&t}return t},null,null)),r._17(671744,[[10,4]],0,h.m,[h.k,h.a,k.i],{routerLink:[0,"routerLink"]},null),r._34(1),(l()(),r._41(null,["Configuration"])),(l()(),r._41(null,["\n "])),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,9,"li",[["class","nav-item"],["routerLinkActive","active"]],null,null,null,null,null)),r._17(1720320,null,2,h.l,[h.k,r.o,r.O,r.i],{routerLinkActive:[0,"routerLinkActive"]},null),r._39(603979776,11,{links:1}),r._39(603979776,12,{linksWithHrefs:1}),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,3,"a",[["class","nav-link"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0,a=l.component;if("click"===n){t=!1!==r._33(l,79).onClick(u.button,u.ctrlKey,u.metaKey,u.shiftKey)&&t}if("click"===n){t=!1!==a.toggleNav(!0)&&t}return t},null,null)),r._17(671744,[[12,4]],0,h.m,[h.k,h.a,k.i],{routerLink:[0,"routerLink"]},null),r._34(1),(l()(),r._41(null,["SignaturePad Card"])),(l()(),r._41(null,["\n "])),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,9,"li",[["class","nav-item"],["routerLinkActive","active"]],null,null,null,null,null)),r._17(1720320,null,2,h.l,[h.k,r.o,r.O,r.i],{routerLinkActive:[0,"routerLinkActive"]},null),r._39(603979776,13,{links:1}),r._39(603979776,14,{linksWithHrefs:1}),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,3,"a",[["class","nav-link"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0,a=l.component;if("click"===n){t=!1!==r._33(l,90).onClick(u.button,u.ctrlKey,u.metaKey,u.shiftKey)&&t}if("click"===n){t=!1!==a.toggleNav(!0)&&t}return t},null,null)),r._17(671744,[[14,4]],0,h.m,[h.k,h.a,k.i],{routerLink:[0,"routerLink"]},null),r._34(1),(l()(),r._41(null,["SignaturePad Card Group"])),(l()(),r._41(null,["\n "])),(l()(),r._41(null,["\n "])),(l()(),r._41(null,["\n "])),(l()(),r._41(null,["\n "])),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,7,"div",[["class","row"],["id","main-content"]],null,null,null,null,null)),(l()(),r._41(null,["\n "])),(l()(),r._19(0,null,null,4,"main",[["class","col"],["id","main-"]],null,null,null,null,null)),(l()(),r._41(null,["\n "])),(l()(),r._19(16777216,null,null,1,"router-outlet",[],null,null,null,null,null)),r._17(212992,null,0,h.o,[h.b,r._1,r.l,[8,null],r.i],null,null),(l()(),r._41(null,["\n "])),(l()(),r._41(null,["\n "])),(l()(),r._41(null,["\n"])),(l()(),r._41(null,["\n"]))],function(l,n){l(n,13,0," navbar-collapse",l(n,14,0,n.component.navBarCollapsed));l(n,19,0,"active"),l(n,24,0,l(n,25,0,"demo"));l(n,30,0,"active"),l(n,35,0,l(n,36,0,"signature-pad"));l(n,41,0,"active"),l(n,46,0,l(n,47,0,"signature-pad-control"));l(n,52,0,"active"),l(n,57,0,l(n,58,0,"signature-pad-control-validation"));l(n,63,0,"active"),l(n,68,0,l(n,69,0,"signature-pad-configuration"));l(n,74,0,"active"),l(n,79,0,l(n,80,0,"signature-pad-card"));l(n,85,0,"active"),l(n,90,0,l(n,91,0,"signature-pad-card-group")),l(n,103,0)},function(l,n){l(n,23,0,r._33(n,24).target,r._33(n,24).href),l(n,34,0,r._33(n,35).target,r._33(n,35).href),l(n,45,0,r._33(n,46).target,r._33(n,46).href),l(n,56,0,r._33(n,57).target,r._33(n,57).href),l(n,67,0,r._33(n,68).target,r._33(n,68).href),l(n,78,0,r._33(n,79).target,r._33(n,79).href),l(n,89,0,r._33(n,90).target,r._33(n,90).href)})}function e(l){return r._43(0,[(l()(),r._19(0,null,null,1,"app-root",[],null,null,null,i,C)),r._17(49152,null,0,_,[],null,null)],null,null)}Object.defineProperty(n,"__esModule",{value:!0});var r=u("/oeL"),o={production:!0},c=function(){function l(){}return l}(),_=function(){function l(){this.navBarCollapsed=!0}return l.prototype.toggleNav=function(l){this.navBarCollapsed=!!l||!this.navBarCollapsed},l.ctorParameters=function(){return[]},l}(),s=u("bm2B"),d=u("yID4"),g=u("yprN"),p=function(){function l(l){this.fb=l}return l.prototype.ngOnInit=function(){this.testForm=this.fb.group({firstName:[],lastName:[],signature:[[]]})},l.ctorParameters=function(){return[{type:s.d}]},l}(),f=[],m=r._16({encapsulation:2,styles:f,data:{}}),v=r._14("app-demo",p,a,{},{},[]),k=u("qbdv"),h=u("BkNc"),b=[],C=r._16({encapsulation:2,styles:b,data:{}}),y=r._14("app-root",_,e,{},{},[]),L=u("fc+i"),N=u("XKz0"),A=function(){function l(){}return l}(),K=u("T2Au"),P=function(){function l(){}return l.forRoot=function(){return{ngModule:l,providers:[]}},l}(),j=function(){function l(){}return l}(),O=function(){function l(){}return l}(),S=r._15(c,[_],function(l){return r._30([r._31(512,r.l,r._11,[[8,[v,y]],[3,r.l],r.F]),r._31(5120,r.B,r._29,[[3,r.B]]),r._31(4608,k.n,k.m,[r.B]),r._31(5120,r.c,r._20,[]),r._31(5120,r.z,r._26,[]),r._31(5120,r.A,r._27,[]),r._31(4608,L.b,L.s,[k.d]),r._31(6144,r.R,null,[L.b]),r._31(4608,L.e,L.f,[]),r._31(5120,L.c,function(l,n,u,t){return[new L.k(l),new L.o(n),new L.n(u,t)]},[k.d,k.d,k.d,L.e]),r._31(4608,L.d,L.d,[L.c,r.H]),r._31(135680,L.m,L.m,[k.d]),r._31(4608,L.l,L.l,[L.d,L.m]),r._31(6144,r.P,null,[L.l]),r._31(6144,L.p,null,[L.m]),r._31(4608,r.Y,r.Y,[r.H]),r._31(4608,L.g,L.g,[k.d]),r._31(4608,L.i,L.i,[k.d]),r._31(5120,h.a,h.x,[h.k]),r._31(4608,h.d,h.d,[]),r._31(6144,h.f,null,[h.d]),r._31(135680,h.p,h.p,[h.k,r.E,r.j,r.x,h.f]),r._31(4608,h.e,h.e,[]),r._31(5120,h.h,h.A,[h.y]),r._31(5120,r.b,function(l){return[l]},[h.h]),r._31(4608,N.h,N.m,[k.d,r.K,N.k]),r._31(4608,N.n,N.n,[N.h,N.l]),r._31(5120,N.a,function(l){return[l]},[N.n]),r._31(4608,N.j,N.j,[]),r._31(6144,N.i,null,[N.j]),r._31(4608,N.g,N.g,[N.i]),r._31(6144,N.b,null,[N.g]),r._31(5120,N.f,N.o,[N.b,[2,N.a]]),r._31(4608,N.c,N.c,[N.f]),r._31(4608,s.d,s.d,[]),r._31(4608,s.o,s.o,[]),r._31(4608,g.l,g.l,[]),r._31(512,k.c,k.c,[]),r._31(1024,r.p,L.q,[]),r._31(1024,r.G,function(){return[h.t()]},[]),r._31(512,h.y,h.y,[r.x]),r._31(1024,r.d,function(l,n,u){return[L.r(l,n),h.z(u)]},[[2,L.h],[2,r.G],h.y]),r._31(512,r.e,r.e,[[2,r.d]]),r._31(131584,r._18,r._18,[r.H,r._12,r.x,r.p,r.l,r.e]),r._31(2048,r.g,null,[r._18]),r._31(512,r.f,r.f,[r.g]),r._31(512,L.a,L.a,[[3,L.a]]),r._31(1024,h.s,h.v,[[3,h.k]]),r._31(512,h.r,h.c,[]),r._31(512,h.b,h.b,[]),r._31(256,h.g,{useHash:!0},[]),r._31(1024,k.i,h.u,[k.p,[2,k.a],h.g]),r._31(512,k.h,k.h,[k.i]),r._31(512,r.j,r.j,[]),r._31(512,r.E,r.V,[r.j,[2,r.W]]),r._31(1024,h.i,function(){return[[{path:"",pathMatch:"full",redirectTo:"demo"},{path:"demo",component:p},{path:"signature-pad",loadChildren:"app/pages/signature-pad/signature-pad.module#SignaturePadModule"},{path:"signature-pad-control",loadChildren:"app/pages/signature-pad-control/signature-pad-control.module#SignaturePadControlModule"},{path:"signature-pad-configuration",loadChildren:"app/pages/signature-pad-configuration/signature-pad-configuration.module#SignaturePadConfigurationModule"},{path:"signature-pad-control-validation",loadChildren:"app/pages/signature-pad-control-validation/signature-pad-control-validation.module#SignaturePadControlValidationModule"},{path:"signature-pad-card",loadChildren:"app/pages/signature-pad-card/signature-pad-card.module#SignaturePadCardModule"},{path:"signature-pad-card-group",loadChildren:"app/pages/signature-pad-card-group/signature-pad-card-group.module#SignaturePadCardGroupModule"}],[{path:"",component:p}]]},[]),r._31(1024,h.k,h.w,[r.g,h.r,h.b,k.h,r.x,r.E,r.j,h.i,h.g,[2,h.q],[2,h.j]]),r._31(512,h.n,h.n,[[2,h.s],[2,h.k]]),r._31(512,A,A,[]),r._31(512,K.a,K.a,[]),r._31(512,N.e,N.e,[]),r._31(512,N.d,N.d,[]),r._31(512,P,P,[]),r._31(512,j,j,[]),r._31(512,s.l,s.l,[]),r._31(512,s.k,s.k,[]),r._31(512,g.a,g.a,[]),r._31(512,O,O,[]),r._31(512,c,c,[]),r._31(256,N.k,"XSRF-TOKEN",[]),r._31(256,N.l,"X-XSRF-TOKEN",[])])});o.production&&Object(r._5)(),Object(L.j)().bootstrapModuleFactory(S).catch(function(l){return console.log(l)})},gFIY:function(l,n,u){function t(l){var n=a[l];return n?u.e(n[1]).then(function(){return u(n[0])}):Promise.reject(new Error("Cannot find module '"+l+"'."))}var a={"app/pages/signature-pad-card-group/signature-pad-card-group.module.ngfactory":["Jidj",5],"app/pages/signature-pad-card/signature-pad-card.module.ngfactory":["fBD8",4],"app/pages/signature-pad-configuration/signature-pad-configuration.module.ngfactory":["UXuG",0],"app/pages/signature-pad-control-validation/signature-pad-control-validation.module.ngfactory":["uD5q",3],"app/pages/signature-pad-control/signature-pad-control.module.ngfactory":["LQIJ",2],"app/pages/signature-pad/signature-pad.module.ngfactory":["m3E1",1]};t.keys=function(){return Object.keys(a)},t.id="gFIY",l.exports=t}},[0]); --------------------------------------------------------------------------------