1+ "use strict";
2+
3+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4+
5+ Object.defineProperty(exports, "__esModule", {
6+ value: true
7+ });
8+ exports.default = void 0;
9+
10+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
11+
12+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
13+
14+ var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
15+
16+ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
17+
18+ var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
19+
20+ var _react = _interopRequireDefault(require("react"));
21+
22+ var Vcode =
23+ /*#__PURE__*/
24+ function (_React$PureComponent) {
25+ (0, _inherits2.default)(Vcode, _React$PureComponent);
26+
27+ function Vcode(props) {
28+ var _this;
29+
30+ (0, _classCallCheck2.default)(this, Vcode);
31+ _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Vcode).call(this, props));
32+ _this.state = {
33+ id: _this.props.id || "".concat(new Date().getTime(), "_").concat(Math.random().toFixed(4)),
34+ // 需要一个唯一的ID,因为vcode要直接操作dom
35+ width: _this.props.width || 150,
36+ // vcode宽度
37+ height: _this.props.height || 40,
38+ // vcode高度
39+ len: _this.props.length || 4,
40+ // 生成几位code
41+ style: function () {
42+ // vcode容器样式
43+ var a = {
44+ position: 'relative',
45+ backgroundColor: '#fff',
46+ overflow: 'hidden',
47+ width: _this.props.width ? "".concat(_this.props.width, "px") : '150px',
48+ height: _this.props.height ? "".concat(_this.props.height, "px") : '40px',
49+ cursor: 'pointer',
50+ verticalAlign: 'middle',
51+ userSelect: 'none'
52+ };
53+
54+ if (_this.props.style) {
55+ return Object.assign({}, a, _this.props.style);
56+ }
57+
58+ return a;
59+ }(),
60+ options: function () {
61+ // 初始化参数
62+ var a = {
63+ codes: [// 所有可能出现的字符
64+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'o', 'p', 'q', 'r', 's', 't', 'x', 'u', 'v', 'y', 'z', 'w', 'n', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
65+ fontSizeMin: 22,
66+ // 字体尺寸最小值
67+ fontSizeMax: 26,
68+ // 字体尺寸最大值
69+ colors: [// 字可能的颜色
70+ '#117cb3', '#f47b06', '#202890', '#db1821', '#b812c2'],
71+ fonts: [// 可能的字体
72+ 'Times New Roman', 'Georgia', 'Serif', 'sans-serif', 'arial', 'tahoma', 'Hiragino Sans GB'],
73+ lines: 8,
74+ // 生成多少根线
75+ lineColors: [// 线可能的颜色
76+ '#7999e1', '#383838', '#ec856d', '#008888'],
77+ lineHeightMin: 1,
78+ // 线的粗细最小值
79+ lineHeightMax: 1,
80+ // 线的粗细最大值
81+ lineWidthMin: 20,
82+ // 线的长度最小值
83+ lineWidthMax: 60 // 线的长度最大值
84+
85+ };
86+
87+ if (_this.props.options) {
88+ return Object.assign({}, a, _this.props.options);
89+ }
90+
91+ return a;
92+ }()
93+ };
94+ return _this;
95+ }
96+ /** 组件初始化完毕时触发 **/
97+
98+
99+ (0, _createClass2.default)(Vcode, [{
100+ key: "componentDidMount",
101+ value: function componentDidMount() {
102+ this.onDraw(this.props.value);
103+ }
104+ /** 组件参数改变 **/
105+
106+ }, {
107+ key: "componentDidUpdate",
108+ value: function componentDidUpdate(prevP) {
109+ if (this.props.value !== prevP.value) {
110+ this.onDraw(this.props.value);
111+ }
112+
113+ if (this.props.width !== prevP.width || this.props.height !== prevP.height || this.props.style !== prevP.style) {
114+ this.setState({
115+ width: this.props.width || 150,
116+ height: this.props.height || 40,
117+ style: Object.assign({}, this.state.style, {
118+ width: this.props.width ? "".concat(this.props.width, "px") : '150px',
119+ height: this.props.height ? "".concat(this.props.height, "px") : '40px'
120+ })
121+ });
122+ }
123+ }
124+ /** 用户点击了验证码图片 **/
125+
126+ }, {
127+ key: "onClick",
128+ value: function onClick() {
129+ // 如果用户没有设置值,就直接重新生成
130+ if (!this.props.value) {
131+ this.onDraw(this.props.value);
132+ }
133+
134+ this.props.onClick && this.props.onClick(); // 触发外部的onClick,什么都不返回
135+ }
136+ /** 随机生成一个Code的CSS样式 **/
137+
138+ }, {
139+ key: "codeCss",
140+ value: function codeCss(uW, i) {
141+ return ["font-size:".concat(this.randint(this.state.options.fontSizeMin, this.state.options.fontSizeMax), "px"), "color:".concat(this.state.options.colors[this.randint(0, this.state.options.colors.length - 1)]), 'position: absolute', "left:".concat(this.randint(uW * i, uW * i + uW - uW / 2), "px"), 'top:50%', "transform:rotate(".concat(this.randint(-15, 15), "deg) translateY(-50%)"), "-o-transform:rotate(".concat(this.randint(-15, 15), "deg) translateY(-50%)"), "-ms-transform:rotate(".concat(this.randint(-15, 15), "deg) translateY(-50%)"), "-moz-transform:rotate(".concat(this.randint(-15, 15), "deg) translateY(-50%)"), "-webkit-transform:rotate(".concat(this.randint(-15, 15), "deg) translateY(-50%)"), "font-family:".concat(this.state.options.fonts[this.randint(0, this.state.options.fonts.length - 1)]), 'font-weight:bold', 'z-index:2'].join(';');
142+ }
143+ /** 随机生成一条线的CSS样式 **/
144+
145+ }, {
146+ key: "lineCss",
147+ value: function lineCss() {
148+ return ['position: absolute', "opacity:".concat(this.randint(3, 8) / 10), "width:".concat(this.randint(this.state.options.lineWidthMin, this.state.options.lineWidthMax), "px"), "height:".concat(this.randint(this.state.options.lineHeightMin, this.state.options.lineHeightMax), "px"), "background:".concat(this.state.options.lineColors[this.randint(0, this.state.options.lineColors.length - 1)]), "left:".concat(this.randint(-this.state.options.lineWidthMin / 2, this.state.width), "px"), "top:".concat(this.randint(0, this.state.height), "px"), "transform:rotate(".concat(this.randint(-30, 30), "deg)"), "-o-transform:rotate(".concat(this.randint(-30, 30), "deg)"), "-ms-transform:rotate(".concat(this.randint(-30, 30), "deg)"), "-moz-transform:rotate(".concat(this.randint(-30, 30), "deg)"), "-webkit-transform:rotate(".concat(this.randint(-30, 30), "deg)"), "font-family:".concat(this.state.options.fonts[this.randint(0, this.state.options.fonts.length - 1)]), "font-weight:".concat(this.randint(400, 900))].join(';');
149+ }
150+ }, {
151+ key: "onDraw",
152+ value: function onDraw(value) {
153+ var c = ''; // 存储生成的code
154+
155+ var div = document.getElementById(this.state.id);
156+ var isImg = /^http[s]*:\/\/|\.jpg$|\.png$|\.jpeg$|\.gif$|\.bmp$|\.webp$|^data:image/.test(value); // 是否是图片
157+
158+ div.innerHTML = '';
159+
160+ if (isImg) {
161+ // 用户传递了一张图片
162+ var dom = document.createElement('img');
163+ dom.style.cssText = ['display: block', 'max-width:100%', 'max-height:100%'].join(';');
164+ dom.src = value;
165+ div.appendChild(dom);
166+ this.props.onChange && this.props.onChange(null);
167+ return null;
168+ } // 不是图片而是普通字符串, 如果value存在说明是用户自定义的字符串
169+
170+
171+ var length = value ? value.length : this.state.len; // 字符的长度
172+
173+ var uW = this.state.width / length / 1.01; // 每个字符占的宽度
174+
175+ for (var i = 0; i < length; i++) {
176+ var _dom = document.createElement('span');
177+
178+ _dom.style.cssText = this.codeCss(uW, i);
179+ var temp = value ? value[i] : this.state.options.codes[Math.round(Math.random() * (this.state.options.codes.length - 1))];
180+ _dom.innerHTML = temp;
181+ c = "".concat(c).concat(temp);
182+ div.appendChild(_dom);
183+ } // 生成好看的线条
184+
185+
186+ for (var _i = 0; _i < this.state.options.lines; _i++) {
187+ var _dom2 = document.createElement('div');
188+
189+ _dom2.style.cssText = this.lineCss();
190+ div.appendChild(_dom2);
191+ }
192+
193+ this.props.onChange && this.props.onChange(c); // 触发回调
194+
195+ return c;
196+ }
197+ /** 生成范围随机数 **/
198+
199+ }, {
200+ key: "randint",
201+ value: function randint(n, m) {
202+ var c = m - n + 1;
203+ var num = Math.random() * c + n;
204+ return Math.floor(num);
205+ }
206+ }, {
207+ key: "render",
208+ value: function render() {
209+ var _this2 = this;
210+
211+ return _react.default.createElement("div", {
212+ id: this.state.id,
213+ style: this.state.style,
214+ className: this.props.className,
215+ onClick: function onClick() {
216+ return _this2.onClick();
217+ }
218+ });
219+ }
220+ }]);
221+ return Vcode;
222+ }(_react.default.PureComponent);
223+ /**
224+ id: P.string, // ID
225+ length: P.number, // 生成几位字符串
226+ value: P.string, // 由父级传入指定的字符串生成code
227+ width: P.number, // 多宽 px
228+ height: P.number, // 多高 px
229+ style: P.object, // 自定义style
230+ className: P.string, // 各种class
231+ onChange: P.func, // 每次生成新的验证码时,将验证码的值传到上级
232+ options: P.object, // 自定义各参数
233+ **/
234+
235+
236+ exports.default = Vcode;
0 commit comments