Commit b40e2e96be7c00a15e1b3111debecafb9fbca4ba
1 parent
9f249603
Circle add prop dashboard
Showing
2 changed files
with
82 additions
and
61 deletions
Show diff stats
examples/routers/circle.vue
| 1 | -<style lang="less"> | ||
| 2 | - .demo-circle-custom{ | ||
| 3 | - & h1{ | ||
| 4 | - color: #3f414d; | ||
| 5 | - font-size: 28px; | ||
| 6 | - font-weight: normal; | ||
| 7 | - } | ||
| 8 | - & p{ | ||
| 9 | - color: #657180; | ||
| 10 | - font-size: 14px; | ||
| 11 | - margin: 10px 0 15px; | ||
| 12 | - } | ||
| 13 | - & span{ | ||
| 14 | - display: block; | ||
| 15 | - padding-top: 15px; | ||
| 16 | - color: #657180; | ||
| 17 | - font-size: 14px; | ||
| 18 | - &:before{ | ||
| 19 | - content: ''; | ||
| 20 | - display: block; | ||
| 21 | - width: 50px; | ||
| 22 | - height: 1px; | ||
| 23 | - margin: 0 auto; | ||
| 24 | - background: #e0e3e6; | ||
| 25 | - position: relative; | ||
| 26 | - top: -15px; | ||
| 27 | - }; | ||
| 28 | - } | ||
| 29 | - & span i{ | ||
| 30 | - font-style: normal; | ||
| 31 | - color: #3f414d; | ||
| 32 | - } | ||
| 33 | - } | ||
| 34 | -</style> | ||
| 35 | <template> | 1 | <template> |
| 36 | - <i-circle | ||
| 37 | - :size="250" | ||
| 38 | - :trail-width="4" | ||
| 39 | - :stroke-width="5" | ||
| 40 | - :percent="75" | ||
| 41 | - stroke-linecap="square" | ||
| 42 | - stroke-color="#43a3fb"> | ||
| 43 | - <div class="demo-circle-custom"> | ||
| 44 | - <h1>{{ 42001776 }}</h1> | ||
| 45 | - <p>消费人群规模</p> | ||
| 46 | - <span> | ||
| 47 | - 总占人数 | ||
| 48 | - <i>75%</i> | ||
| 49 | - </span> | ||
| 50 | - </div> | ||
| 51 | - </i-circle> | 2 | + <div> |
| 3 | + <i-circle :percent="percent" dashboard :stroke-color="color"> | ||
| 4 | + <Icon v-if="percent == 100" type="ios-checkmark" size="60" style="color:#5cb85c"></Icon> | ||
| 5 | + <span v-else style="font-size:24px">{{ percent }}%</span> | ||
| 6 | + </i-circle> | ||
| 7 | + <ButtonGroup size="large"> | ||
| 8 | + <Button icon="ios-add" @click="add"></Button> | ||
| 9 | + <Button icon="ios-remove" @click="minus"></Button> | ||
| 10 | + </ButtonGroup> | ||
| 11 | + </div> | ||
| 52 | </template> | 12 | </template> |
| 53 | <script> | 13 | <script> |
| 54 | export default { | 14 | export default { |
| 55 | - | 15 | + data () { |
| 16 | + return { | ||
| 17 | + percent: 0 | ||
| 18 | + } | ||
| 19 | + }, | ||
| 20 | + computed: { | ||
| 21 | + color () { | ||
| 22 | + let color = '#2db7f5'; | ||
| 23 | + if (this.percent == 100) { | ||
| 24 | + color = '#5cb85c'; | ||
| 25 | + } | ||
| 26 | + return color; | ||
| 27 | + } | ||
| 28 | + }, | ||
| 29 | + methods: { | ||
| 30 | + add () { | ||
| 31 | + if (this.percent >= 100) { | ||
| 32 | + return false; | ||
| 33 | + } | ||
| 34 | + this.percent += 10; | ||
| 35 | + }, | ||
| 36 | + minus () { | ||
| 37 | + if (this.percent <= 0) { | ||
| 38 | + return false; | ||
| 39 | + } | ||
| 40 | + this.percent -= 10; | ||
| 41 | + } | ||
| 42 | + } | ||
| 56 | } | 43 | } |
| 57 | </script> | 44 | </script> |
src/components/circle/circle.vue
| 1 | <template> | 1 | <template> |
| 2 | <div :style="circleSize" :class="wrapClasses"> | 2 | <div :style="circleSize" :class="wrapClasses"> |
| 3 | <svg viewBox="0 0 100 100"> | 3 | <svg viewBox="0 0 100 100"> |
| 4 | - <path :d="pathString" :stroke="trailColor" :stroke-width="trailWidth" :fill-opacity="0"/> | ||
| 5 | - <path :d="pathString" :stroke-linecap="strokeLinecap" :stroke="strokeColor" :stroke-width="strokeWidth" fill-opacity="0" :style="pathStyle"/> | 4 | + <path :d="pathString" :stroke="trailColor" :stroke-width="trailWidth" :fill-opacity="0" :style="trailStyle" /> |
| 5 | + <path :d="pathString" :stroke-linecap="strokeLinecap" :stroke="strokeColor" :stroke-width="computedStrokeWidth" fill-opacity="0" :style="pathStyle" /> | ||
| 6 | </svg> | 6 | </svg> |
| 7 | <div :class="innerClasses"> | 7 | <div :class="innerClasses"> |
| 8 | <slot></slot> | 8 | <slot></slot> |
| @@ -46,6 +46,10 @@ | @@ -46,6 +46,10 @@ | ||
| 46 | trailColor: { | 46 | trailColor: { |
| 47 | type: String, | 47 | type: String, |
| 48 | default: '#eaeef2' | 48 | default: '#eaeef2' |
| 49 | + }, | ||
| 50 | + dashboard: { | ||
| 51 | + type: Boolean, | ||
| 52 | + default: false | ||
| 49 | } | 53 | } |
| 50 | }, | 54 | }, |
| 51 | computed: { | 55 | computed: { |
| @@ -55,23 +59,53 @@ | @@ -55,23 +59,53 @@ | ||
| 55 | height: `${this.size}px` | 59 | height: `${this.size}px` |
| 56 | }; | 60 | }; |
| 57 | }, | 61 | }, |
| 62 | + computedStrokeWidth () { | ||
| 63 | + return this.percent === 0 && this.dashboard ? 0 : this.strokeWidth; | ||
| 64 | + }, | ||
| 58 | radius () { | 65 | radius () { |
| 59 | return 50 - this.strokeWidth / 2; | 66 | return 50 - this.strokeWidth / 2; |
| 60 | }, | 67 | }, |
| 61 | pathString () { | 68 | pathString () { |
| 62 | - return `M 50,50 m 0,-${this.radius} | ||
| 63 | - a ${this.radius},${this.radius} 0 1 1 0,${2 * this.radius} | ||
| 64 | - a ${this.radius},${this.radius} 0 1 1 0,-${2 * this.radius}`; | 69 | + if (this.dashboard) { |
| 70 | + return `M 50,50 m 0,${this.radius} | ||
| 71 | + a ${this.radius},${this.radius} 0 1 1 0,-${2 * this.radius} | ||
| 72 | + a ${this.radius},${this.radius} 0 1 1 0,${2 * this.radius}`; | ||
| 73 | + } else { | ||
| 74 | + return `M 50,50 m 0,-${this.radius} | ||
| 75 | + a ${this.radius},${this.radius} 0 1 1 0,${2 * this.radius} | ||
| 76 | + a ${this.radius},${this.radius} 0 1 1 0,-${2 * this.radius}`; | ||
| 77 | + } | ||
| 65 | }, | 78 | }, |
| 66 | len () { | 79 | len () { |
| 67 | return Math.PI * 2 * this.radius; | 80 | return Math.PI * 2 * this.radius; |
| 68 | }, | 81 | }, |
| 82 | + trailStyle () { | ||
| 83 | + let style = {}; | ||
| 84 | + if (this.dashboard) { | ||
| 85 | + style = { | ||
| 86 | + 'stroke-dasharray': `${this.len - 75}px ${this.len}px`, | ||
| 87 | + 'stroke-dashoffset': `-${75 / 2}px`, | ||
| 88 | + 'transition': 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s' | ||
| 89 | + } | ||
| 90 | + } | ||
| 91 | + return style; | ||
| 92 | + }, | ||
| 69 | pathStyle () { | 93 | pathStyle () { |
| 70 | - return { | ||
| 71 | - 'stroke-dasharray': `${this.len}px ${this.len}px`, | ||
| 72 | - 'stroke-dashoffset': `${((100 - this.percent) / 100 * this.len)}px`, | ||
| 73 | - 'transition': 'stroke-dashoffset 0.6s ease 0s, stroke 0.6s ease' | ||
| 74 | - }; | 94 | + let style = {}; |
| 95 | + if (this.dashboard) { | ||
| 96 | + style = { | ||
| 97 | + 'stroke-dasharray': `${(this.percent / 100) * (this.len - 75)}px ${this.len}px`, | ||
| 98 | + 'stroke-dashoffset': `-${75 / 2}px`, | ||
| 99 | + 'transition': 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s' | ||
| 100 | + }; | ||
| 101 | + } else { | ||
| 102 | + style = { | ||
| 103 | + 'stroke-dasharray': `${this.len}px ${this.len}px`, | ||
| 104 | + 'stroke-dashoffset': `${((100 - this.percent) / 100 * this.len)}px`, | ||
| 105 | + 'transition': 'stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease' | ||
| 106 | + }; | ||
| 107 | + } | ||
| 108 | + return style; | ||
| 75 | }, | 109 | }, |
| 76 | wrapClasses () { | 110 | wrapClasses () { |
| 77 | return `${prefixCls}`; | 111 | return `${prefixCls}`; |