From 441669f081fbf0e303856ff1cc1c826a18402fc3 Mon Sep 17 00:00:00 2001 From: Harlan Date: Mon, 19 Mar 2018 17:20:09 +0800 Subject: [PATCH] ColorPicker: add predefine colors (#10170) * ColorPicker: add predefine colors(#8702) * Add selected state of predefine color and test cases * Fix the bugs mentioned in review --- examples/docs/en-US/color-picker.md | 45 ++++++++- examples/docs/es/color-picker.md | 44 ++++++++- examples/docs/zh-CN/color-picker.md | 44 ++++++++- packages/color-picker/src/color.js | 23 ++++- .../src/components/picker-dropdown.vue | 8 +- .../color-picker/src/components/predefine.vue | 62 ++++++++++++ packages/color-picker/src/main.vue | 6 +- packages/theme-chalk/src/color-picker.scss | 34 +++++++ test/unit/specs/color-picker.spec.js | 94 +++++++++++++++++++ 9 files changed, 351 insertions(+), 9 deletions(-) create mode 100644 packages/color-picker/src/components/predefine.vue diff --git a/examples/docs/en-US/color-picker.md b/examples/docs/en-US/color-picker.md index 1709b51d3..8cc197138 100644 --- a/examples/docs/en-US/color-picker.md +++ b/examples/docs/en-US/color-picker.md @@ -5,7 +5,19 @@ color1: '#409EFF', color2: null, color3: 'rgba(19, 206, 102, 0.8)', - color4: '#409EFF' + color4: '#409EFF', + color5: 'hsva(180, 65, 20, 0.5)', + predefineColors: [ + 'rgba(19, 206, 102, 0.18)', + 'rgb(25, 159, 147)', + 'hsv(250, 54, 98)', + 'hsva(180, 65, 20, 0.5)', + 'hsl(170, 32%, 87%)', + 'hsla(45, 62%, 47%, 0.13)', + '#7486de', + '#45aa9477', + '#892345' + ] }; }, mounted() { @@ -88,6 +100,36 @@ ColorPicker is a color selector supporting multiple color formats. ``` ::: +### Predefine colors + +:::demo ColorPicker supports predefine colors +```html + + + +``` +::: + + ### Sizes :::demo @@ -117,6 +159,7 @@ ColorPicker is a color selector supporting multiple color formats. | show-alpha | whether to display the alpha slider | boolean | — | false | | color-format | color format of v-model | string | hsl / hsv / hex / rgb | hex (when show-alpha is false)/ rgb (when show-alpha is true) | | popper-class | custom class name for ColorPicker's dropdown | string | — | — | +| predefine | predefine some colors | array | — | — | ### Events | Event Name | Description | Parameters | diff --git a/examples/docs/es/color-picker.md b/examples/docs/es/color-picker.md index 040bb17a9..826bfe06c 100644 --- a/examples/docs/es/color-picker.md +++ b/examples/docs/es/color-picker.md @@ -5,7 +5,19 @@ color1: '#409EFF', color2: null, color3: 'rgba(19, 206, 102, 0.8)', - color4: '#409EFF' + color4: '#409EFF', + color5: 'hsva(180, 65, 20, 0.5)', + predefineColors: [ + 'rgba(19, 206, 102, 0.18)', + 'rgb(25, 159, 147)', + 'hsv(250, 54, 98)', + 'hsva(180, 65, 20, 0.5)', + 'hsl(170, 32%, 87%)', + 'hsla(45, 62%, 47%, 0.13)', + '#7486de', + '#45aa9477', + '#892345' + ] }; }, mounted() { @@ -88,6 +100,35 @@ ColorPicker es un selector de color que soporta varios formatos de color. ``` ::: +### Colores predefinidos + +:::demo ColorPicker admite colores predefinidos +```html + + + +``` +::: + ### Sizes :::demo @@ -117,6 +158,7 @@ ColorPicker es un selector de color que soporta varios formatos de color. | show-alpha | especifica si se muestra el control deslizante para el valor alpha | boolean | — | false | | color-format | formato de color del `v-model` | string | hsl / hsv / hex / rgb | hex (si show-alpha es false)/ rgb (si show-alpha es true) | | popper-class | nombre de clase para el dropdown del ColorPicker | string | — | — | +| predefine | colores predefinidos | array | — | — | ### Eventos | Nombre de Evento | Descripción | Parametros | diff --git a/examples/docs/zh-CN/color-picker.md b/examples/docs/zh-CN/color-picker.md index 666bcfaf2..e9d6a8dc3 100644 --- a/examples/docs/zh-CN/color-picker.md +++ b/examples/docs/zh-CN/color-picker.md @@ -5,7 +5,19 @@ color1: '#409EFF', color2: null, color3: 'rgba(19, 206, 102, 0.8)', - color4: '#409EFF' + color4: '#409EFF', + color5: 'hsva(180, 65, 20, 0.5)', + predefineColors: [ + 'rgba(19, 206, 102, 0.18)', + 'rgb(25, 159, 147)', + 'hsv(250, 54, 98)', + 'hsva(180, 65, 20, 0.5)', + 'hsl(170, 32%, 87%)', + 'hsla(45, 62%, 47%, 0.13)', + '#7486de', + '#45aa9477', + '#892345' + ] }; }, mounted() { @@ -88,6 +100,35 @@ ``` ::: +### 预定义颜色 + +:::demo ColorPicker 支持预定义颜色 +```html + + + +``` +::: + ### 不同尺寸 :::demo @@ -117,6 +158,7 @@ | show-alpha | 是否支持透明度选择 | boolean | — | false | | color-format | 写入 v-model 的颜色的格式 | string | hsl / hsv / hex / rgb | hex(show-alpha 为 false)/ rgb(show-alpha 为 true) | | popper-class | ColorPicker 下拉框的类名 | string | — | — | +| predefine | 预定义颜色 | array | — | — | ### Events | 事件名称 | 说明 | 回调参数 | diff --git a/packages/color-picker/src/color.js b/packages/color-picker/src/color.js index a33e9482f..8dee3c84d 100644 --- a/packages/color-picker/src/color.js +++ b/packages/color-picker/src/color.js @@ -215,6 +215,8 @@ export default class Color { if (parts.length === 4) { this._alpha = Math.floor(parseFloat(parts[3]) * 100); + } else if (parts.length === 3) { + this._alpha = 100; } if (parts.length >= 3) { const { h, s, v } = hsl2hsv(parts[0], parts[1], parts[2]); @@ -226,6 +228,8 @@ export default class Color { if (parts.length === 4) { this._alpha = Math.floor(parseFloat(parts[3]) * 100); + } else if (parts.length === 3) { + this._alpha = 100; } if (parts.length >= 3) { fromHSV(parts[0], parts[1], parts[2]); @@ -236,6 +240,8 @@ export default class Color { if (parts.length === 4) { this._alpha = Math.floor(parseFloat(parts[3]) * 100); + } else if (parts.length === 3) { + this._alpha = 100; } if (parts.length >= 3) { const { h, s, v } = rgb2hsv(parts[0], parts[1], parts[2]); @@ -249,10 +255,16 @@ export default class Color { r = parseHexChannel(hex[0] + hex[0]); g = parseHexChannel(hex[1] + hex[1]); b = parseHexChannel(hex[2] + hex[2]); - } else if (hex.length === 6) { + } else if (hex.length === 6 || hex.length === 8) { r = parseHexChannel(hex.substring(0, 2)); g = parseHexChannel(hex.substring(2, 4)); - b = parseHexChannel(hex.substring(4)); + b = parseHexChannel(hex.substring(4, 6)); + } + + if (hex.length === 8) { + this._alpha = Math.floor(parseHexChannel(hex.substring(6)) / 255 * 100); + } else if (hex.length === 3 || hex.length === 6) { + this._alpha = 100; } const { h, s, v } = rgb2hsv(r, g, b); @@ -260,6 +272,13 @@ export default class Color { } } + compare(color) { + return Math.abs(color._hue - this._hue) < 2 && + Math.abs(color._saturation - this._saturation) < 1 && + Math.abs(color._value - this._value) < 1 && + Math.abs(color._alpha - this._alpha) < 1; + } + doOnChange() { const { _hue, _saturation, _value, _alpha, format } = this; diff --git a/packages/color-picker/src/components/picker-dropdown.vue b/packages/color-picker/src/components/picker-dropdown.vue index 97122b2be..b50f85ae6 100644 --- a/packages/color-picker/src/components/picker-dropdown.vue +++ b/packages/color-picker/src/components/picker-dropdown.vue @@ -8,6 +8,7 @@ +
+
+ 预设: +
+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/packages/color-picker/src/main.vue b/packages/color-picker/src/main.vue index acc64d1a7..efae48538 100644 --- a/packages/color-picker/src/main.vue +++ b/packages/color-picker/src/main.vue @@ -24,7 +24,8 @@ @pick="confirmValue" @clear="clearValue" :color="color" - :show-alpha="showAlpha"> + :show-alpha="showAlpha" + :predefine="predefine">
@@ -43,7 +44,8 @@ colorFormat: String, disabled: Boolean, size: String, - popperClass: String + popperClass: String, + predefine: Array }, inject: { diff --git a/packages/theme-chalk/src/color-picker.scss b/packages/theme-chalk/src/color-picker.scss index 7505401ec..fb4f5b10e 100644 --- a/packages/theme-chalk/src/color-picker.scss +++ b/packages/theme-chalk/src/color-picker.scss @@ -1,6 +1,40 @@ @import "mixins/mixins"; @import "common/var"; +@include b(color-predefine) { + display: flex; + font-size: 12px; + margin-top: 8px; + + @include e(colors) { + display: flex; + flex: 1; + flex-wrap: wrap; + } + + @include e(color-selector) { + margin: 0 0 6px 6px; + width: 24px; + height: 24px; + border: 1px #8c939d solid; + border-radius: 2px; + cursor: pointer; + + &.selected { + border: 3px $--color-primary solid; + } + + > div { + display: flex; + height: 100%; + } + + @include when(alpha) { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==); + } + } +} + @include b(color-hue-slider) { position: relative; box-sizing: border-box; diff --git a/test/unit/specs/color-picker.spec.js b/test/unit/specs/color-picker.spec.js index 31bb19ede..34c4d5387 100644 --- a/test/unit/specs/color-picker.spec.js +++ b/test/unit/specs/color-picker.spec.js @@ -265,4 +265,98 @@ describe('ColorPicker', () => { }); }, ANIMATION_TIME); }); + + it('should change color to the selected color', done => { + const vm = createVue({ + template: ` + + `, + data() { + return { + color: 'hsva(180, 65, 20, 0.5)', + colors: [ + 'rgba(19, 206, 102, 0.18)', + 'rgb(25, 159, 147)', + 'hsv(250, 54, 98)', + 'hsva(180, 65, 20, 0.5)', + 'hsl(170, 32%, 87%)', + 'hsla(45, 62%, 47%, 0.13)', + '#7486de', + '#45aa9477', + '#892345' + ] + }; + } + }, true); + + const trigger = vm.$el.querySelector('.el-color-picker__trigger'); + trigger.click(); + + setTimeout(() => { + expect(document.querySelectorAll('.el-color-predefine__color-selector').length === 9).to.be.true; + const selector = document.querySelector('.el-color-predefine__color-selector:nth-child(4)'); + selector.click(); + vm.$nextTick(() => { + const picker = vm.$children[0]; + expect(picker.color._hue === 180).to.be.true; + expect(picker.color._saturation === 65).to.be.true; + expect(picker.color._value === 20).to.be.true; + expect(picker.color._alpha === 50).to.be.true; + + const selector2 = document.querySelector('.el-color-predefine__color-selector:nth-child(3)'); + selector2.click(); + + vm.$nextTick(() => { + expect(picker.color._hue === 250).to.be.true; + expect(picker.color._saturation === 54).to.be.true; + expect(picker.color._value === 98).to.be.true; + expect(picker.color._alpha === 100).to.be.true; + done(); + }); + }); + }); + }); + + it('should change selected state of predefined color', done => { + const vm = createVue({ + template: ` + + `, + data() { + return { + color: 'hsva(180, 65, 20, 0.5)', + colors: [ + 'rgba(19, 206, 102, 0.18)', + 'rgb(25, 159, 147)', + 'hsv(250, 54, 98)', + 'hsva(180, 65, 20, 0.5)', + 'hsl(170, 32%, 87%)', + 'hsla(45, 62%, 47%, 0.13)', + '#7486de', + '#45aa9477', + '#892345' + ] + }; + } + }, true); + + const trigger = vm.$el.querySelector('.el-color-picker__trigger'); + trigger.click(); + + setTimeout(() => { + const selector = document.querySelector('.el-color-predefine__color-selector:nth-child(4)'); + selector.click(); + vm.$nextTick(() => { + expect(selector.classList.contains('selected')).to.be.true; + + const hueBar = document.querySelector('.el-color-hue-slider'); + hueBar.__vue__.handleClick({ target: null, clientX: 0, clientY: 1000 }); + + vm.$nextTick(() => { + expect(selector.classList.contains('selected')).to.be.false; + done(); + }); + }); + }); + }); });