UNPKG

ng-captcha

Version:

A pure front-end angular captcha module.

202 lines (196 loc) 18.5 kB
import { Component, ViewChild, Output, EventEmitter, Input, NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var CaptchaComponent = /** @class */ (function () { function CaptchaComponent() { 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 {?} */ CaptchaComponent.prototype.ngOnInit = /** * @return {?} */ function () { this.init(); this.refresh(); }; /** * @return {?} */ CaptchaComponent.prototype.onClick = /** * @return {?} */ function () { this.refresh(); }; /** * @return {?} */ CaptchaComponent.prototype.init = /** * @return {?} */ function () { 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 // generate code /** * @return {?} */ CaptchaComponent.prototype.refresh = // generate code /** * @return {?} */ function () { this.code = ''; /** @type {?} */ var 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 (var i = 0; i < 4; i++) { /** @type {?} */ var 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 {?} */ var x = this.canvas.width / 5 * i; /** @type {?} */ var y = this.canvas.height / 2; /** @type {?} */ var 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 (var 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 (var 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 a random integer * @param {?} min 最小值 * @param {?} max 最大值 * @return {?} */ CaptchaComponent.prototype.randomNum = /** * return a random integer * @param {?} min 最小值 * @param {?} max 最大值 * @return {?} */ function (min, max) { return Math.floor(Math.random() * (max - min) + min); }; /** * return a random color */ /** * return a random color * @param {?=} min * @param {?=} max * @return {?} */ CaptchaComponent.prototype.randomColor = /** * return a random color * @param {?=} min * @param {?=} max * @return {?} */ function (min, max) { if (min === void 0) { min = 0; } if (max === void 0) { max = 255; } /** @type {?} */ var r = this.randomNum(min, max); /** @type {?} */ var g = this.randomNum(min, max); /** @type {?} */ var 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 = function () { return []; }; CaptchaComponent.propDecorators = { width: [{ type: Input }], height: [{ type: Input }], generateCode: [{ type: Output }], container: [{ type: ViewChild, args: ['captchaContainer',] }] }; return CaptchaComponent; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var CaptchaModule = /** @class */ (function () { function CaptchaModule() { } CaptchaModule.decorators = [ { type: NgModule, args: [{ imports: [ CommonModule ], declarations: [CaptchaComponent], exports: [CaptchaComponent] },] } ]; return CaptchaModule; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ export { CaptchaModule, CaptchaComponent as ɵa }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctY2FwdGNoYS5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vbmctY2FwdGNoYS9saWIvY2FwdGNoYS5jb21wb25lbnQudHMiLCJuZzovL25nLWNhcHRjaGEvbGliL2NhcHRjaGEubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0LCBWaWV3Q2hpbGQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjYXB0Y2hhJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NhcHRjaGEuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9jYXB0Y2hhLmNvbXBvbmVudC5jc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBDYXB0Y2hhQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICBASW5wdXQoKSB3aWR0aFxuICBASW5wdXQoKSBoZWlnaHRcbiAgQE91dHB1dCgpIGdlbmVyYXRlQ29kZSA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuICBAVmlld0NoaWxkKCdjYXB0Y2hhQ29udGFpbmVyJykgY29udGFpbmVyXG4gIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpXG4gIGxldHRlcnMgPSBbXCIwXCIsIFwiMVwiLCBcIjJcIiwgXCIzXCIsIFwiNFwiLCBcIjVcIiwgXCI2XCIsIFwiN1wiLCBcIjhcIiwgXCI5XCIsIFwiYVwiLCBcImJcIiwgXCJjXCIsIFwiZFwiLCBcImVcIiwgXCJmXCIsIFwiZ1wiLCBcImhcIiwgXCJpXCIsIFwialwiLCBcImtcIiwgXCJsXCIsIFwibVwiLCBcIm5cIiwgXCJvXCIsIFwicFwiLCBcInFcIiwgXCJyXCIsIFwic1wiLCBcInRcIiwgXCJ1XCIsIFwidlwiLCBcIndcIiwgXCJ4XCIsIFwieVwiLCBcInpcIiwgXCJBXCIsIFwiQlwiLCBcIkNcIiwgXCJEXCIsIFwiRVwiLCBcIkZcIiwgXCJHXCIsIFwiSFwiLCBcIklcIiwgXCJKXCIsIFwiS1wiLCBcIkxcIiwgXCJNXCIsIFwiTlwiLCBcIk9cIiwgXCJQXCIsIFwiUVwiLCBcIlJcIiwgXCJTXCIsIFwiVFwiLCBcIlVcIiwgXCJWXCIsIFwiV1wiLCBcIlhcIiwgXCJZXCIsIFwiWlwiXVxuICBjb2RlID0gJydcblxuICBjb25zdHJ1Y3RvcigpIHsgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuaW5pdCgpXG4gICAgdGhpcy5yZWZyZXNoKClcbiAgfVxuXG4gIG9uQ2xpY2soKSB7XG4gICAgdGhpcy5yZWZyZXNoKClcbiAgfVxuXG4gIHByaXZhdGUgaW5pdCgpIHtcbiAgICB0aGlzLmNhbnZhcy53aWR0aCA9IHRoaXMud2lkdGggfHwgMTAwXG4gICAgdGhpcy5jYW52YXMuaGVpZ2h0ID0gdGhpcy5oZWlnaHQgfHwgNTBcbiAgICB0aGlzLmNhbnZhcy5zdHlsZS5jdXJzb3IgPSAncG9pbnRlcidcbiAgICB0aGlzLmNhbnZhcy5pbm5lckhUTUwgPSAnw6bCgsKow6fCmsKEw6bCtcKPw6jCp8KIw6XCmcKow6fCicKIw6bCnMKsw6TCuMKNw6bClMKvw6bCjMKBY2FudmFzJ1xuICAgIHRoaXMuY29udGFpbmVyLm5hdGl2ZUVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5jYW52YXMpXG4gIH1cblxuICAvLyBnZW5lcmF0ZSBjb2RlXG4gIHByaXZhdGUgcmVmcmVzaCgpIHtcbiAgICB0aGlzLmNvZGUgPSAnJ1xuICAgIGNvbnN0IGN0eCA9IHRoaXMuY2FudmFzLmdldENvbnRleHQoJzJkJylcbiAgICBjdHgudGV4dEJhc2VsaW5lID0gJ21pZGRsZSdcbiAgICBjdHguZmlsbFN0eWxlID0gdGhpcy5yYW5kb21Db2xvcigxODAsIDI0MClcbiAgICBjdHguZmlsbFJlY3QoMCwgMCwgdGhpcy5jYW52YXMud2lkdGgsIHRoaXMuY2FudmFzLmhlaWdodClcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgICBjb25zdCBsZXR0ZXIgPSB0aGlzLmxldHRlcnNbdGhpcy5yYW5kb21OdW0oMCwgdGhpcy5sZXR0ZXJzLmxlbmd0aCldXG4gICAgICB0aGlzLmNvZGUgKz0gbGV0dGVyXG4gICAgICBjdHguZm9udCA9IHRoaXMucmFuZG9tTnVtKHRoaXMuY2FudmFzLmhlaWdodCAvIDIsIHRoaXMuY2FudmFzLmhlaWdodCkgKyAncHggU2ltSGVpJ1xuICAgICAgY3R4LmZpbGxTdHlsZSA9IHRoaXMucmFuZG9tQ29sb3IoNTAsIDE2MClcbiAgICAgIGN0eC5zaGFkb3dPZmZzZXRYID0gdGhpcy5yYW5kb21OdW0oLTMsIDMpXG4gICAgICBjdHguc2hhZG93T2Zmc2V0WSA9IHRoaXMucmFuZG9tTnVtKC0zLCAzKVxuICAgICAgY3R4LnNoYWRvd0JsdXIgPSB0aGlzLnJhbmRvbU51bSgtMywgMylcbiAgICAgIGN0eC5zaGFkb3dDb2xvciA9ICdyZ2IoMCwgMCwgMCwgMC4zKSdcbiAgICAgIGNvbnN0IHggPSB0aGlzLmNhbnZhcy53aWR0aCAvIDUgKiBpXG4gICAgICBjb25zdCB5ID0gdGhpcy5jYW52YXMuaGVpZ2h0IC8gMlxuICAgICAgY29uc3QgZGVnID0gdGhpcy5yYW5kb21OdW0oLTMwLCAzMClcbiAgICAgIC8vIHNldHRpbmcgcm90YXRlIGFuZCBvcmlnaW4gcG9pbnRcbiAgICAgIGN0eC50cmFuc2xhdGUoeCwgeSlcbiAgICAgIGN0eC5yb3RhdGUoZGVnICogTWF0aC5QSSAvIDE4MClcbiAgICAgIGN0eC5maWxsVGV4dChsZXR0ZXIsIDAsIDApXG4gICAgICAvLyByZXNldCByb3RhdGUgYW5kIG9yaWdpbiBwb2ludFxuICAgICAgY3R4LnJvdGF0ZSgtZGVnICogTWF0aC5QSSAvIDE4MClcbiAgICAgIGN0eC50cmFuc2xhdGUoLXgsIC15KVxuICAgIH1cblxuICAgIC8vIGRyYXcgaW50ZXJmZXJpbmcgbGluZVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgICBjdHguc3Ryb2tlU3R5bGUgPSB0aGlzLnJhbmRvbUNvbG9yKDQwLCAxODApXG4gICAgICBjdHguYmVnaW5QYXRoKClcbiAgICAgIGN0eC5tb3ZlVG8odGhpcy5yYW5kb21OdW0oMCwgdGhpcy5jYW52YXMud2lkdGgpLCB0aGlzLnJhbmRvbU51bSgwLCB0aGlzLmNhbnZhcy5oZWlnaHQpKVxuICAgICAgY3R4LmxpbmVUbyh0aGlzLnJhbmRvbU51bSgwLCB0aGlzLmNhbnZhcy53aWR0aCksIHRoaXMucmFuZG9tTnVtKDAsIHRoaXMuY2FudmFzLmhlaWdodCkpXG4gICAgICBjdHguc3Ryb2tlKClcbiAgICB9XG5cbiAgICAvLyBkcmF3IGludGVyZmVyaW5nIHBvaW50XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmNhbnZhcy53aWR0aCAvIDQ7IGkrKykge1xuICAgICAgY3R4LmZpbGxTdHlsZSA9IHRoaXMucmFuZG9tQ29sb3IoKVxuICAgICAgY3R4LmJlZ2luUGF0aCgpXG4gICAgICBjdHguYXJjKHRoaXMucmFuZG9tTnVtKDAsIHRoaXMuY2FudmFzLndpZHRoKSwgdGhpcy5yYW5kb21OdW0oMCwgdGhpcy5jYW52YXMuaGVpZ2h0KSwgMSwgMCwgMiAqIE1hdGguUEkpXG4gICAgICBjdHguZmlsbCgpXG4gICAgfVxuXG4gICAgdGhpcy5nZW5lcmF0ZUNvZGUuZW1pdCh0aGlzLmNvZGUudG9Mb3dlckNhc2UoKSlcbiAgfVxuXG4gIC8qKlxuICAgKiByZXR1cm4gYSByYW5kb20gaW50ZWdlclxuICAgKiBAcGFyYW0gbWluIMOmwpzCgMOlwrDCj8OlwoDCvFxuICAgKiBAcGFyYW0gbWF4IMOmwpzCgMOlwqTCp8OlwoDCvFxuICAgKi9cbiAgcHJpdmF0ZSByYW5kb21OdW0obWluLCBtYXgpIHtcbiAgICByZXR1cm4gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogKG1heCAtIG1pbikgKyBtaW4pXG4gIH1cblxuICAvKipcbiAgICogcmV0dXJuIGEgcmFuZG9tIGNvbG9yXG4gICAqL1xuICBwcml2YXRlIHJhbmRvbUNvbG9yKG1pbiA9IDAsIG1heCA9IDI1NSkge1xuICAgIGNvbnN0IHIgPSB0aGlzLnJhbmRvbU51bShtaW4sIG1heClcbiAgICBjb25zdCBnID0gdGhpcy5yYW5kb21OdW0obWluLCBtYXgpXG4gICAgY29uc3QgYiA9IHRoaXMucmFuZG9tTnVtKG1pbiwgbWF4KVxuICAgIHJldHVybiBgcmdiKCR7cn0sICR7Z30sICR7Yn0pYFxuICB9XG5cbn1cbiIsImltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQ2FwdGNoYUNvbXBvbmVudCB9IGZyb20gJy4vY2FwdGNoYS5jb21wb25lbnQnO1xuXG5ATmdNb2R1bGUoe1xuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlXG4gIF0sXG4gIGRlY2xhcmF0aW9uczogW0NhcHRjaGFDb21wb25lbnRdLFxuICBleHBvcnRzOiBbQ2FwdGNoYUNvbXBvbmVudF1cbn0pXG5leHBvcnQgY2xhc3MgQ2FwdGNoYU1vZHVsZSB7IH1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7SUFpQkU7UUFOVSxpQkFBWSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUE7UUFFM0MsV0FBTSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDekMsWUFBTyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcs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