ng-captcha
Version:
A pure front-end angular captcha module.
202 lines (196 loc) • 18.5 kB
JavaScript
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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