Commit fe2e253f358f08f97cb9e1a5ec7df01f3c9bc3e1
1 parent
8e89ea2d
Exists in
master
feat: 按钮支持主题与自定义颜色
Showing
7 changed files
with
462 additions
and
108 deletions
Show diff stats
examples/styles/variables.scss
| ... | ... | @@ -20,8 +20,6 @@ $background: #fff; |
| 20 | 20 | |
| 21 | 21 | // NEW STYLE |
| 22 | 22 | |
| 23 | -// $color-primary: #F39800; | |
| 24 | - | |
| 25 | 23 | $color-primary: #FDD108; |
| 26 | 24 | |
| 27 | 25 | $color-zy-yellow: #FDD108; |
| ... | ... | @@ -33,6 +31,7 @@ $color-wx: #07c160; |
| 33 | 31 | $color-blue: #2F86F6; |
| 34 | 32 | $color-green: #28AA91; |
| 35 | 33 | $color-red: #FF5257; |
| 34 | +$color-yellow: #ffd752; | |
| 36 | 35 | $color-blue-dark: #5878B4; |
| 37 | 36 | $color-ink: #2D2D2D; |
| 38 | 37 | $color-grey: #8C8C8C; |
| ... | ... | @@ -61,13 +60,13 @@ $color-disabled: #ccc; |
| 61 | 60 | $bg-active: #f3f3f3; |
| 62 | 61 | $bg-disabled: #f5f5f5; |
| 63 | 62 | |
| 64 | -$font-lg: 1.3125rem; | |
| 65 | -$font-md: 0.9375rem; | |
| 66 | -$font-sm: 0.6875rem; | |
| 63 | +$font-lg: 1.25rem; | |
| 64 | +$font-md: 1rem; | |
| 65 | +$font-sm: 0.65rem; | |
| 67 | 66 | |
| 68 | -$h-gap-lg: 0.625rem; | |
| 69 | -$h-gap-md: 0.468rem; | |
| 70 | -$h-gap-sm: 0.3125rem; | |
| 71 | -$v-gap-lg: 1.4rem; | |
| 72 | -$v-gap-md: 0.9375rem; | |
| 73 | -$v-gap-sm: 0.625rem; | |
| 74 | 67 | \ No newline at end of file |
| 68 | +$h-gap-lg: 0.65rem; | |
| 69 | +$h-gap-md: 0.45rem; | |
| 70 | +$h-gap-sm: 0.3rem; | |
| 71 | +$v-gap-lg: 1.5rem; | |
| 72 | +$v-gap-md: 1rem; | |
| 73 | +$v-gap-sm: 0.65rem; | |
| 75 | 74 | \ No newline at end of file | ... | ... |
examples/views/docs/component/button.md
| ... | ... | @@ -11,10 +11,121 @@ |
| 11 | 11 | ```html |
| 12 | 12 | <template> |
| 13 | 13 | <div> |
| 14 | - <zui-button disabled>Default</zui-button> | |
| 14 | + <zui-button>Default</zui-button> | |
| 15 | 15 | <zui-button type="primary">Primary</zui-button> |
| 16 | 16 | <zui-button type="secondary">Secondary</zui-button> |
| 17 | - <zui-button type="link">链接</zui-button> | |
| 17 | + <zui-button type="plain">Plain</zui-button> | |
| 18 | + <zui-button type="link">Link</zui-button> | |
| 19 | + </div> | |
| 20 | +</template> | |
| 21 | +``` | |
| 22 | + | |
| 23 | +::: | |
| 24 | + | |
| 25 | +## 按钮主题 | |
| 26 | + | |
| 27 | +配置`theme`属性改变按钮主题 | |
| 28 | + | |
| 29 | +::: snippet 支持`red`、`green`、`blue` | |
| 30 | + | |
| 31 | +```html | |
| 32 | +<template> | |
| 33 | + <div> | |
| 34 | + <div style="padding-top: 10px;"> | |
| 35 | + <zui-button theme="red">Default</zui-button> | |
| 36 | + <zui-button type="primary" theme="red">Primary</zui-button> | |
| 37 | + <zui-button type="secondary" theme="red">Secondary</zui-button> | |
| 38 | + <zui-button type="plain" theme="red">Plain</zui-button> | |
| 39 | + <zui-button type="ghost" theme="red">Ghost</zui-button> | |
| 40 | + <zui-button type="link" theme="red">Link</zui-button> | |
| 41 | + </div> | |
| 42 | + <div style="padding-top: 10px;"> | |
| 43 | + <zui-button theme="green">Default</zui-button> | |
| 44 | + <zui-button type="primary" theme="green">Primary</zui-button> | |
| 45 | + <zui-button type="secondary" theme="green">Secondary</zui-button> | |
| 46 | + <zui-button type="plain" theme="green">Plain</zui-button> | |
| 47 | + <zui-button type="ghost" theme="green">Ghost</zui-button> | |
| 48 | + <zui-button type="link" theme="green">Link</zui-button> | |
| 49 | + </div> | |
| 50 | + <div style="padding-top: 10px;"> | |
| 51 | + <zui-button theme="blue">Default</zui-button> | |
| 52 | + <zui-button type="primary" theme="blue">Primary</zui-button> | |
| 53 | + <zui-button type="secondary" theme="blue">Secondary</zui-button> | |
| 54 | + <zui-button type="plain" theme="blue">Plain</zui-button> | |
| 55 | + <zui-button type="ghost" theme="blue">Ghost</zui-button> | |
| 56 | + <zui-button type="link" theme="blue">Link</zui-button> | |
| 57 | + </div> | |
| 58 | + </div> | |
| 59 | +</template> | |
| 60 | +``` | |
| 61 | + | |
| 62 | +::: | |
| 63 | + | |
| 64 | +## 按钮颜色 | |
| 65 | + | |
| 66 | +配置`color`属性改变按钮颜色 | |
| 67 | + | |
| 68 | +::: snippet 支持任意颜色 | |
| 69 | + | |
| 70 | +```html | |
| 71 | +<template> | |
| 72 | + <div> | |
| 73 | + <div style="padding-top: 10px;"> | |
| 74 | + <zui-button color="#074137">Default</zui-button> | |
| 75 | + <zui-button type="primary" color="#074137">Primary</zui-button> | |
| 76 | + <zui-button type="secondary" color="#074137">Secondary</zui-button> | |
| 77 | + <zui-button type="plain" color="#074137">Plain</zui-button> | |
| 78 | + <zui-button type="ghost" color="#074137">Ghost</zui-button> | |
| 79 | + <zui-button type="link" color="#074137">Link</zui-button> | |
| 80 | + </div> | |
| 81 | + <div style="padding-top: 10px;"> | |
| 82 | + <zui-button color="#FDD108">Default</zui-button> | |
| 83 | + <zui-button type="primary" color="#FDD108">Primary</zui-button> | |
| 84 | + <zui-button type="secondary" color="#FDD108">Secondary</zui-button> | |
| 85 | + <zui-button type="plain" color="#FDD108">Plain</zui-button> | |
| 86 | + <zui-button type="ghost" color="#FDD108">Ghost</zui-button> | |
| 87 | + <zui-button type="link" color="#FDD108">Link</zui-button> | |
| 88 | + </div> | |
| 89 | + <div style="padding-top: 10px;"> | |
| 90 | + <zui-button color="#F39800">Default</zui-button> | |
| 91 | + <zui-button type="primary" color="#F39800">Primary</zui-button> | |
| 92 | + <zui-button type="secondary" color="#F39800">Secondary</zui-button> | |
| 93 | + <zui-button type="plain" color="#F39800">Plain</zui-button> | |
| 94 | + <zui-button type="ghost" color="#F39800">Ghost</zui-button> | |
| 95 | + <zui-button type="link" color="#F39800">Link</zui-button> | |
| 96 | + </div> | |
| 97 | + <div style="padding-top: 10px;"> | |
| 98 | + <zui-button color="#FF5257">Default</zui-button> | |
| 99 | + <zui-button type="primary" color="#FF5257">Primary</zui-button> | |
| 100 | + <zui-button type="secondary" color="#FF5257">Secondary</zui-button> | |
| 101 | + <zui-button type="plain" color="#FF5257">Plain</zui-button> | |
| 102 | + <zui-button type="ghost" color="#FF5257">Ghost</zui-button> | |
| 103 | + <zui-button type="link" color="#FF5257">Link</zui-button> | |
| 104 | + </div> | |
| 105 | + <div style="padding-top: 10px;"> | |
| 106 | + <zui-button color="rgb(40, 170, 145)">Default</zui-button> | |
| 107 | + <zui-button type="primary" color="rgb(40, 170, 145)">Primary</zui-button> | |
| 108 | + <zui-button type="secondary" color="rgb(40, 170, 145)">Secondary</zui-button> | |
| 109 | + <zui-button type="plain" color="rgb(40, 170, 145)">Plain</zui-button> | |
| 110 | + <zui-button type="ghost" color="rgb(40, 170, 145)">Ghost</zui-button> | |
| 111 | + <zui-button type="link" color="rgb(40, 170, 145)">Link</zui-button> | |
| 112 | + </div> | |
| 113 | + <div style="padding-top: 10px;"> | |
| 114 | + <zui-button color="#2F86F6">Default</zui-button> | |
| 115 | + <zui-button type="primary" color="#2F86F6">Primary</zui-button> | |
| 116 | + <zui-button type="secondary" color="#2F86F6">Secondary</zui-button> | |
| 117 | + <zui-button type="plain" color="#2F86F6">Plain</zui-button> | |
| 118 | + <zui-button type="ghost" color="#2F86F6">Ghost</zui-button> | |
| 119 | + <zui-button type="link" color="#2F86F6">Link</zui-button> | |
| 120 | + </div> | |
| 121 | + <div style="padding-top: 10px;"> | |
| 122 | + <zui-button color="#000">Default</zui-button> | |
| 123 | + <zui-button type="primary" color="#000">Primary</zui-button> | |
| 124 | + <zui-button type="secondary" color="#000">Secondary</zui-button> | |
| 125 | + <zui-button type="plain" color="#000">Plain</zui-button> | |
| 126 | + <zui-button type="ghost" color="#000">Ghost</zui-button> | |
| 127 | + <zui-button type="link" color="#000">Link</zui-button> | |
| 128 | + </div> | |
| 18 | 129 | </div> |
| 19 | 130 | </template> |
| 20 | 131 | ``` | ... | ... |
package.json
packages/button/index.scss
| ... | ... | @@ -6,32 +6,25 @@ |
| 6 | 6 | font-weight: normal; |
| 7 | 7 | font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif; |
| 8 | 8 | cursor: pointer; |
| 9 | - transition: all 70ms ease 20ms; | |
| 10 | - border-radius: 0.3125rem; | |
| 9 | + transition: all 70ms ease; | |
| 10 | + border-radius: 0.35rem; | |
| 11 | 11 | position: relative; |
| 12 | 12 | display: inline-block; |
| 13 | 13 | text-align: center; |
| 14 | 14 | border: none; |
| 15 | 15 | outline: none; |
| 16 | - line-height: 1.5; | |
| 17 | - &::after { | |
| 18 | - line-height: 1.5; | |
| 19 | - padding: 0; | |
| 20 | - margin: 0; | |
| 21 | - border: none; | |
| 22 | - content: ""; | |
| 23 | - pointer-events: none; /* 防止点击触发 */ | |
| 24 | - box-sizing: border-box; | |
| 25 | - position: absolute; | |
| 26 | - width: 200%; | |
| 27 | - height: 200%; | |
| 28 | - left: 0; | |
| 29 | - top: 0; | |
| 30 | - border: 1px solid $color-border; | |
| 31 | - border-radius: 0.625rem; | |
| 32 | - transform: scale(0.5); | |
| 33 | - transform-origin: 0 0; | |
| 34 | - } | |
| 16 | + line-height: 1.5; | |
| 17 | + box-sizing: border-box; | |
| 18 | + border: 1px solid transparent; | |
| 19 | + &.red { | |
| 20 | + color: $color-red; | |
| 21 | + } | |
| 22 | + &.blue { | |
| 23 | + color: $color-blue; | |
| 24 | + } | |
| 25 | + &.green { | |
| 26 | + color: $color-green; | |
| 27 | + } | |
| 35 | 28 | &.block { |
| 36 | 29 | display: block; |
| 37 | 30 | width: 100%; |
| ... | ... | @@ -48,99 +41,153 @@ |
| 48 | 41 | padding: $h-gap-lg $v-gap-lg; |
| 49 | 42 | font-size: $font-lg; |
| 50 | 43 | } |
| 51 | - &:active { | |
| 44 | + &.default { | |
| 45 | + border-color: $color-border; | |
| 46 | + } | |
| 47 | + &.button-hover { | |
| 52 | 48 | background-color: $bg-active; |
| 53 | - &, &::after { | |
| 54 | - border-color: $bg-active; | |
| 49 | + } | |
| 50 | + @mixin fill-mixin($color) { | |
| 51 | + &.button-hover { | |
| 52 | + background-color: $color; | |
| 55 | 53 | } |
| 56 | 54 | } |
| 57 | 55 | &.primary { |
| 58 | 56 | background-color: $color-primary; |
| 59 | 57 | color: #FFF; |
| 60 | - &:active { | |
| 61 | - background-color: darken($color-primary, 3%); | |
| 62 | - &, &::after { | |
| 63 | - border-color: darken($color-primary, 3%); | |
| 64 | - } | |
| 58 | + @include fill-mixin(lighten($color-primary, 10%)); | |
| 59 | + &.red { | |
| 60 | + background-color: $color-red; | |
| 61 | + @include fill-mixin(lighten($color-red, 10%)); | |
| 62 | + } | |
| 63 | + &.green { | |
| 64 | + background-color: $color-green; | |
| 65 | + @include fill-mixin(lighten($color-green, 10%)); | |
| 65 | 66 | } |
| 66 | - &, &::after { | |
| 67 | - border-color: $color-primary; | |
| 67 | + &.blue { | |
| 68 | + background-color: $color-blue; | |
| 69 | + @include fill-mixin(lighten($color-blue, 10%)); | |
| 68 | 70 | } |
| 69 | 71 | } |
| 70 | 72 | &.secondary { |
| 71 | - background-color: lighten($color-primary, 40%); | |
| 72 | 73 | color: $color-primary; |
| 73 | - &:active { | |
| 74 | - background-color: lighten($color-primary, 30%); | |
| 75 | - color: darken($color-primary, 3%); | |
| 76 | - &, &::after { | |
| 77 | - border-color: lighten($color-primary, 30%); | |
| 74 | + background-color: hsl(hue($color-primary), saturation($color-primary), 95%); | |
| 75 | + @include fill-mixin(hsl(hue($color-primary), saturation($color-primary), 90%)); | |
| 76 | + &.red { | |
| 77 | + color: $color-red; | |
| 78 | + background-color: hsl(hue($color-red), saturation($color-red), 95%); | |
| 79 | + @include fill-mixin(hsl(hue($color-red), saturation($color-red), 90%)); | |
| 80 | + } | |
| 81 | + &.green { | |
| 82 | + color: $color-green; | |
| 83 | + background-color: hsl(hue($color-green), saturation($color-green), 95%); | |
| 84 | + @include fill-mixin(hsl(hue($color-green), saturation($color-green), 90%)); | |
| 85 | + } | |
| 86 | + &.blue { | |
| 87 | + color: $color-blue; | |
| 88 | + background-color: hsl(hue($color-blue), saturation($color-blue), 95%); | |
| 89 | + @include fill-mixin(hsl(hue($color-blue), saturation($color-blue), 90%)); | |
| 90 | + } | |
| 91 | + } | |
| 92 | + &.plain { | |
| 93 | + color: $color-primary; | |
| 94 | + background-color: hsl(hue($color-primary), saturation($color-primary), 95%); | |
| 95 | + border-color: $color-primary; | |
| 96 | + &:not(.custom).button-hover { | |
| 97 | + background-color: hsl(hue($color-primary), saturation($color-primary), 95%); | |
| 98 | + } | |
| 99 | + &.red { | |
| 100 | + color: $color-red; | |
| 101 | + border-color: $color-red; | |
| 102 | + background-color: hsl(hue($color-red), saturation($color-red), 95%); | |
| 103 | + &:not(.custom).button-hover { | |
| 104 | + background-color: hsl(hue($color-red), saturation($color-red), 90%); | |
| 78 | 105 | } |
| 79 | 106 | } |
| 80 | - &, &::after { | |
| 81 | - border-color: lighten($color-primary, 40%); | |
| 82 | - } | |
| 83 | - } | |
| 84 | - &.plain { | |
| 85 | - &.primary { | |
| 86 | - color: $color-primary; | |
| 87 | - background-color: transparent; | |
| 88 | - &:active { | |
| 89 | - background-color: rgba($color-primary, 0.1); | |
| 90 | - } | |
| 91 | - } | |
| 92 | - &.disabled { | |
| 93 | - background-color: rgba($bg-disabled, 0.1); | |
| 94 | - color: $color-disabled; | |
| 95 | - cursor: not-allowed; | |
| 96 | - &:active { | |
| 97 | - color: $color-disabled; | |
| 98 | - background-color: rgba($bg-disabled, 0.1); | |
| 99 | - &, &::after { | |
| 100 | - border-color: $bg-disabled; | |
| 101 | - } | |
| 102 | - } | |
| 103 | - &, &::after { | |
| 104 | - border-color: $bg-disabled; | |
| 105 | - } | |
| 106 | - } | |
| 107 | - } | |
| 107 | + &.green { | |
| 108 | + color: $color-green; | |
| 109 | + border-color: $color-green; | |
| 110 | + background-color: hsl(hue($color-green), saturation($color-green), 95%); | |
| 111 | + &:not(.custom).button-hover { | |
| 112 | + background-color: hsl(hue($color-green), saturation($color-green), 90%); | |
| 113 | + } | |
| 114 | + } | |
| 115 | + &.blue { | |
| 116 | + color: $color-blue; | |
| 117 | + border-color: $color-blue; | |
| 118 | + background-color: hsl(hue($color-blue), saturation($color-blue), 95%); | |
| 119 | + &:not(.custom).button-hover { | |
| 120 | + background-color: hsl(hue($color-blue), saturation($color-blue), 90%); | |
| 121 | + } | |
| 122 | + } | |
| 123 | + } | |
| 124 | + &.ghost { | |
| 125 | + color: $color-primary; | |
| 126 | + background-color: transparent; | |
| 127 | + border-color: $color-primary; | |
| 128 | + &:not(.custom).button-hover { | |
| 129 | + background-color: hsl(hue($color-primary), saturation($color-primary), 95%); | |
| 130 | + } | |
| 131 | + &.red { | |
| 132 | + color: $color-red; | |
| 133 | + border-color: $color-red; | |
| 134 | + &:not(.custom).button-hover { | |
| 135 | + background-color: hsl(hue($color-red), saturation($color-red), 95%); | |
| 136 | + } | |
| 137 | + } | |
| 138 | + &.green { | |
| 139 | + color: $color-green; | |
| 140 | + border-color: $color-green; | |
| 141 | + &:not(.custom).button-hover { | |
| 142 | + background-color: hsl(hue($color-green), saturation($color-green), 95%); | |
| 143 | + } | |
| 144 | + } | |
| 145 | + &.blue { | |
| 146 | + color: $color-blue; | |
| 147 | + border-color: $color-blue; | |
| 148 | + &:not(.custom).button-hover { | |
| 149 | + background-color: hsl(hue($color-blue), saturation($color-blue), 95%); | |
| 150 | + } | |
| 151 | + } | |
| 152 | + } | |
| 108 | 153 | &.link { |
| 109 | - padding: $h-gap-sm $v-gap-sm; | |
| 110 | - background: inherit; | |
| 111 | - border: inherit; | |
| 154 | + background-color: transparent; | |
| 155 | + border-color: transparent; | |
| 112 | 156 | color: $color-primary; |
| 113 | - &:active { | |
| 114 | - color: darken($color-primary, 5%); | |
| 157 | + &.button-hover { | |
| 158 | + color: lighten($color-primary, 10%); | |
| 159 | + } | |
| 160 | + &.red { | |
| 161 | + color: $color-red; | |
| 162 | + &.button-hover { | |
| 163 | + color: lighten($color-red, 10%); | |
| 164 | + } | |
| 165 | + } | |
| 166 | + &.green { | |
| 167 | + color: $color-green; | |
| 168 | + &.button-hover { | |
| 169 | + color: lighten($color-green, 10%); | |
| 170 | + } | |
| 171 | + } | |
| 172 | + &.blue { | |
| 173 | + color: $color-blue; | |
| 174 | + &.button-hover { | |
| 175 | + color: lighten($color-blue, 10%); | |
| 176 | + } | |
| 115 | 177 | } |
| 116 | - &::after { | |
| 117 | - display: none; | |
| 118 | - } | |
| 119 | 178 | } |
| 120 | 179 | &.disabled { |
| 121 | 180 | background-color: $bg-disabled; |
| 122 | 181 | color: $color-disabled; |
| 123 | 182 | cursor: not-allowed; |
| 124 | - &:active { | |
| 183 | + &.button-hover { | |
| 125 | 184 | background-color: $bg-disabled; |
| 126 | - &, &::after { | |
| 127 | - border-color: $bg-disabled; | |
| 128 | - } | |
| 129 | - } | |
| 130 | - &, &::after { | |
| 131 | - border-color: $bg-disabled; | |
| 132 | 185 | } |
| 133 | 186 | } |
| 134 | 187 | &.round { |
| 135 | 188 | border-radius: 1.5rem; |
| 136 | - &::after { | |
| 137 | - border-radius: 3rem; | |
| 138 | - } | |
| 139 | 189 | } |
| 140 | 190 | &.square { |
| 141 | 191 | border-radius: 0; |
| 142 | - &::after { | |
| 143 | - border-radius: 0; | |
| 144 | - } | |
| 145 | 192 | } |
| 146 | 193 | } |
| 147 | 194 | \ No newline at end of file | ... | ... |
packages/button/index.vue
| 1 | 1 | <template> |
| 2 | - <button class="zui-button" :class="classRender" @click="onClick"> | |
| 2 | + <button class="zui-button" :class="classRender" :style="styleRender" v-on="bindEvents"> | |
| 3 | 3 | <slot></slot> |
| 4 | 4 | </button> |
| 5 | 5 | </template> |
| 6 | 6 | |
| 7 | 7 | <script> |
| 8 | +import color from 'color'; | |
| 9 | + | |
| 8 | 10 | export default { |
| 9 | 11 | name: 'Button', |
| 10 | 12 | props: { |
| ... | ... | @@ -23,26 +25,100 @@ export default { |
| 23 | 25 | round: Boolean, |
| 24 | 26 | square: Boolean, |
| 25 | 27 | disabled: Boolean, |
| 26 | - plain: Boolean, | |
| 28 | + theme: String, | |
| 29 | + color: String, | |
| 30 | + hoverClass: { | |
| 31 | + type: String, | |
| 32 | + default: 'button-hover', | |
| 33 | + }, | |
| 34 | + hoverStartTime: { | |
| 35 | + type: Number, | |
| 36 | + default: 0, | |
| 37 | + }, | |
| 38 | + hoverStayTime: { | |
| 39 | + type: Number, | |
| 40 | + default: 70, | |
| 41 | + }, | |
| 42 | + }, | |
| 43 | + data() { | |
| 44 | + return { | |
| 45 | + active: false, | |
| 46 | + }; | |
| 27 | 47 | }, |
| 28 | 48 | computed: { |
| 29 | 49 | classRender() { |
| 30 | 50 | return { |
| 31 | 51 | [this.size]: true, |
| 32 | 52 | [this.type]: true, |
| 53 | + [this.theme]: !!this.theme, | |
| 54 | + [this.hoverClass]: this.active, | |
| 33 | 55 | disabled: this.disabled, |
| 34 | 56 | block: this.block, |
| 35 | 57 | round: this.round, |
| 36 | 58 | square: this.square, |
| 37 | - plain: this.plain, | |
| 59 | + custom: !!this.color, | |
| 38 | 60 | }; |
| 39 | 61 | }, |
| 40 | - }, | |
| 41 | - methods: { | |
| 42 | - onClick() { | |
| 43 | - if (!this.disabled) { | |
| 44 | - this.$emit('click'); | |
| 62 | + styleRender() { | |
| 63 | + if (this.color) { | |
| 64 | + if (this.type === 'primary') { | |
| 65 | + return { | |
| 66 | + backgroundColor: this.active ? color(this.color).lighten(0.2) : this.color, | |
| 67 | + borderColor: this.active ? color(this.color).lighten(0.2) : this.color, | |
| 68 | + }; | |
| 69 | + } else if (this.type === 'secondary') { | |
| 70 | + return { | |
| 71 | + backgroundColor: this.active ? color(this.color).lightness(90) : color(this.color).lightness(95), | |
| 72 | + color: this.color, | |
| 73 | + }; | |
| 74 | + } else if (this.type === 'plain') { | |
| 75 | + return { | |
| 76 | + borderColor: this.color, | |
| 77 | + color: this.color, | |
| 78 | + backgroundColor: this.active ? color(this.color).lightness(90) : color(this.color).lightness(95), | |
| 79 | + }; | |
| 80 | + } else if (this.type === 'ghost') { | |
| 81 | + return { | |
| 82 | + borderColor: this.color, | |
| 83 | + color: this.color, | |
| 84 | + backgroundColor: this.active ? color(this.color).lightness(95) : undefined, | |
| 85 | + }; | |
| 86 | + } else { | |
| 87 | + return { | |
| 88 | + color: this.active ? color(this.color).lighten(0.2) : this.color, | |
| 89 | + }; | |
| 90 | + } | |
| 45 | 91 | } |
| 92 | + return {}; | |
| 93 | + }, | |
| 94 | + bindEvents() { | |
| 95 | + const events = this.$listeners || {}; | |
| 96 | + const activeEvents = ['mousedown', 'touchstart']; | |
| 97 | + const deactiveEvents = ['mouseup', 'mousemove', 'touchend', 'touchmove']; | |
| 98 | + let safeEvents = { ...events }; | |
| 99 | + activeEvents.forEach(key => { | |
| 100 | + safeEvents[key] = e => { | |
| 101 | + const originEvent = events[key]; | |
| 102 | + originEvent && originEvent(e); | |
| 103 | + if (this.hoverStartTime) { | |
| 104 | + setTimeout(() => { | |
| 105 | + this.active = true; | |
| 106 | + }, this.hoverStartTime); | |
| 107 | + } else { | |
| 108 | + this.active = true; | |
| 109 | + } | |
| 110 | + }; | |
| 111 | + }); | |
| 112 | + deactiveEvents.forEach(key => { | |
| 113 | + safeEvents[key] = e => { | |
| 114 | + const originEvent = events[key]; | |
| 115 | + originEvent && originEvent(e); | |
| 116 | + setTimeout(() => { | |
| 117 | + this.active = false; | |
| 118 | + }, this.hoverStayTime); | |
| 119 | + }; | |
| 120 | + }); | |
| 121 | + return safeEvents; | |
| 46 | 122 | }, |
| 47 | 123 | }, |
| 48 | 124 | }; | ... | ... |
| ... | ... | @@ -0,0 +1,120 @@ |
| 1 | +export const RGB = ({ r, g, b }) => { | |
| 2 | + return `rgb(${r}, ${g}, ${b})`; | |
| 3 | +}; | |
| 4 | + | |
| 5 | +// 将rgb颜色转成hex | |
| 6 | +export const RGBToHex = (color = '') => { | |
| 7 | + const rgb = color.split(','); | |
| 8 | + const r = parseInt(rgb[0].split('(')[1]); | |
| 9 | + const g = parseInt(rgb[1]); | |
| 10 | + const b = parseInt(rgb[2].split(')')[0]); | |
| 11 | + const hex = '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); | |
| 12 | + return hex; | |
| 13 | +}; | |
| 14 | + | |
| 15 | +// 将hex颜色转成rgb | |
| 16 | +export const HexToRGBA = (hex = '', opacity) => { | |
| 17 | + const red = parseInt(`0x${hex.slice(1, 3)}`); | |
| 18 | + const green = parseInt(`0x${hex.slice(3, 5)}`); | |
| 19 | + const blue = parseInt(`0x${hex.slice(5, 7)}`); | |
| 20 | + const RGBA = `rgba(${red},${green},${blue},${opacity})`; | |
| 21 | + return { red, green, blue, rgba: RGBA }; | |
| 22 | +}; | |
| 23 | + | |
| 24 | +const RGB_MAX = 255; | |
| 25 | +const HUE_MAX = 360; | |
| 26 | +const SV_MAX = 100; | |
| 27 | + | |
| 28 | +export const HexToHSL = hex => { | |
| 29 | + const { red, green, blue } = HexToRGBA(hex); | |
| 30 | + return RGBToHSL(red, green, blue); | |
| 31 | +}; | |
| 32 | + | |
| 33 | +export const HSLToRGB = function (h, s, l) { | |
| 34 | + function _hue2Rgb(p, q, t) { | |
| 35 | + if (t < 0) t += 1; | |
| 36 | + if (t > 1) t -= 1; | |
| 37 | + if (t < 1 / 6) return p + (q - p) * 6 * t; | |
| 38 | + if (t < 1 / 2) return q; | |
| 39 | + if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; | |
| 40 | + return p; | |
| 41 | + } | |
| 42 | + | |
| 43 | + function _normalizeAngle(degrees) { | |
| 44 | + return ((degrees % 360) + 360) % 360; | |
| 45 | + } | |
| 46 | + | |
| 47 | + if (typeof h === 'object') { | |
| 48 | + const args = h; | |
| 49 | + h = args.h; | |
| 50 | + s = args.s; | |
| 51 | + l = args.l; | |
| 52 | + } | |
| 53 | + | |
| 54 | + var r, g, b; | |
| 55 | + | |
| 56 | + h = _normalizeAngle(h); | |
| 57 | + h = h === HUE_MAX ? 1 : (h % HUE_MAX) / parseFloat(HUE_MAX); | |
| 58 | + s = s === SV_MAX ? 1 : (s % SV_MAX) / parseFloat(SV_MAX); | |
| 59 | + l = l === SV_MAX ? 1 : (l % SV_MAX) / parseFloat(SV_MAX); | |
| 60 | + | |
| 61 | + if (s === 0) { | |
| 62 | + r = g = b = l; // achromatic | |
| 63 | + } else { | |
| 64 | + var q = l < 0.5 ? l * (1 + s) : l + s - l * s; | |
| 65 | + var p = 2 * l - q; | |
| 66 | + r = _hue2Rgb(p, q, h + 1 / 3); | |
| 67 | + g = _hue2Rgb(p, q, h); | |
| 68 | + b = _hue2Rgb(p, q, h - 1 / 3); | |
| 69 | + } | |
| 70 | + | |
| 71 | + return { | |
| 72 | + r: Math.round(r * RGB_MAX), | |
| 73 | + g: Math.round(g * RGB_MAX), | |
| 74 | + b: Math.round(b * RGB_MAX), | |
| 75 | + }; | |
| 76 | +}; | |
| 77 | + | |
| 78 | +export const RGBToHSL = (r, g, b) => { | |
| 79 | + if (typeof r === 'object') { | |
| 80 | + const args = r; | |
| 81 | + r = args.r; | |
| 82 | + g = args.g; | |
| 83 | + b = args.b; | |
| 84 | + } | |
| 85 | + // It converts [0,255] format, to [0,1] | |
| 86 | + r = r === RGB_MAX ? 1 : (r % RGB_MAX) / parseFloat(RGB_MAX); | |
| 87 | + g = g === RGB_MAX ? 1 : (g % RGB_MAX) / parseFloat(RGB_MAX); | |
| 88 | + b = b === RGB_MAX ? 1 : (b % RGB_MAX) / parseFloat(RGB_MAX); | |
| 89 | + | |
| 90 | + var max = Math.max(r, g, b); | |
| 91 | + var min = Math.min(r, g, b); | |
| 92 | + var h, | |
| 93 | + s, | |
| 94 | + l = (max + min) / 2; | |
| 95 | + | |
| 96 | + if (max === min) { | |
| 97 | + h = s = 0; // achromatic | |
| 98 | + } else { | |
| 99 | + var d = max - min; | |
| 100 | + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); | |
| 101 | + switch (max) { | |
| 102 | + case r: | |
| 103 | + h = (g - b) / d + (g < b ? 6 : 0); | |
| 104 | + break; | |
| 105 | + case g: | |
| 106 | + h = (b - r) / d + 2; | |
| 107 | + break; | |
| 108 | + case b: | |
| 109 | + h = (r - g) / d + 4; | |
| 110 | + break; | |
| 111 | + } | |
| 112 | + h /= 6; | |
| 113 | + } | |
| 114 | + | |
| 115 | + return { | |
| 116 | + h: Math.round(h * HUE_MAX), | |
| 117 | + s: Math.round(s * SV_MAX), | |
| 118 | + l: Math.round(l * SV_MAX), | |
| 119 | + }; | |
| 120 | +}; | ... | ... |
yarn.lock
| ... | ... | @@ -2798,7 +2798,7 @@ color-string@^1.5.2: |
| 2798 | 2798 | color-name "^1.0.0" |
| 2799 | 2799 | simple-swizzle "^0.2.2" |
| 2800 | 2800 | |
| 2801 | -color@^3.0.0: | |
| 2801 | +color@^3.0.0, color@^3.1.2: | |
| 2802 | 2802 | version "3.1.2" |
| 2803 | 2803 | resolved "https://registry.npm.taobao.org/color/download/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" |
| 2804 | 2804 | integrity sha1-aBSOf4XUGtdknF+oyBBvCY0inhA= | ... | ... |