UNPKG

ng-captcha

Version:

A pure front-end angular captcha module.

146 lines 16.5 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import { Component, ViewChild, Output, EventEmitter, Input } from '@angular/core'; export class CaptchaComponent { constructor() { this.generateCode = new EventEmitter(); this.canvas = document.createElement('canvas'); this.letters = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]; this.code = ''; } /** * @return {?} */ ngOnInit() { this.init(); this.refresh(); } /** * @return {?} */ onClick() { this.refresh(); } /** * @return {?} */ init() { this.canvas.width = this.width || 100; this.canvas.height = this.height || 50; this.canvas.style.cursor = 'pointer'; this.canvas.innerHTML = '您的浏览器版本不支持canvas'; this.container.nativeElement.appendChild(this.canvas); } // generate code /** * @return {?} */ refresh() { this.code = ''; /** @type {?} */ const ctx = this.canvas.getContext('2d'); ctx.textBaseline = 'middle'; ctx.fillStyle = this.randomColor(180, 240); ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); for (let i = 0; i < 4; i++) { /** @type {?} */ const letter = this.letters[this.randomNum(0, this.letters.length)]; this.code += letter; ctx.font = this.randomNum(this.canvas.height / 2, this.canvas.height) + 'px SimHei'; ctx.fillStyle = this.randomColor(50, 160); ctx.shadowOffsetX = this.randomNum(-3, 3); ctx.shadowOffsetY = this.randomNum(-3, 3); ctx.shadowBlur = this.randomNum(-3, 3); ctx.shadowColor = 'rgb(0, 0, 0, 0.3)'; /** @type {?} */ const x = this.canvas.width / 5 * i; /** @type {?} */ const y = this.canvas.height / 2; /** @type {?} */ const deg = this.randomNum(-30, 30) // setting rotate and origin point ; // setting rotate and origin point ctx.translate(x, y); ctx.rotate(deg * Math.PI / 180); ctx.fillText(letter, 0, 0); // reset rotate and origin point ctx.rotate(-deg * Math.PI / 180); ctx.translate(-x, -y); } // draw interfering line for (let i = 0; i < 4; i++) { ctx.strokeStyle = this.randomColor(40, 180); ctx.beginPath(); ctx.moveTo(this.randomNum(0, this.canvas.width), this.randomNum(0, this.canvas.height)); ctx.lineTo(this.randomNum(0, this.canvas.width), this.randomNum(0, this.canvas.height)); ctx.stroke(); } // draw interfering point for (let i = 0; i < this.canvas.width / 4; i++) { ctx.fillStyle = this.randomColor(); ctx.beginPath(); ctx.arc(this.randomNum(0, this.canvas.width), this.randomNum(0, this.canvas.height), 1, 0, 2 * Math.PI); ctx.fill(); } this.generateCode.emit(this.code.toLowerCase()); } /** * return a random integer * @param {?} min 最小值 * @param {?} max 最大值 * @return {?} */ randomNum(min, max) { return Math.floor(Math.random() * (max - min) + min); } /** * return a random color * @param {?=} min * @param {?=} max * @return {?} */ randomColor(min = 0, max = 255) { /** @type {?} */ const r = this.randomNum(min, max); /** @type {?} */ const g = this.randomNum(min, max); /** @type {?} */ const b = this.randomNum(min, max); return `rgb(${r}, ${g}, ${b})`; } } CaptchaComponent.decorators = [ { type: Component, args: [{ selector: 'captcha', template: "<div class=\"captcha-container\" #captchaContainer (click)=\"onClick()\"></div>", styles: [".captcha-container{display:inline-block;line-height:0}"] }] } ]; /** @nocollapse */ CaptchaComponent.ctorParameters = () => []; CaptchaComponent.propDecorators = { width: [{ type: Input }], height: [{ type: Input }], generateCode: [{ type: Output }], container: [{ type: ViewChild, args: ['captchaContainer',] }] }; if (false) { /** @type {?} */ CaptchaComponent.prototype.width; /** @type {?} */ CaptchaComponent.prototype.height; /** @type {?} */ CaptchaComponent.prototype.generateCode; /** @type {?} */ CaptchaComponent.prototype.container; /** @type {?} */ CaptchaComponent.prototype.canvas; /** @type {?} */ CaptchaComponent.prototype.letters; /** @type {?} */ CaptchaComponent.prototype.code; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FwdGNoYS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZy1jYXB0Y2hhLyIsInNvdXJjZXMiOlsibGliL2NhcHRjaGEuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLFNBQVMsRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQU8xRixNQUFNLE9BQU8sZ0JBQWdCO0lBVTNCO1FBTlUsaUJBQVksR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFBO1FBRTNDLFdBQU0sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBQ3pDLFlBQU8sR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdB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QUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQTtJQUNoQyxDQUFDOzs7WUFwR0YsU0FBUyxTQUFDO2dCQUNULFFBQVEsRUFBRSxTQUFTO2dCQUNuQiwyRkFBdUM7O2FBRXhDOzs7OztvQkFHRSxLQUFLO3FCQUNMLEtBQUs7MkJBQ0wsTUFBTTt3QkFDTixTQUFTLFNBQUMsa0JBQWtCOzs7O0lBSDdCLGlDQUFjOztJQUNkLGtDQUFlOztJQUNmLHdDQUEyQzs7SUFDM0MscUNBQXdDOztJQUN4QyxrQ0FBeUM7O0lBQ3pDLG1DQUFnVTs7SUFDaFUsZ0NBQVMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgVmlld0NoaWxkLCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY2FwdGNoYScsXG4gIHRlbXBsYXRlVXJsOiAnLi9jYXB0Y2hhLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vY2FwdGNoYS5jb21wb25lbnQuY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgQ2FwdGNoYUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cbiAgQElucHV0KCkgd2lkdGhcbiAgQElucHV0KCkgaGVpZ2h0XG4gIEBPdXRwdXQoKSBnZW5lcmF0ZUNvZGUgPSBuZXcgRXZlbnRFbWl0dGVyKClcbiAgQFZpZXdDaGlsZCgnY2FwdGNoYUNvbnRhaW5lcicpIGNvbnRhaW5lclxuICBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKVxuICBsZXR0ZXJzID0gW1wiMFwiLCBcIjFcIiwgXCIyXCIsIFwiM1wiLCBcIjRcIiwgXCI1XCIsIFwiNlwiLCBcIjdcIiwgXCI4XCIsIFwiOVwiLCBcImFcIiwgXCJiXCIsIFwiY1wiLCBcImRcIiwgXCJlXCIsIFwiZlwiLCBcImdcIiwgXCJoXCIsIFwiaVwiLCBcImpcIiwgXCJrXCIsIFwibFwiLCBcIm1cIiwgXCJuXCIsIFwib1wiLCBcInBcIiwgXCJxXCIsIFwiclwiLCBcInNcIiwgXCJ0XCIsIFwidVwiLCBcInZcIiwgXCJ3XCIsIFwieFwiLCBcInlcIiwgXCJ6XCIsIFwiQVwiLCBcIkJcIiwgXCJDXCIsIFwiRFwiLCBcIkVcIiwgXCJGXCIsIFwiR1wiLCBcIkhcIiwgXCJJXCIsIFwiSlwiLCBcIktcIiwgXCJMXCIsIFwiTVwiLCBcIk5cIiwgXCJPXCIsIFwiUFwiLCBcIlFcIiwgXCJSXCIsIFwiU1wiLCBcIlRcIiwgXCJVXCIsIFwiVlwiLCBcIldcIiwgXCJYXCIsIFwiWVwiLCBcIlpcIl1cbiAgY29kZSA9ICcnXG5cbiAgY29uc3RydWN0b3IoKSB7IH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmluaXQoKVxuICAgIHRoaXMucmVmcmVzaCgpXG4gIH1cblxuICBvbkNsaWNrKCkge1xuICAgIHRoaXMucmVmcmVzaCgpXG4gIH1cblxuICBwcml2YXRlIGluaXQoKSB7XG4gICAgdGhpcy5jYW52YXMud2lkdGggPSB0aGlzLndpZHRoIHx8IDEwMFxuICAgIHRoaXMuY2FudmFzLmhlaWdodCA9IHRoaXMuaGVpZ2h0IHx8IDUwXG4gICAgdGhpcy5jYW52YXMuc3R5bGUuY3Vyc29yID0gJ3BvaW50ZXInXG4gICAgdGhpcy5jYW52YXMuaW5uZXJIVE1MID0gJ+aCqOeahOa1j+iniOWZqOeJiOacrOS4jeaUr+aMgWNhbnZhcydcbiAgICB0aGlzLmNvbnRhaW5lci5uYXRpdmVFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuY2FudmFzKVxuICB9XG5cbiAgLy8gZ2VuZXJhdGUgY29kZVxuICBwcml2YXRlIHJlZnJlc2goKSB7XG4gICAgdGhpcy5jb2RlID0gJydcbiAgICBjb25zdCBjdHggPSB0aGlzLmNhbnZhcy5nZXRDb250ZXh0KCcyZCcpXG4gICAgY3R4LnRleHRCYXNlbGluZSA9ICdtaWRkbGUnXG4gICAgY3R4LmZpbGxTdHlsZSA9IHRoaXMucmFuZG9tQ29sb3IoMTgwLCAyNDApXG4gICAgY3R4LmZpbGxSZWN0KDAsIDAsIHRoaXMuY2FudmFzLndpZHRoLCB0aGlzLmNhbnZhcy5oZWlnaHQpXG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgICAgY29uc3QgbGV0dGVyID0gdGhpcy5sZXR0ZXJzW3RoaXMucmFuZG9tTnVtKDAsIHRoaXMubGV0dGVycy5sZW5ndGgpXVxuICAgICAgdGhpcy5jb2RlICs9IGxldHRlclxuICAgICAgY3R4LmZvbnQgPSB0aGlzLnJhbmRvbU51bSh0aGlzLmNhbnZhcy5oZWlnaHQgLyAyLCB0aGlzLmNhbnZhcy5oZWlnaHQpICsgJ3B4IFNpbUhlaSdcbiAgICAgIGN0eC5maWxsU3R5bGUgPSB0aGlzLnJhbmRvbUNvbG9yKDUwLCAxNjApXG4gICAgICBjdHguc2hhZG93T2Zmc2V0WCA9IHRoaXMucmFuZG9tTnVtKC0zLCAzKVxuICAgICAgY3R4LnNoYWRvd09mZnNldFkgPSB0aGlzLnJhbmRvbU51bSgtMywgMylcbiAgICAgIGN0eC5zaGFkb3dCbHVyID0gdGhpcy5yYW5kb21OdW0oLTMsIDMpXG4gICAgICBjdHguc2hhZG93Q29sb3IgPSAncmdiKDAsIDAsIDAsIDAuMyknXG4gICAgICBjb25zdCB4ID0gdGhpcy5jYW52YXMud2lkdGggLyA1ICogaVxuICAgICAgY29uc3QgeSA9IHRoaXMuY2FudmFzLmhlaWdodCAvIDJcbiAgICAgIGNvbnN0IGRlZyA9IHRoaXMucmFuZG9tTnVtKC0zMCwgMzApXG4gICAgICAvLyBzZXR0aW5nIHJvdGF0ZSBhbmQgb3JpZ2luIHBvaW50XG4gICAgICBjdHgudHJhbnNsYXRlKHgsIHkpXG4gICAgICBjdHgucm90YXRlKGRlZyAqIE1hdGguUEkgLyAxODApXG4gICAgICBjdHguZmlsbFRleHQobGV0dGVyLCAwLCAwKVxuICAgICAgLy8gcmVzZXQgcm90YXRlIGFuZCBvcmlnaW4gcG9pbnRcbiAgICAgIGN0eC5yb3RhdGUoLWRlZyAqIE1hdGguUEkgLyAxODApXG4gICAgICBjdHgudHJhbnNsYXRlKC14LCAteSlcbiAgICB9XG5cbiAgICAvLyBkcmF3IGludGVyZmVyaW5nIGxpbmVcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgICAgY3R4LnN0cm9rZVN0eWxlID0gdGhpcy5yYW5kb21Db2xvcig0MCwgMTgwKVxuICAgICAgY3R4LmJlZ2luUGF0aCgpXG4gICAgICBjdHgubW92ZVRvKHRoaXMucmFuZG9tTnVtKDAsIHRoaXMuY2FudmFzLndpZHRoKSwgdGhpcy5yYW5kb21OdW0oMCwgdGhpcy5jYW52YXMuaGVpZ2h0KSlcbiAgICAgIGN0eC5saW5lVG8odGhpcy5yYW5kb21OdW0oMCwgdGhpcy5jYW52YXMud2lkdGgpLCB0aGlzLnJhbmRvbU51bSgwLCB0aGlzLmNhbnZhcy5oZWlnaHQpKVxuICAgICAgY3R4LnN0cm9rZSgpXG4gICAgfVxuXG4gICAgLy8gZHJhdyBpbnRlcmZlcmluZyBwb2ludFxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jYW52YXMud2lkdGggLyA0OyBpKyspIHtcbiAgICAgIGN0eC5maWxsU3R5bGUgPSB0aGlzLnJhbmRvbUNvbG9yKClcbiAgICAgIGN0eC5iZWdpblBhdGgoKVxuICAgICAgY3R4LmFyYyh0aGlzLnJhbmRvbU51bSgwLCB0aGlzLmNhbnZhcy53aWR0aCksIHRoaXMucmFuZG9tTnVtKDAsIHRoaXMuY2FudmFzLmhlaWdodCksIDEsIDAsIDIgKiBNYXRoLlBJKVxuICAgICAgY3R4LmZpbGwoKVxuICAgIH1cblxuICAgIHRoaXMuZ2VuZXJhdGVDb2RlLmVtaXQodGhpcy5jb2RlLnRvTG93ZXJDYXNlKCkpXG4gIH1cblxuICAvKipcbiAgICogcmV0dXJuIGEgcmFuZG9tIGludGVnZXJcbiAgICogQHBhcmFtIG1pbiDmnIDlsI/lgLxcbiAgICogQHBhcmFtIG1heCDmnIDlpKflgLxcbiAgICovXG4gIHByaXZhdGUgcmFuZG9tTnVtKG1pbiwgbWF4KSB7XG4gICAgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIChtYXggLSBtaW4pICsgbWluKVxuICB9XG5cbiAgLyoqXG4gICAqIHJldHVybiBhIHJhbmRvbSBjb2xvclxuICAgKi9cbiAgcHJpdmF0ZSByYW5kb21Db2xvcihtaW4gPSAwLCBtYXggPSAyNTUpIHtcbiAgICBjb25zdCByID0gdGhpcy5yYW5kb21OdW0obWluLCBtYXgpXG4gICAgY29uc3QgZyA9IHRoaXMucmFuZG9tTnVtKG1pbiwgbWF4KVxuICAgIGNvbnN0IGIgPSB0aGlzLnJhbmRvbU51bShtaW4sIG1heClcbiAgICByZXR1cm4gYHJnYigke3J9LCAke2d9LCAke2J9KWBcbiAgfVxuXG59XG4iXX0=