11import React from 'react' ;
2-
2+ // equire('es6-object-assign').polyfill();
33class Vcode extends React . Component {
44 constructor ( props ) {
55 super ( props ) ;
66 this . state = {
77 id : this . props . id || `${ new Date ( ) . getTime ( ) } _${ Math . random ( ) . toFixed ( 4 ) } ` , // 需要一个唯一的ID,因为vcode要直接操作dom
8- width : this . props . width || 150 , // vcode宽度
9- height : this . props . height || 40 , // vcode高度
10- len : this . props . length || 4 , // 生成几位code
11- style : ( ( ) => { // vcode容器样式
8+ width : this . props . width || 150 , // vcode宽度
9+ height : this . props . height || 40 , // vcode高度
10+ len : this . props . length || 4 , // 生成几位code
11+ style : ( ( ) => {
12+ // vcode容器样式
1213 const a = {
1314 position : 'relative' ,
1415 backgroundColor : '#fff' ,
@@ -24,24 +25,75 @@ class Vcode extends React.Component {
2425 }
2526 return a ;
2627 } ) ( ) ,
27- options : ( ( ) => { // 初始化参数
28+ options : ( ( ) => {
29+ // 初始化参数
2830 const a = {
29- codes : [ // 所有可能出现的字符
30- 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'i' , 'j' , 'k' , 'l' , 'm' ,
31- 'o' , 'p' , 'q' , 'r' , 's' , 't' , 'x' , 'u' , 'v' , 'y' , 'z' , 'w' , 'n' ,
32- '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' ,
31+ codes : [
32+ // 所有可能出现的字符
33+ 'a' ,
34+ 'b' ,
35+ 'c' ,
36+ 'd' ,
37+ 'e' ,
38+ 'f' ,
39+ 'g' ,
40+ 'h' ,
41+ 'i' ,
42+ 'j' ,
43+ 'k' ,
44+ 'l' ,
45+ 'm' ,
46+ 'o' ,
47+ 'p' ,
48+ 'q' ,
49+ 'r' ,
50+ 's' ,
51+ 't' ,
52+ 'x' ,
53+ 'u' ,
54+ 'v' ,
55+ 'y' ,
56+ 'z' ,
57+ 'w' ,
58+ 'n' ,
59+ '0' ,
60+ '1' ,
61+ '2' ,
62+ '3' ,
63+ '4' ,
64+ '5' ,
65+ '6' ,
66+ '7' ,
67+ '8' ,
68+ '9' ,
3369 ] ,
34- fontSizeMin : 22 , // 字体尺寸最小值
35- fontSizeMax : 26 , // 字体尺寸最大值
36- colors : [ // 字可能的颜色
37- '#117cb3' , '#f47b06' , '#202890' , '#db1821' , '#b812c2' ,
70+ fontSizeMin : 22 , // 字体尺寸最小值
71+ fontSizeMax : 26 , // 字体尺寸最大值
72+ colors : [
73+ // 字可能的颜色
74+ '#117cb3' ,
75+ '#f47b06' ,
76+ '#202890' ,
77+ '#db1821' ,
78+ '#b812c2' ,
3879 ] ,
39- fonts : [ // 可能的字体
40- 'Times New Roman' , 'Georgia' , 'Serif' , 'sans-serif' , 'arial' , 'tahoma' , 'Hiragino Sans GB' ,
80+ fonts : [
81+ // 可能的字体
82+ 'Times New Roman' ,
83+ 'Georgia' ,
84+ 'Serif' ,
85+ 'sans-serif' ,
86+ 'arial' ,
87+ 'tahoma' ,
88+ 'Hiragino Sans GB' ,
4189 ] ,
42- lines : 8 , // 生成多少根线
43- lineColors : [ // 线可能的颜色
44- '#7999e1' , '#383838' , '#ec856d' , '#008888' ,
90+ lines : 8 , // 生成多少根线
91+ lineColors : [
92+ // 线可能的颜色
93+ '#7999e1' ,
94+ '#383838' ,
95+ '#ec856d' ,
96+ '#008888' ,
4597 ] ,
4698 lineHeightMin : 1 , // 线的粗细最小值
4799 lineHeightMax : 1 , // 线的粗细最大值
@@ -63,10 +115,10 @@ class Vcode extends React.Component {
63115
64116 /** 组件参数改变 **/
65117 UNSAFE_componentWillReceiveProps ( nextP , nextS ) {
66- if ( this . props . value !== nextP . value ) {
118+ if ( this . props . value !== nextP . value ) {
67119 this . onDraw ( nextP . value ) ;
68120 }
69- if ( this . props . width !== nextP . width || this . props . height !== nextP . height ) {
121+ if ( this . props . width !== nextP . width || this . props . height !== nextP . height ) {
70122 this . setState ( {
71123 width : nextP . width ,
72124 height : nextP . height ,
@@ -78,30 +130,27 @@ class Vcode extends React.Component {
78130 onClick ( ) {
79131 const div = document . getElementById ( this . state . id ) ;
80132 // 如果this.props.value有值,表明值是外部受控,这个地方不需要重新渲染
81- let code = null ;
82- if ( ! this . props . value ) {
83- code = this . onDraw ( this . props . value ) ;
84- }
133+ let code = null ;
134+ if ( ! this . props . value ) {
135+ code = this . onDraw ( this . props . value ) ;
136+ }
85137 this . props . onClick && this . props . onClick ( ) ; // 触发外部的onClick,什么都不返回
86138 }
87139
88140 /** 随机生成一个Code的CSS样式 **/
89- codeCss ( uW , i ) {
141+ codeCss ( uW , i ) {
90142 return [
91- `font-size:${ this . randint ( this . state . options . fontSizeMin ,
92- this . state . options . fontSizeMax ) } px`,
93- `color:${ this . state . options . colors [ this . randint ( 0 ,
94- this . state . options . colors . length - 1 ) ] } `,
143+ `font-size:${ this . randint ( this . state . options . fontSizeMin , this . state . options . fontSizeMax ) } px` ,
144+ `color:${ this . state . options . colors [ this . randint ( 0 , this . state . options . colors . length - 1 ) ] } ` ,
95145 'position: absolute' ,
96- `left:${ this . randint ( uW * i , ( ( uW * i ) + uW ) - ( uW / 2 ) ) } px` ,
146+ `left:${ this . randint ( uW * i , uW * i + uW - uW / 2 ) } px` ,
97147 'top:50%' ,
98148 `transform:rotate(${ this . randint ( - 15 , 15 ) } deg) translateY(-50%)` ,
99149 `-o-transform:rotate(${ this . randint ( - 15 , 15 ) } deg) translateY(-50%)` ,
100150 `-ms-transform:rotate(${ this . randint ( - 15 , 15 ) } deg) translateY(-50%)` ,
101151 `-moz-transform:rotate(${ this . randint ( - 15 , 15 ) } deg) translateY(-50%)` ,
102152 `-webkit-transform:rotate(${ this . randint ( - 15 , 15 ) } deg) translateY(-50%)` ,
103- `font-family:${ this . state . options . fonts [ this . randint ( 0 ,
104- this . state . options . fonts . length - 1 ) ] } `,
153+ `font-family:${ this . state . options . fonts [ this . randint ( 0 , this . state . options . fonts . length - 1 ) ] } ` ,
105154 'font-weight:bold' ,
106155 'z-index:2' ,
107156 ] . join ( ';' ) ;
@@ -110,53 +159,51 @@ class Vcode extends React.Component {
110159 /** 随机生成一条线的CSS样式 **/
111160 lineCss ( ) {
112161 return [
113- 'position: absolute' ,
114- `opacity:${ this . randint ( 3 , 8 ) / 10 } ` ,
115- `width:${ this . randint ( this . state . options . lineWidthMin , this . state . options . lineWidthMax ) } px` ,
116- `height:${ this . randint ( this . state . options . lineHeightMin ,
117- this . state . options . lineHeightMax ) } px`,
118- `background:${ this . state . options . lineColors [ this . randint ( 0 ,
119- this . state . options . lineColors . length - 1 ) ] } `,
120- `left:${ this . randint ( - this . state . options . lineWidthMin / 2 , this . state . width ) } px` ,
121- `top:${ this . randint ( 0 , this . state . height ) } px` ,
122- `transform:rotate(${ this . randint ( - 30 , 30 ) } deg)` ,
123- `-o-transform:rotate(${ this . randint ( - 30 , 30 ) } deg)` ,
124- `-ms-transform:rotate(${ this . randint ( - 30 , 30 ) } deg)` ,
125- `-moz-transform:rotate(${ this . randint ( - 30 , 30 ) } deg)` ,
126- `-webkit-transform:rotate(${ this . randint ( - 30 , 30 ) } deg)` ,
127- `font-family:${ this . state . options . fonts [ this . randint ( 0 ,
128- this . state . options . fonts . length - 1 ) ] } `,
129- `font-weight:${ this . randint ( 400 , 900 ) } ` ,
130- ] . join ( ';' ) ;
162+ 'position: absolute' ,
163+ `opacity:${ this . randint ( 3 , 8 ) / 10 } ` ,
164+ `width:${ this . randint ( this . state . options . lineWidthMin , this . state . options . lineWidthMax ) } px` ,
165+ `height:${ this . randint ( this . state . options . lineHeightMin , this . state . options . lineHeightMax ) } px` ,
166+ `background:${ this . state . options . lineColors [ this . randint ( 0 , this . state . options . lineColors . length - 1 ) ] } ` ,
167+ `left:${ this . randint ( - this . state . options . lineWidthMin / 2 , this . state . width ) } px` ,
168+ `top:${ this . randint ( 0 , this . state . height ) } px` ,
169+ `transform:rotate(${ this . randint ( - 30 , 30 ) } deg)` ,
170+ `-o-transform:rotate(${ this . randint ( - 30 , 30 ) } deg)` ,
171+ `-ms-transform:rotate(${ this . randint ( - 30 , 30 ) } deg)` ,
172+ `-moz-transform:rotate(${ this . randint ( - 30 , 30 ) } deg)` ,
173+ `-webkit-transform:rotate(${ this . randint ( - 30 , 30 ) } deg)` ,
174+ `font-family:${ this . state . options . fonts [ this . randint ( 0 , this . state . options . fonts . length - 1 ) ] } ` ,
175+ `font-weight:${ this . randint ( 400 , 900 ) } ` ,
176+ ] . join ( ';' ) ;
131177 }
132178
133179 onDraw ( value ) {
134- let c = '' ; // 存储生成的code
180+ let c = '' ; // 存储生成的code
135181 const div = document . getElementById ( this . state . id ) ;
136182 const isImg = / ^ h t t p [ s ] * : \/ \/ | \. j p g $ | \. p n g $ | \. j p e g $ | \. g i f $ | \. b m p $ | \. w e b p $ | ^ d a t a : i m a g e / . test ( value ) ; // 是否是图片
137183 div . innerHTML = '' ;
138184
139- if ( isImg ) { // 用户传递了一张图片
140- const dom = document . createElement ( "img" ) ;
141- dom . style . cssText = [ "display: block" , "max-width:100%" , "max-height:100%" ] . join ( ";" ) ;
142- dom . src = value ;
143- div . appendChild ( dom ) ;
144- this . props . onChange && this . props . onChange ( null ) ;
145- return null ;
185+ if ( isImg ) {
186+ // 用户传递了一张图片
187+ const dom = document . createElement ( 'img' ) ;
188+ dom . style . cssText = [ 'display: block' , 'max-width:100%' , 'max-height:100%' ] . join ( ';' ) ;
189+ dom . src = value ;
190+ div . appendChild ( dom ) ;
191+ this . props . onChange && this . props . onChange ( null ) ;
192+ return null ;
146193 }
147194
148195 // 不是图片而是普通字符串, 如果value存在说明是用户自定义的字符串
149- let length = value . length || this . state . len ; // 字符的长度
196+ let length = value ? value . length : this . state . len ; // 字符的长度
150197
151- const uW = this . state . width / length / 1.01 ; // 每个字符占的宽度
152- for ( let i = 0 ; i < length ; i ++ ) {
153- const dom = document . createElement ( 'span' ) ;
154- dom . style . cssText = this . codeCss ( uW , i ) ;
155- const temp = value ? value [ i ] : this . state . options . codes [ ( Math . round ( Math . random ( ) * ( this . state . options . codes . length - 1 ) ) ) ] ;
156- dom . innerHTML = temp ;
157- c = `${ c } ${ temp } ` ;
158- div . appendChild ( dom ) ;
159- }
198+ const uW = this . state . width / length / 1.01 ; // 每个字符占的宽度
199+ for ( let i = 0 ; i < length ; i ++ ) {
200+ const dom = document . createElement ( 'span' ) ;
201+ dom . style . cssText = this . codeCss ( uW , i ) ;
202+ const temp = value ? value [ i ] : this . state . options . codes [ Math . round ( Math . random ( ) * ( this . state . options . codes . length - 1 ) ) ] ;
203+ dom . innerHTML = temp ;
204+ c = `${ c } ${ temp } ` ;
205+ div . appendChild ( dom ) ;
206+ }
160207
161208 // 生成好看的线条
162209 for ( let i = 0 ; i < this . state . options . lines ; i ++ ) {
@@ -165,25 +212,18 @@ class Vcode extends React.Component {
165212 div . appendChild ( dom ) ;
166213 }
167214 this . props . onChange && this . props . onChange ( c ) ; // 触发回调
168- return c ;
215+ return c ;
169216 }
170217
171218 /** 生成范围随机数 **/
172219 randint ( n , m ) {
173- const c = ( m - n ) + 1 ;
174- const num = ( Math . random ( ) * c ) + n ;
220+ const c = m - n + 1 ;
221+ const num = Math . random ( ) * c + n ;
175222 return Math . floor ( num ) ;
176223 }
177224
178225 render ( ) {
179- return (
180- < div
181- id = { this . state . id }
182- style = { this . state . style }
183- className = { this . props . className }
184- onClick = { ( ) => this . onClick ( ) }
185- />
186- ) ;
226+ return < div id = { this . state . id } style = { this . state . style } className = { this . props . className } onClick = { ( ) => this . onClick ( ) } /> ;
187227 }
188228}
189229
0 commit comments