Commit e7893a68ede3fef83accc70beabcd1ca6f4e9eff
1 parent
dab39476
update ColorPicker
Showing
12 changed files
with
994 additions
and
26 deletions
Show diff stats
.eslintignore
LICENSE
... | ... | @@ -151,4 +151,26 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
151 | 151 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
152 | 152 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
153 | 153 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
154 | -THE SOFTWARE. | |
155 | 154 | \ No newline at end of file |
155 | +THE SOFTWARE. | |
156 | + | |
157 | +The MIT License (MIT) | |
158 | + | |
159 | +Copyright (c) 2015 greyby | |
160 | + | |
161 | +Permission is hereby granted, free of charge, to any person obtaining a copy | |
162 | +of this software and associated documentation files (the "Software"), to deal | |
163 | +in the Software without restriction, including without limitation the rights | |
164 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
165 | +copies of the Software, and to permit persons to whom the Software is | |
166 | +furnished to do so, subject to the following conditions: | |
167 | + | |
168 | +The above copyright notice and this permission notice shall be included in all | |
169 | +copies or substantial portions of the Software. | |
170 | + | |
171 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
172 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
173 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
174 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
175 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
176 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
177 | +SOFTWARE. | ... | ... |
examples/routers/color-picker.vue
1 | 1 | <template> |
2 | 2 | <div style="margin: 100px;"> |
3 | + {{ color.rgba }} | |
3 | 4 | <!--<Input placeholder="请输入..." size="large" style="width: 50px;"></Input>--> |
4 | 5 | <!--<color-picker placement="bottom-start" size="large"></color-picker>--> |
5 | 6 | <!--<Date-picker type="date" placeholder="选择日期" size="large" style="width: 200px"></Date-picker>--> |
6 | - <color-picker recommend alpha placement="bottom" size="default"></color-picker> | |
7 | + <color-picker v-model="color" alpha :recommend="true" placement="bottom" size="default"></color-picker> | |
8 | + <color-picker v-model="color" :alpha="false" :recommend="false" placement="bottom" size="default"></color-picker> | |
7 | 9 | <!--<Date-picker type="date" placeholder="选择日期" style="width: 200px"></Date-picker>--> |
8 | 10 | <!--<color-picker placement="bottom-start" size="small"></color-picker>--> |
9 | 11 | <!--<Date-picker type="date" placeholder="选择日期" size="small" style="width: 200px"></Date-picker>--> |
... | ... | @@ -13,7 +15,30 @@ |
13 | 15 | export default { |
14 | 16 | props: {}, |
15 | 17 | data () { |
16 | - return {}; | |
18 | + return { | |
19 | + color: { | |
20 | + hex: '#194d33', | |
21 | + hsl: { | |
22 | + h: 150, | |
23 | + s: 0.5, | |
24 | + l: 0.2, | |
25 | + a: 1 | |
26 | + }, | |
27 | + hsv: { | |
28 | + h: 150, | |
29 | + s: 0.66, | |
30 | + v: 0.30, | |
31 | + a: 1 | |
32 | + }, | |
33 | + rgba: { | |
34 | + r: 25, | |
35 | + g: 77, | |
36 | + b: 51, | |
37 | + a: 1 | |
38 | + }, | |
39 | + a: 1 | |
40 | + } | |
41 | + }; | |
17 | 42 | }, |
18 | 43 | computed: {}, |
19 | 44 | methods: {} | ... | ... |
package-lock.json
1 | 1 | { |
2 | 2 | "name": "iview", |
3 | - "version": "2.0.0-rc.18", | |
3 | + "version": "2.1.0", | |
4 | 4 | "lockfileVersion": 1, |
5 | 5 | "requires": true, |
6 | 6 | "dependencies": { |
... | ... | @@ -15043,6 +15043,11 @@ |
15043 | 15043 | "setimmediate": "1.0.5" |
15044 | 15044 | } |
15045 | 15045 | }, |
15046 | + "tinycolor2": { | |
15047 | + "version": "1.4.1", | |
15048 | + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz", | |
15049 | + "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=" | |
15050 | + }, | |
15046 | 15051 | "tmp": { |
15047 | 15052 | "version": "0.0.31", |
15048 | 15053 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", | ... | ... |
package.json
1 | +<template> | |
2 | + <div class="ivu-color-picker-alpha"> | |
3 | + <div class="ivu-color-picker-alpha-checkboard-wrap"> | |
4 | + <div class="ivu-color-picker-alpha-checkerboard"></div> | |
5 | + </div> | |
6 | + <div class="ivu-color-picker-alpha-gradient" :style="{background: gradientColor}"></div> | |
7 | + <div class="ivu-color-picker-alpha-container" ref="container" | |
8 | + @mousedown="handleMouseDown" | |
9 | + @touchmove="handleChange" | |
10 | + @touchstart="handleChange"> | |
11 | + <div class="ivu-color-picker-alpha-pointer" :style="{left: colors.a * 100 + '%'}"> | |
12 | + <div class="ivu-color-picker-alpha-picker"></div> | |
13 | + </div> | |
14 | + </div> | |
15 | + </div> | |
16 | +</template> | |
17 | +<script> | |
18 | + export default { | |
19 | + name: 'Alpha', | |
20 | + props: { | |
21 | + value: Object, | |
22 | + onChange: Function | |
23 | + }, | |
24 | + computed: { | |
25 | + colors () { | |
26 | + return this.value; | |
27 | + }, | |
28 | + gradientColor () { | |
29 | + const rgba = this.colors.rgba; | |
30 | + const rgbStr = [rgba.r, rgba.g, rgba.b].join(','); | |
31 | + return 'linear-gradient(to right, rgba(' + rgbStr + ', 0) 0%, rgba(' + rgbStr + ', 1) 100%)'; | |
32 | + } | |
33 | + }, | |
34 | + methods: { | |
35 | + handleChange (e, skip) { | |
36 | + !skip && e.preventDefault(); | |
37 | + const container = this.$refs.container; | |
38 | + const containerWidth = container.clientWidth; | |
39 | + | |
40 | + const xOffset = container.getBoundingClientRect().left + window.pageXOffset; | |
41 | + const pageX = e.pageX || (e.touches ? e.touches[0].pageX : 0); | |
42 | + const left = pageX - xOffset; | |
43 | + | |
44 | + let a; | |
45 | + if (left < 0) { | |
46 | + a = 0; | |
47 | + } else if (left > containerWidth) { | |
48 | + a = 1; | |
49 | + } else { | |
50 | + a = Math.round(left * 100 / containerWidth) / 100; | |
51 | + } | |
52 | + | |
53 | + if (this.colors.a !== a) { | |
54 | + this.$emit('change', { | |
55 | + h: this.colors.hsl.h, | |
56 | + s: this.colors.hsl.s, | |
57 | + l: this.colors.hsl.l, | |
58 | + a: a, | |
59 | + source: 'rgba' | |
60 | + }); | |
61 | + } | |
62 | + }, | |
63 | + handleMouseDown (e) { | |
64 | + this.handleChange(e, true); | |
65 | + window.addEventListener('mousemove', this.handleChange); | |
66 | + window.addEventListener('mouseup', this.handleMouseUp); | |
67 | + }, | |
68 | + handleMouseUp () { | |
69 | + this.unbindEventListeners(); | |
70 | + }, | |
71 | + unbindEventListeners () { | |
72 | + window.removeEventListener('mousemove', this.handleChange); | |
73 | + window.removeEventListener('mouseup', this.handleMouseUp); | |
74 | + } | |
75 | + } | |
76 | + }; | |
77 | +</script> | |
0 | 78 | \ No newline at end of file | ... | ... |
src/components/color-picker/color-picker.vue
... | ... | @@ -8,12 +8,14 @@ |
8 | 8 | </div> |
9 | 9 | <Dropdown-menu slot="list"> |
10 | 10 | <div :class="[prefixCls + '-picker']"> |
11 | - <div :class="[prefixCls + '-picker-panel']"></div> | |
11 | + <div :class="[prefixCls + '-picker-panel']"> | |
12 | + <Saturation v-model="saturationColors" @change="childChange"></Saturation> | |
13 | + </div> | |
12 | 14 | <div :class="[prefixCls + '-picker-hue-slider']"> |
13 | - <Slider v-model="hueNumber" :min="0" :max="255"></Slider> | |
15 | + <Hue v-model="saturationColors" @change="childChange"></Hue> | |
14 | 16 | </div> |
15 | 17 | <div v-if="alpha" :class="[prefixCls + '-picker-alpha-slider']"> |
16 | - <Slider v-model="alphaNumber" :min="0" :max="100"></Slider> | |
18 | + <Alpha v-model="saturationColors" @change="childChange"></Alpha> | |
17 | 19 | </div> |
18 | 20 | <recommend-colors v-if="colors.length" :list="colors" :class="[prefixCls + '-picker-colors']"></recommend-colors> |
19 | 21 | <recommend-colors v-if="!colors.length && recommend" :list="recommendedColor" :class="[prefixCls + '-picker-colors']"></recommend-colors> |
... | ... | @@ -23,22 +25,76 @@ |
23 | 25 | </Dropdown> |
24 | 26 | </template> |
25 | 27 | <script> |
28 | + import tinycolor from 'tinycolor2'; | |
29 | + | |
26 | 30 | import Dropdown from '../dropdown/dropdown.vue'; |
27 | 31 | import DropdownMenu from '../dropdown/dropdown-menu.vue'; |
28 | - import Slider from '../slider/slider.vue'; | |
29 | 32 | import RecommendColors from './recommend-colors.vue'; |
30 | 33 | import Confirm from '../date-picker/base/confirm.vue'; |
34 | + | |
35 | + import Saturation from './saturation.vue'; | |
36 | + import Hue from './hue.vue'; | |
37 | + import Alpha from './alpha.vue'; | |
38 | + | |
31 | 39 | import { oneOf } from '../../utils/assist'; |
32 | 40 | |
33 | 41 | const prefixCls = 'ivu-color-picker'; |
34 | 42 | const inputPrefixCls = 'ivu-input'; |
35 | 43 | |
44 | + function _colorChange (data, oldHue) { | |
45 | + const alpha = data && data.a; | |
46 | + let color; | |
47 | + | |
48 | + // hsl is better than hex between conversions | |
49 | + if (data && data.hsl) { | |
50 | + color = tinycolor(data.hsl); | |
51 | + } else if (data && data.hex && data.hex.length > 0) { | |
52 | + color = tinycolor(data.hex); | |
53 | + } else { | |
54 | + color = tinycolor(data); | |
55 | + } | |
56 | + | |
57 | + if (color && (color._a === undefined || color._a === null)) { | |
58 | + color.setAlpha(alpha || 1); | |
59 | + } | |
60 | + | |
61 | + const hsl = color.toHsl(); | |
62 | + const hsv = color.toHsv(); | |
63 | + | |
64 | + if (hsl.s === 0) { | |
65 | + hsv.h = hsl.h = data.h || (data.hsl && data.hsl.h) || oldHue || 0; | |
66 | + } | |
67 | + | |
68 | + // when the hsv.v is less than 0.0164 (base on test) | |
69 | + // because of possible loss of precision | |
70 | + // the result of hue and saturation would be miscalculated | |
71 | + if (hsv.v < 0.0164) { | |
72 | + hsv.h = data.h || (data.hsv && data.hsv.h) || 0; | |
73 | + hsv.s = data.s || (data.hsv && data.hsv.s) || 0; | |
74 | + } | |
75 | + | |
76 | + if (hsl.l < 0.01) { | |
77 | + hsl.h = data.h || (data.hsl && data.hsl.h) || 0; | |
78 | + hsl.s = data.s || (data.hsl && data.hsl.s) || 0; | |
79 | + } | |
80 | + | |
81 | + return { | |
82 | + hsl: hsl, | |
83 | + hex: color.toHexString().toUpperCase(), | |
84 | + rgba: color.toRgb(), | |
85 | + hsv: hsv, | |
86 | + oldHue: data.h || oldHue || hsl.h, | |
87 | + source: data.source, | |
88 | + a: data.a || color.getAlpha() | |
89 | + }; | |
90 | + } | |
91 | + | |
36 | 92 | export default { |
37 | 93 | name: 'ColorPicker', |
38 | - components: { Dropdown, DropdownMenu, Slider, Confirm, RecommendColors }, | |
94 | + components: { Dropdown, DropdownMenu, Confirm, RecommendColors, Saturation, Hue, Alpha }, | |
39 | 95 | props: { |
40 | 96 | value: { |
41 | - type: String | |
97 | + type: Object | |
42 | 98 | }, |
43 | 99 | alpha: { |
44 | 100 | type: Boolean, |
... | ... | @@ -81,10 +137,8 @@ |
81 | 137 | }, |
82 | 138 | data () { |
83 | 139 | return { |
140 | + val: _colorChange(this.value), | |
84 | 141 | prefixCls: prefixCls, |
85 | - currentValue: this.value, | |
86 | - hueNumber: 0, | |
87 | - alphaNumber: 0, | |
88 | 142 | recommendedColor: [ |
89 | 143 | '#2d8cf0', |
90 | 144 | '#19be6b', |
... | ... | @@ -110,6 +164,15 @@ |
110 | 164 | }; |
111 | 165 | }, |
112 | 166 | computed: { |
167 | + saturationColors: { | |
168 | + get () { | |
169 | + return this.val; | |
170 | + }, | |
171 | + set (newVal) { | |
172 | + this.val = newVal; | |
173 | + this.$emit('input', newVal); | |
174 | + } | |
175 | + }, | |
113 | 176 | wrapClasses () { |
114 | 177 | return [ |
115 | 178 | `${prefixCls}-rel`, |
... | ... | @@ -129,8 +192,41 @@ |
129 | 192 | ]; |
130 | 193 | } |
131 | 194 | }, |
195 | + watch: { | |
196 | + value (newVal) { | |
197 | + this.val = _colorChange(newVal); | |
198 | + } | |
199 | + }, | |
132 | 200 | methods: { |
201 | + childChange (data) { | |
202 | + this.colorChange(data); | |
203 | + }, | |
204 | + colorChange (data, oldHue) { | |
205 | + this.oldHue = this.saturationColors.hsl.h; | |
206 | + this.saturationColors = _colorChange(data, oldHue || this.oldHue); | |
207 | + }, | |
208 | + isValidHex (hex) { | |
209 | + return tinycolor(hex).isValid(); | |
210 | + }, | |
211 | + simpleCheckForValidColor (data) { | |
212 | + const keysToCheck = ['r', 'g', 'b', 'a', 'h', 's', 'l', 'v']; | |
213 | + let checked = 0; | |
214 | + let passed = 0; | |
133 | 215 | |
216 | + for (let i = 0; i < keysToCheck.length; i++) { | |
217 | + const letter = keysToCheck[i]; | |
218 | + if (data[letter]) { | |
219 | + checked++; | |
220 | + if (!isNaN(data[letter])) { | |
221 | + passed++; | |
222 | + } | |
223 | + } | |
224 | + } | |
225 | + | |
226 | + if (checked === passed) { | |
227 | + return data; | |
228 | + } | |
229 | + } | |
134 | 230 | } |
135 | 231 | }; |
136 | 232 | </script> |
137 | 233 | \ No newline at end of file | ... | ... |
src/components/color-picker/color.js deleted
1 | +<template> | |
2 | + <div class="ivu-color-picker-hue"> | |
3 | + <div class="ivu-color-picker-hue-container" ref="container" | |
4 | + @mousedown="handleMouseDown" | |
5 | + @touchmove="handleChange" | |
6 | + @touchstart="handleChange"> | |
7 | + <div class="ivu-color-picker-hue-pointer" :style="{top: 0, left: pointerLeft}"> | |
8 | + <div class="ivu-color-picker-hue-picker"></div> | |
9 | + </div> | |
10 | + </div> | |
11 | + </div> | |
12 | +</template> | |
13 | +<script> | |
14 | + export default { | |
15 | + name: 'Hue', | |
16 | + props: { | |
17 | + value: Object | |
18 | + }, | |
19 | + data () { | |
20 | + return { | |
21 | + oldHue: 0, | |
22 | + pullDirection: '' | |
23 | + }; | |
24 | + }, | |
25 | + computed: { | |
26 | + colors () { | |
27 | + const h = this.value.hsl.h; | |
28 | + if (h !== 0 && h - this.oldHue > 0) this.pullDirection = 'right'; | |
29 | + if (h !== 0 && h - this.oldHue < 0) this.pullDirection = 'left'; | |
30 | + this.oldHue = h; | |
31 | + | |
32 | + return this.value; | |
33 | + }, | |
34 | + pointerLeft () { | |
35 | + if (this.colors.hsl.h === 0 && this.pullDirection === 'right') return '100%'; | |
36 | + return (this.colors.hsl.h * 100) / 360 + '%'; | |
37 | + } | |
38 | + }, | |
39 | + methods: { | |
40 | + handleChange (e, skip) { | |
41 | + !skip && e.preventDefault(); | |
42 | + | |
43 | + const container = this.$refs.container; | |
44 | + const containerWidth = container.clientWidth; | |
45 | + | |
46 | + const xOffset = container.getBoundingClientRect().left + window.pageXOffset; | |
47 | + const pageX = e.pageX || (e.touches ? e.touches[0].pageX : 0); | |
48 | + const left = pageX - xOffset; | |
49 | + | |
50 | + let h; | |
51 | + let percent; | |
52 | + | |
53 | + if (left < 0) { | |
54 | + h = 0; | |
55 | + } else if (left > containerWidth) { | |
56 | + h = 360; | |
57 | + } else { | |
58 | + percent = left * 100 / containerWidth; | |
59 | + h = (360 * percent / 100); | |
60 | + } | |
61 | + | |
62 | + if (this.colors.hsl.h !== h) { | |
63 | + this.$emit('change', { | |
64 | + h: h, | |
65 | + s: this.colors.hsl.s, | |
66 | + l: this.colors.hsl.l, | |
67 | + a: this.colors.hsl.a, | |
68 | + source: 'hsl' | |
69 | + }); | |
70 | + } | |
71 | + }, | |
72 | + handleMouseDown (e) { | |
73 | + this.handleChange(e, true); | |
74 | + window.addEventListener('mousemove', this.handleChange); | |
75 | + window.addEventListener('mouseup', this.handleMouseUp); | |
76 | + }, | |
77 | + handleMouseUp () { | |
78 | + this.unbindEventListeners(); | |
79 | + }, | |
80 | + unbindEventListeners () { | |
81 | + window.removeEventListener('mousemove', this.handleChange); | |
82 | + window.removeEventListener('mouseup', this.handleMouseUp); | |
83 | + } | |
84 | + } | |
85 | + }; | |
86 | +</script> | |
0 | 87 | \ No newline at end of file | ... | ... |
1 | +<template> | |
2 | + <div class="ivu-color-picker-saturation-wrapper"> | |
3 | + <div | |
4 | + class="ivu-color-picker-saturation" | |
5 | + :style="{background: bgColor}" | |
6 | + ref="container" | |
7 | + @mousedown="handleMouseDown"> | |
8 | + <div class="ivu-color-picker-saturation--white"></div> | |
9 | + <div class="ivu-color-picker-saturation--black"></div> | |
10 | + <div class="ivu-color-picker-saturation-pointer" :style="{top: pointerTop, left: pointerLeft}"> | |
11 | + <div class="ivu-color-picker-saturation-circle"></div> | |
12 | + </div> | |
13 | + </div> | |
14 | + </div> | |
15 | +</template> | |
16 | +<script> | |
17 | + import throttle from '../../utils/throttle'; | |
18 | + | |
19 | + export default { | |
20 | + name: 'Saturation', | |
21 | + props: { | |
22 | + value: Object | |
23 | + }, | |
24 | + data () { | |
25 | + return {}; | |
26 | + }, | |
27 | + computed: { | |
28 | + colors () { | |
29 | + return this.value; | |
30 | + }, | |
31 | + bgColor () { | |
32 | + return `hsl(${this.colors.hsv.h}, 100%, 50%)`; | |
33 | + }, | |
34 | + pointerTop () { | |
35 | + return (-(this.colors.hsv.v * 100) + 1) + 100 + '%'; | |
36 | + }, | |
37 | + pointerLeft () { | |
38 | + return this.colors.hsv.s * 100 + '%'; | |
39 | + } | |
40 | + }, | |
41 | + methods: { | |
42 | + throttle: throttle((fn, data) => {fn(data);}, 20, | |
43 | + { | |
44 | + 'leading': true, | |
45 | + 'trailing': false | |
46 | + }), | |
47 | + handleChange (e, skip) { | |
48 | + !skip && e.preventDefault(); | |
49 | + const container = this.$refs.container; | |
50 | + const containerWidth = container.clientWidth; | |
51 | + const containerHeight = container.clientHeight; | |
52 | + const xOffset = container.getBoundingClientRect().left + window.pageXOffset; | |
53 | + const yOffset = container.getBoundingClientRect().top + window.pageYOffset; | |
54 | + const pageX = e.pageX || (e.touches ? e.touches[0].pageX : 0); | |
55 | + const pageY = e.pageY || (e.touches ? e.touches[0].pageY : 0); | |
56 | + let left = pageX - xOffset; | |
57 | + let top = pageY - yOffset; | |
58 | + if (left < 0) { | |
59 | + left = 0; | |
60 | + } else if (left > containerWidth) { | |
61 | + left = containerWidth; | |
62 | + } else if (top < 0) { | |
63 | + top = 0; | |
64 | + } else if (top > containerHeight) { | |
65 | + top = containerHeight; | |
66 | + } | |
67 | + const saturation = left / containerWidth; | |
68 | + let bright = -(top / containerHeight) + 1; | |
69 | + bright = bright > 0 ? bright : 0; | |
70 | + bright = bright > 1 ? 1 : bright; | |
71 | + this.throttle(this.onChange, { | |
72 | + h: this.colors.hsv.h, | |
73 | + s: saturation, | |
74 | + v: bright, | |
75 | + a: this.colors.hsv.a, | |
76 | + source: 'hsva' | |
77 | + }); | |
78 | + }, | |
79 | + onChange (param) { | |
80 | + this.$emit('change', param); | |
81 | + }, | |
82 | + handleMouseDown () { | |
83 | + // this.handleChange(e, true) | |
84 | + window.addEventListener('mousemove', this.handleChange); | |
85 | + window.addEventListener('mouseup', this.handleChange); | |
86 | + window.addEventListener('mouseup', this.handleMouseUp); | |
87 | + }, | |
88 | + handleMouseUp () { | |
89 | + this.unbindEventListeners(); | |
90 | + }, | |
91 | + unbindEventListeners () { | |
92 | + window.removeEventListener('mousemove', this.handleChange); | |
93 | + window.removeEventListener('mouseup', this.handleChange); | |
94 | + window.removeEventListener('mouseup', this.handleMouseUp); | |
95 | + } | |
96 | + } | |
97 | + }; | |
98 | +</script> | |
0 | 99 | \ No newline at end of file | ... | ... |
src/styles/components/color-picker.less
... | ... | @@ -24,30 +24,31 @@ |
24 | 24 | } |
25 | 25 | |
26 | 26 | &-picker{ |
27 | - padding: 8px 8px 0; | |
27 | + padding: 4px 8px 0; | |
28 | 28 | &-panel{ |
29 | 29 | width: 200px; |
30 | - height: 200px; | |
31 | 30 | margin: 0 auto; |
32 | - background: #47cb89; | |
33 | - border-radius: 50%; | |
34 | - } | |
35 | - &-hue-slider{ | |
36 | - | |
31 | + box-sizing: initial; | |
32 | + position: relative; | |
37 | 33 | } |
38 | - &-alpha-slider{ | |
39 | - | |
34 | + &-hue-slider, &-alpha-slider{ | |
35 | + height: 10px; | |
36 | + margin-top: 8px; | |
37 | + position: relative; | |
40 | 38 | } |
41 | 39 | &-colors{ |
42 | 40 | margin-top: 8px; |
41 | + overflow: hidden; | |
43 | 42 | span{ |
44 | 43 | display: inline-block; |
45 | - width: 18px; | |
46 | - height: 18px; | |
44 | + width: 20px; | |
45 | + height: 20px; | |
46 | + float: left; | |
47 | 47 | em{ |
48 | 48 | display: block; |
49 | 49 | width: 16px; |
50 | 50 | height: 16px; |
51 | + margin: 2px; | |
51 | 52 | cursor: pointer; |
52 | 53 | border-radius: 2px; |
53 | 54 | box-shadow: inset 0 0 0 1px rgba(0,0,0,.15); |
... | ... | @@ -58,4 +59,121 @@ |
58 | 59 | margin-top: 8px; |
59 | 60 | } |
60 | 61 | } |
62 | + | |
63 | + &-saturation{ | |
64 | + &-wrapper{ | |
65 | + width: 100%; | |
66 | + padding-bottom: 75%; | |
67 | + position: relative; | |
68 | + overflow: hidden; | |
69 | + } | |
70 | + &, &--white, &--black{ | |
71 | + cursor: pointer; | |
72 | + position: absolute; | |
73 | + top: 0; | |
74 | + left: 0; | |
75 | + right: 0; | |
76 | + bottom: 0; | |
77 | + } | |
78 | + &--white{ | |
79 | + background: linear-gradient(to right, #fff, rgba(255,255,255,0)); | |
80 | + } | |
81 | + &--black{ | |
82 | + background: linear-gradient(to top, #000, rgba(0,0,0,0)); | |
83 | + } | |
84 | + &-pointer{ | |
85 | + cursor: pointer; | |
86 | + position: absolute; | |
87 | + } | |
88 | + &-circle{ | |
89 | + cursor: head; | |
90 | + width: 4px; | |
91 | + height: 4px; | |
92 | + box-shadow: 0 0 0 1.5px #fff, inset 0 0 1px 1px rgba(0,0,0,.3), 0 0 1px 2px rgba(0,0,0,.4); | |
93 | + border-radius: 50%; | |
94 | + transform: translate(-2px, -2px); | |
95 | + } | |
96 | + } | |
97 | + | |
98 | + &-hue{ | |
99 | + position: absolute; | |
100 | + top: 0; | |
101 | + right: 0; | |
102 | + bottom: 0; | |
103 | + left: 0; | |
104 | + border-radius: 2px; | |
105 | + background: linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%); | |
106 | + &-container{ | |
107 | + cursor: pointer; | |
108 | + margin: 0 2px; | |
109 | + position: relative; | |
110 | + height: 100%; | |
111 | + } | |
112 | + &-pointer{ | |
113 | + z-index: 2; | |
114 | + position: absolute; | |
115 | + } | |
116 | + &-picker{ | |
117 | + cursor: pointer; | |
118 | + margin-top: 1px; | |
119 | + width: 4px; | |
120 | + border-radius: 1px; | |
121 | + height: 8px; | |
122 | + box-shadow: 0 0 2px rgba(0, 0, 0, .6); | |
123 | + background: #fff; | |
124 | + transform: translateX(-2px); | |
125 | + } | |
126 | + } | |
127 | + | |
128 | + &-alpha{ | |
129 | + position: absolute; | |
130 | + top: 0; | |
131 | + right: 0; | |
132 | + bottom: 0; | |
133 | + left: 0; | |
134 | + &-checkboard-wrap{ | |
135 | + position: absolute; | |
136 | + top: 0; | |
137 | + right: 0; | |
138 | + bottom: 0; | |
139 | + left: 0; | |
140 | + overflow: hidden; | |
141 | + } | |
142 | + &-checkerboard{ | |
143 | + position: absolute; | |
144 | + top: 0; | |
145 | + right: 0; | |
146 | + bottom: 0; | |
147 | + left: 0; | |
148 | + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==); | |
149 | + } | |
150 | + &-gradient{ | |
151 | + position: absolute; | |
152 | + top: 0; | |
153 | + right: 0; | |
154 | + bottom: 0; | |
155 | + left: 0; | |
156 | + } | |
157 | + &-container{ | |
158 | + cursor: pointer; | |
159 | + position: relative; | |
160 | + z-index: 2; | |
161 | + height: 100%; | |
162 | + margin: 0 3px; | |
163 | + } | |
164 | + &-pointer{ | |
165 | + z-index: 2; | |
166 | + position: absolute; | |
167 | + } | |
168 | + &-picker{ | |
169 | + cursor: pointer; | |
170 | + width: 4px; | |
171 | + border-radius: 1px; | |
172 | + height: 8px; | |
173 | + box-shadow: 0 0 2px rgba(0, 0, 0, .6); | |
174 | + background: #fff; | |
175 | + margin-top: 1px; | |
176 | + transform: translateX(-2px); | |
177 | + } | |
178 | + } | |
61 | 179 | } |
62 | 180 | \ No newline at end of file | ... | ... |
1 | +/** | |
2 | + * lodash (Custom Build) <https://lodash.com/> | |
3 | + * Build: `lodash modularize exports="npm" -o ./` | |
4 | + * Copyright jQuery Foundation and other contributors <https://jquery.org/> | |
5 | + * Released under MIT license <https://lodash.com/license> | |
6 | + * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE> | |
7 | + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors | |
8 | + */ | |
9 | + | |
10 | +/** Used as the `TypeError` message for "Functions" methods. */ | |
11 | +var FUNC_ERROR_TEXT = 'Expected a function'; | |
12 | + | |
13 | +/** Used as references for various `Number` constants. */ | |
14 | +var NAN = 0 / 0; | |
15 | + | |
16 | +/** `Object#toString` result references. */ | |
17 | +var symbolTag = '[object Symbol]'; | |
18 | + | |
19 | +/** Used to match leading and trailing whitespace. */ | |
20 | +var reTrim = /^\s+|\s+$/g; | |
21 | + | |
22 | +/** Used to detect bad signed hexadecimal string values. */ | |
23 | +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; | |
24 | + | |
25 | +/** Used to detect binary string values. */ | |
26 | +var reIsBinary = /^0b[01]+$/i; | |
27 | + | |
28 | +/** Used to detect octal string values. */ | |
29 | +var reIsOctal = /^0o[0-7]+$/i; | |
30 | + | |
31 | +/** Built-in method references without a dependency on `root`. */ | |
32 | +var freeParseInt = parseInt; | |
33 | + | |
34 | +/** Detect free variable `global` from Node.js. */ | |
35 | +var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; | |
36 | + | |
37 | +/** Detect free variable `self`. */ | |
38 | +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; | |
39 | + | |
40 | +/** Used as a reference to the global object. */ | |
41 | +var root = freeGlobal || freeSelf || Function('return this')(); | |
42 | + | |
43 | +/** Used for built-in method references. */ | |
44 | +var objectProto = Object.prototype; | |
45 | + | |
46 | +/** | |
47 | + * Used to resolve the | |
48 | + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) | |
49 | + * of values. | |
50 | + */ | |
51 | +var objectToString = objectProto.toString; | |
52 | + | |
53 | +/* Built-in method references for those with the same name as other `lodash` methods. */ | |
54 | +var nativeMax = Math.max, | |
55 | + nativeMin = Math.min; | |
56 | + | |
57 | +/** | |
58 | + * Gets the timestamp of the number of milliseconds that have elapsed since | |
59 | + * the Unix epoch (1 January 1970 00:00:00 UTC). | |
60 | + * | |
61 | + * @static | |
62 | + * @memberOf _ | |
63 | + * @since 2.4.0 | |
64 | + * @category Date | |
65 | + * @returns {number} Returns the timestamp. | |
66 | + * @example | |
67 | + * | |
68 | + * _.defer(function(stamp) { | |
69 | + * console.log(_.now() - stamp); | |
70 | + * }, _.now()); | |
71 | + * // => Logs the number of milliseconds it took for the deferred invocation. | |
72 | + */ | |
73 | +var now = function() { | |
74 | + return root.Date.now(); | |
75 | +}; | |
76 | + | |
77 | +/** | |
78 | + * Creates a debounced function that delays invoking `func` until after `wait` | |
79 | + * milliseconds have elapsed since the last time the debounced function was | |
80 | + * invoked. The debounced function comes with a `cancel` method to cancel | |
81 | + * delayed `func` invocations and a `flush` method to immediately invoke them. | |
82 | + * Provide `options` to indicate whether `func` should be invoked on the | |
83 | + * leading and/or trailing edge of the `wait` timeout. The `func` is invoked | |
84 | + * with the last arguments provided to the debounced function. Subsequent | |
85 | + * calls to the debounced function return the result of the last `func` | |
86 | + * invocation. | |
87 | + * | |
88 | + * **Note:** If `leading` and `trailing` options are `true`, `func` is | |
89 | + * invoked on the trailing edge of the timeout only if the debounced function | |
90 | + * is invoked more than once during the `wait` timeout. | |
91 | + * | |
92 | + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred | |
93 | + * until to the next tick, similar to `setTimeout` with a timeout of `0`. | |
94 | + * | |
95 | + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) | |
96 | + * for details over the differences between `_.debounce` and `_.throttle`. | |
97 | + * | |
98 | + * @static | |
99 | + * @memberOf _ | |
100 | + * @since 0.1.0 | |
101 | + * @category Function | |
102 | + * @param {Function} func The function to debounce. | |
103 | + * @param {number} [wait=0] The number of milliseconds to delay. | |
104 | + * @param {Object} [options={}] The options object. | |
105 | + * @param {boolean} [options.leading=false] | |
106 | + * Specify invoking on the leading edge of the timeout. | |
107 | + * @param {number} [options.maxWait] | |
108 | + * The maximum time `func` is allowed to be delayed before it's invoked. | |
109 | + * @param {boolean} [options.trailing=true] | |
110 | + * Specify invoking on the trailing edge of the timeout. | |
111 | + * @returns {Function} Returns the new debounced function. | |
112 | + * @example | |
113 | + * | |
114 | + * // Avoid costly calculations while the window size is in flux. | |
115 | + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); | |
116 | + * | |
117 | + * // Invoke `sendMail` when clicked, debouncing subsequent calls. | |
118 | + * jQuery(element).on('click', _.debounce(sendMail, 300, { | |
119 | + * 'leading': true, | |
120 | + * 'trailing': false | |
121 | + * })); | |
122 | + * | |
123 | + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. | |
124 | + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); | |
125 | + * var source = new EventSource('/stream'); | |
126 | + * jQuery(source).on('message', debounced); | |
127 | + * | |
128 | + * // Cancel the trailing debounced invocation. | |
129 | + * jQuery(window).on('popstate', debounced.cancel); | |
130 | + */ | |
131 | +function debounce(func, wait, options) { | |
132 | + var lastArgs, | |
133 | + lastThis, | |
134 | + maxWait, | |
135 | + result, | |
136 | + timerId, | |
137 | + lastCallTime, | |
138 | + lastInvokeTime = 0, | |
139 | + leading = false, | |
140 | + maxing = false, | |
141 | + trailing = true; | |
142 | + | |
143 | + if (typeof func != 'function') { | |
144 | + throw new TypeError(FUNC_ERROR_TEXT); | |
145 | + } | |
146 | + wait = toNumber(wait) || 0; | |
147 | + if (isObject(options)) { | |
148 | + leading = !!options.leading; | |
149 | + maxing = 'maxWait' in options; | |
150 | + maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; | |
151 | + trailing = 'trailing' in options ? !!options.trailing : trailing; | |
152 | + } | |
153 | + | |
154 | + function invokeFunc(time) { | |
155 | + var args = lastArgs, | |
156 | + thisArg = lastThis; | |
157 | + | |
158 | + lastArgs = lastThis = undefined; | |
159 | + lastInvokeTime = time; | |
160 | + result = func.apply(thisArg, args); | |
161 | + return result; | |
162 | + } | |
163 | + | |
164 | + function leadingEdge(time) { | |
165 | + // Reset any `maxWait` timer. | |
166 | + lastInvokeTime = time; | |
167 | + // Start the timer for the trailing edge. | |
168 | + timerId = setTimeout(timerExpired, wait); | |
169 | + // Invoke the leading edge. | |
170 | + return leading ? invokeFunc(time) : result; | |
171 | + } | |
172 | + | |
173 | + function remainingWait(time) { | |
174 | + var timeSinceLastCall = time - lastCallTime, | |
175 | + timeSinceLastInvoke = time - lastInvokeTime, | |
176 | + result = wait - timeSinceLastCall; | |
177 | + | |
178 | + return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result; | |
179 | + } | |
180 | + | |
181 | + function shouldInvoke(time) { | |
182 | + var timeSinceLastCall = time - lastCallTime, | |
183 | + timeSinceLastInvoke = time - lastInvokeTime; | |
184 | + | |
185 | + // Either this is the first call, activity has stopped and we're at the | |
186 | + // trailing edge, the system time has gone backwards and we're treating | |
187 | + // it as the trailing edge, or we've hit the `maxWait` limit. | |
188 | + return (lastCallTime === undefined || (timeSinceLastCall >= wait) || | |
189 | + (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); | |
190 | + } | |
191 | + | |
192 | + function timerExpired() { | |
193 | + var time = now(); | |
194 | + if (shouldInvoke(time)) { | |
195 | + return trailingEdge(time); | |
196 | + } | |
197 | + // Restart the timer. | |
198 | + timerId = setTimeout(timerExpired, remainingWait(time)); | |
199 | + } | |
200 | + | |
201 | + function trailingEdge(time) { | |
202 | + timerId = undefined; | |
203 | + | |
204 | + // Only invoke if we have `lastArgs` which means `func` has been | |
205 | + // debounced at least once. | |
206 | + if (trailing && lastArgs) { | |
207 | + return invokeFunc(time); | |
208 | + } | |
209 | + lastArgs = lastThis = undefined; | |
210 | + return result; | |
211 | + } | |
212 | + | |
213 | + function cancel() { | |
214 | + if (timerId !== undefined) { | |
215 | + clearTimeout(timerId); | |
216 | + } | |
217 | + lastInvokeTime = 0; | |
218 | + lastArgs = lastCallTime = lastThis = timerId = undefined; | |
219 | + } | |
220 | + | |
221 | + function flush() { | |
222 | + return timerId === undefined ? result : trailingEdge(now()); | |
223 | + } | |
224 | + | |
225 | + function debounced() { | |
226 | + var time = now(), | |
227 | + isInvoking = shouldInvoke(time); | |
228 | + | |
229 | + lastArgs = arguments; | |
230 | + lastThis = this; | |
231 | + lastCallTime = time; | |
232 | + | |
233 | + if (isInvoking) { | |
234 | + if (timerId === undefined) { | |
235 | + return leadingEdge(lastCallTime); | |
236 | + } | |
237 | + if (maxing) { | |
238 | + // Handle invocations in a tight loop. | |
239 | + timerId = setTimeout(timerExpired, wait); | |
240 | + return invokeFunc(lastCallTime); | |
241 | + } | |
242 | + } | |
243 | + if (timerId === undefined) { | |
244 | + timerId = setTimeout(timerExpired, wait); | |
245 | + } | |
246 | + return result; | |
247 | + } | |
248 | + debounced.cancel = cancel; | |
249 | + debounced.flush = flush; | |
250 | + return debounced; | |
251 | +} | |
252 | + | |
253 | +/** | |
254 | + * Creates a throttled function that only invokes `func` at most once per | |
255 | + * every `wait` milliseconds. The throttled function comes with a `cancel` | |
256 | + * method to cancel delayed `func` invocations and a `flush` method to | |
257 | + * immediately invoke them. Provide `options` to indicate whether `func` | |
258 | + * should be invoked on the leading and/or trailing edge of the `wait` | |
259 | + * timeout. The `func` is invoked with the last arguments provided to the | |
260 | + * throttled function. Subsequent calls to the throttled function return the | |
261 | + * result of the last `func` invocation. | |
262 | + * | |
263 | + * **Note:** If `leading` and `trailing` options are `true`, `func` is | |
264 | + * invoked on the trailing edge of the timeout only if the throttled function | |
265 | + * is invoked more than once during the `wait` timeout. | |
266 | + * | |
267 | + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred | |
268 | + * until to the next tick, similar to `setTimeout` with a timeout of `0`. | |
269 | + * | |
270 | + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) | |
271 | + * for details over the differences between `_.throttle` and `_.debounce`. | |
272 | + * | |
273 | + * @static | |
274 | + * @memberOf _ | |
275 | + * @since 0.1.0 | |
276 | + * @category Function | |
277 | + * @param {Function} func The function to throttle. | |
278 | + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. | |
279 | + * @param {Object} [options={}] The options object. | |
280 | + * @param {boolean} [options.leading=true] | |
281 | + * Specify invoking on the leading edge of the timeout. | |
282 | + * @param {boolean} [options.trailing=true] | |
283 | + * Specify invoking on the trailing edge of the timeout. | |
284 | + * @returns {Function} Returns the new throttled function. | |
285 | + * @example | |
286 | + * | |
287 | + * // Avoid excessively updating the position while scrolling. | |
288 | + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); | |
289 | + * | |
290 | + * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. | |
291 | + * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); | |
292 | + * jQuery(element).on('click', throttled); | |
293 | + * | |
294 | + * // Cancel the trailing throttled invocation. | |
295 | + * jQuery(window).on('popstate', throttled.cancel); | |
296 | + */ | |
297 | +function throttle(func, wait, options) { | |
298 | + var leading = true, | |
299 | + trailing = true; | |
300 | + | |
301 | + if (typeof func != 'function') { | |
302 | + throw new TypeError(FUNC_ERROR_TEXT); | |
303 | + } | |
304 | + if (isObject(options)) { | |
305 | + leading = 'leading' in options ? !!options.leading : leading; | |
306 | + trailing = 'trailing' in options ? !!options.trailing : trailing; | |
307 | + } | |
308 | + return debounce(func, wait, { | |
309 | + 'leading': leading, | |
310 | + 'maxWait': wait, | |
311 | + 'trailing': trailing | |
312 | + }); | |
313 | +} | |
314 | + | |
315 | +/** | |
316 | + * Checks if `value` is the | |
317 | + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) | |
318 | + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) | |
319 | + * | |
320 | + * @static | |
321 | + * @memberOf _ | |
322 | + * @since 0.1.0 | |
323 | + * @category Lang | |
324 | + * @param {*} value The value to check. | |
325 | + * @returns {boolean} Returns `true` if `value` is an object, else `false`. | |
326 | + * @example | |
327 | + * | |
328 | + * _.isObject({}); | |
329 | + * // => true | |
330 | + * | |
331 | + * _.isObject([1, 2, 3]); | |
332 | + * // => true | |
333 | + * | |
334 | + * _.isObject(_.noop); | |
335 | + * // => true | |
336 | + * | |
337 | + * _.isObject(null); | |
338 | + * // => false | |
339 | + */ | |
340 | +function isObject(value) { | |
341 | + var type = typeof value; | |
342 | + return !!value && (type == 'object' || type == 'function'); | |
343 | +} | |
344 | + | |
345 | +/** | |
346 | + * Checks if `value` is object-like. A value is object-like if it's not `null` | |
347 | + * and has a `typeof` result of "object". | |
348 | + * | |
349 | + * @static | |
350 | + * @memberOf _ | |
351 | + * @since 4.0.0 | |
352 | + * @category Lang | |
353 | + * @param {*} value The value to check. | |
354 | + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. | |
355 | + * @example | |
356 | + * | |
357 | + * _.isObjectLike({}); | |
358 | + * // => true | |
359 | + * | |
360 | + * _.isObjectLike([1, 2, 3]); | |
361 | + * // => true | |
362 | + * | |
363 | + * _.isObjectLike(_.noop); | |
364 | + * // => false | |
365 | + * | |
366 | + * _.isObjectLike(null); | |
367 | + * // => false | |
368 | + */ | |
369 | +function isObjectLike(value) { | |
370 | + return !!value && typeof value == 'object'; | |
371 | +} | |
372 | + | |
373 | +/** | |
374 | + * Checks if `value` is classified as a `Symbol` primitive or object. | |
375 | + * | |
376 | + * @static | |
377 | + * @memberOf _ | |
378 | + * @since 4.0.0 | |
379 | + * @category Lang | |
380 | + * @param {*} value The value to check. | |
381 | + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. | |
382 | + * @example | |
383 | + * | |
384 | + * _.isSymbol(Symbol.iterator); | |
385 | + * // => true | |
386 | + * | |
387 | + * _.isSymbol('abc'); | |
388 | + * // => false | |
389 | + */ | |
390 | +function isSymbol(value) { | |
391 | + return typeof value == 'symbol' || | |
392 | + (isObjectLike(value) && objectToString.call(value) == symbolTag); | |
393 | +} | |
394 | + | |
395 | +/** | |
396 | + * Converts `value` to a number. | |
397 | + * | |
398 | + * @static | |
399 | + * @memberOf _ | |
400 | + * @since 4.0.0 | |
401 | + * @category Lang | |
402 | + * @param {*} value The value to process. | |
403 | + * @returns {number} Returns the number. | |
404 | + * @example | |
405 | + * | |
406 | + * _.toNumber(3.2); | |
407 | + * // => 3.2 | |
408 | + * | |
409 | + * _.toNumber(Number.MIN_VALUE); | |
410 | + * // => 5e-324 | |
411 | + * | |
412 | + * _.toNumber(Infinity); | |
413 | + * // => Infinity | |
414 | + * | |
415 | + * _.toNumber('3.2'); | |
416 | + * // => 3.2 | |
417 | + */ | |
418 | +function toNumber(value) { | |
419 | + if (typeof value == 'number') { | |
420 | + return value; | |
421 | + } | |
422 | + if (isSymbol(value)) { | |
423 | + return NAN; | |
424 | + } | |
425 | + if (isObject(value)) { | |
426 | + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; | |
427 | + value = isObject(other) ? (other + '') : other; | |
428 | + } | |
429 | + if (typeof value != 'string') { | |
430 | + return value === 0 ? value : +value; | |
431 | + } | |
432 | + value = value.replace(reTrim, ''); | |
433 | + var isBinary = reIsBinary.test(value); | |
434 | + return (isBinary || reIsOctal.test(value)) | |
435 | + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) | |
436 | + : (reIsBadHex.test(value) ? NAN : +value); | |
437 | +} | |
438 | + | |
439 | +module.exports = throttle; | ... | ... |