chore(progress): get off work checkpoint, for line, circle progress

This commit is contained in:
07akioni 2019-08-02 18:52:29 +08:00
parent 5114908c6d
commit 77385c63df
7 changed files with 595 additions and 69 deletions

View File

@ -0,0 +1,63 @@
<template>
<div class="n-doc-section">
<div class="n-doc-section__header">
Circle
</div>
<div
class="n-doc-section__view"
style="flex-wrap: nowrap;"
>
<!--EXAMPLE_START-->
<n-progress
type="circle"
:percentage="percentage"
/>
<n-progress
type="circle"
status="success"
:percentage="percentage"
/>
<n-progress
type="circle"
status="warning"
:percentage="percentage"
/>
<n-progress
type="circle"
status="error"
:percentage="percentage"
/>
<!--EXAMPLE_END-->
</div>
<div class="n-doc-section__inspect">
<n-button @click="minus">
minus
</n-button><n-button @click="add">
add
</n-button>
</div>
<n-doc-source-block>
<!--SOURCE-->
</n-doc-source-block>
</div>
</template>
<script>
export default {
data () {
return {
percentage: 0
}
},
methods: {
add () {
this.percentage += 10
if (this.percentage > 100) this.percentage = 0
},
minus () {
this.percentage -= 10
if (this.percentage < 0) this.percentage = 100
}
}
}
</script>

View File

@ -5,21 +5,24 @@
> >
<div class="n-doc-header"> <div class="n-doc-header">
<n-gradient-text :font-size="20"> <n-gradient-text :font-size="20">
scaffold Progress / n-progress
</n-gradient-text> </n-gradient-text>
</div> </div>
<div class="n-doc-body"> <div class="n-doc-body">
<scaffold /> <circle-demo />
<line-demo />
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import scaffold from './scaffold.demo.vue' import circleDemo from './circle.demo.vue'
import lineDemo from './line.demo.vue'
export default { export default {
components: { components: {
scaffold circleDemo,
lineDemo
}, },
data () { data () {
return { return {

View File

@ -0,0 +1,132 @@
<template>
<div class="n-doc-section">
<div class="n-doc-section__header">
Line
</div>
<div
class="n-doc-section__view"
style="flex-wrap: wrap;"
>
<!--EXAMPLE_START-->
<n-progress
type="line"
:percentage="percentage"
:show-indicator="false"
/>
<n-progress
type="line"
:percentage="percentage"
/>
<n-progress
type="line"
:percentage="percentage"
:indicator-position="'inside'"
/>
<n-progress
type="line"
:percentage="percentage"
:indicator-position="'inside-label'"
/>
<n-progress
type="line"
status="success"
:percentage="percentage"
:show-indicator="false"
/>
<n-progress
type="line"
status="success"
:percentage="percentage"
/>
<n-progress
type="line"
status="success"
:percentage="percentage"
:indicator-position="'inside'"
/>
<n-progress
type="line"
status="success"
:percentage="percentage"
:indicator-position="'inside-label'"
/>
<n-progress
type="line"
status="warning"
:percentage="percentage"
:show-indicator="false"
/>
<n-progress
type="line"
status="warning"
:percentage="percentage"
/>
<n-progress
type="line"
status="warning"
:percentage="percentage"
:indicator-position="'inside'"
/>
<n-progress
type="line"
status="warning"
:percentage="percentage"
:indicator-position="'inside-label'"
/>
<n-progress
type="line"
status="error"
:percentage="percentage"
:show-indicator="false"
/>
<n-progress
type="line"
status="error"
:percentage="percentage"
/>
<n-progress
type="line"
status="error"
:percentage="percentage"
:indicator-position="'inside'"
/>
<n-progress
type="line"
status="error"
:percentage="percentage"
:indicator-position="'inside-label'"
/>
<!--EXAMPLE_END-->
</div>
<div class="n-doc-section__inspect">
<n-button @click="minus">
minus
</n-button><n-button @click="add">
add
</n-button>
</div>
<n-doc-source-block>
<!--SOURCE-->
</n-doc-source-block>
</div>
</template>
<script>
export default {
data () {
return {
percentage: 50
}
},
methods: {
add () {
this.percentage += 10
if (this.percentage > 100) this.percentage = 0
},
minus () {
this.percentage -= 10
if (this.percentage < 0) this.percentage = 100
}
}
}
</script>

View File

@ -1,31 +0,0 @@
<template>
<div class="n-doc-section">
<div class="n-doc-section__header">
Scaffold
</div>
<div
class="n-doc-section__view"
style="flex-wrap: nowrap;"
>
<!--EXAMPLE_START-->
<n-progress
type="circle"
:percentage="60"
/>
<!--EXAMPLE_END-->
</div>
<pre class="n-doc-section__inspect">Inspect some value here</pre>
<n-doc-source-block>
<!--SOURCE-->
</n-doc-source-block>
</div>
</template>
<script>
export default {
data () {
return {
}
}
}
</script>

View File

@ -1,49 +1,224 @@
<template> <template>
<div <div
:style="{ class="n-progress"
width: width + 'px', :class="{
height: width + 'px' [`n-progress--${status}`]: status,
[`n-progress--${type}`]: type
}" }"
> >
<svg viewBox="0 0 100 100"> <div
<g> v-if="type === 'circle'"
<path class="n-progress-content"
d=" >
m 50 3 <div
a 47 47 0 1 1 0 94 class="n-progress-graph"
a 47 47 0 1 1 0 -94 >
" <div
stroke-width="3" class="n-progress-graph__circle"
stroke-linecap="round" >
stroke="white" <svg viewBox="0 0 110 110">
fill="none" <g>
style="stroke-dasharray: 157, 1000; stroke-dashoffset: 0;" <path
/> class="n-progress-graph__circle-rail"
</g> d="m 55 5 a 50 50 0 1 1 0 100 a 50 50 0 1 1 0 -100"
<g> stroke-width="10"
<path stroke-linecap="round"
d=" fill="none"
m 50 6 style="stroke-dashoffset: 0;"
a 44 44 0 1 1 0 88 />
a 44 44 0 1 1 0 -88 </g>
" <g>
stroke-width="3" <path
stroke-linecap="round" class="n-progress-graph__circle-fill"
stroke="red" d="m 55 5 a 50 50 0 1 1 0 100 a 50 50 0 1 1 0 -100"
fill="none" stroke-width="10"
style="stroke-dasharray: 120, 1000; stroke-dashoffset: 0;" stroke-linecap="round"
/> fill="none"
</g> :style="`stroke-dasharray: ${strokeDasharray}; stroke-dashoffset: 0;`"
</svg> />
</g>
</svg>
</div>
</div>
<div v-if="showIndicator && indicatorPosition === 'outside'">
<div
v-if="status"
class="n-progress-icon"
>
<n-icon :type="iconType" />
</div>
<div
v-else
class="n-progress-text"
>
<span class="n-progress-text__percentage">{{ percentage }}</span>
<span class="n-progress-text__unit">{{ unit }}</span>
</div>
</div>
</div>
<div
v-else-if="type === 'line'"
class="n-progress-content"
>
<div class="n-progress-graph">
<div
ref="line"
class="n-progress-graph__line"
:class="{
[`n-progress-graph__line--indicator-${indicatorPosition}`]: true
}"
>
<div class="n-progress-graph__line-rail">
<div
class="n-progress-graph__line-fill"
:style="{
maxWidth: percentage + '%'
}"
>
<div
v-if="indicatorPosition === 'inside'"
class="n-progress-graph__line-indicator"
>
{{ percentage + unit }}
</div>
</div>
</div>
<div
v-if="indicatorPosition === 'inside-label'"
ref="indicator"
class="n-progress-graph__line-indicator"
:style="indicatorPercentageIsCaculated ? {
right: `${indicatorPercentage}%`
} : {
transition: 'none',
right: `${indicatorPercentage}%`
}"
>
{{ percentage + unit }}
</div>
</div>
</div>
<div v-if="showIndicator && indicatorPosition === 'outside'">
<div
v-if="status"
class="n-progress-icon"
>
<n-icon :type="iconType" />
</div>
<div
v-else
class="n-progress-text"
>
<span class="n-progress-text__percentage">{{ percentage }}</span>
<span class="n-progress-text__unit">{{ unit }}</span>
</div>
</div>
</div>
</div> </div>
</template> </template>
<script> <script>
import NIcon from '../../Icon'
export default { export default {
name: 'NProgress', name: 'NProgress',
components: {
NIcon
},
props: {
type: {
validator (type) {
return ['line', 'circle', 'double-circle'].includes(type)
},
default: 'line'
},
status: {
validator (status) {
return ['success', 'error', 'warning'].includes(status)
},
default: null
},
color: {
type: String,
default: null
},
percentage: {
type: Number,
default: 0
},
unit: {
type: String,
default: '%'
},
showIndicator: {
type: Boolean,
default: true
},
indicatorPosition: {
validator (indicatorPosition) {
return ['inside', 'inside-label', 'outside'].includes(indicatorPosition)
},
default: 'outside'
}
},
data () { data () {
return { return {
width: 126 indicatorPercentage: 50,
indicatorPercentageIsCaculated: false
}
},
computed: {
strokeDasharray () {
return `${Math.PI * this.percentage}, 500`
},
iconType () {
if (this.type === 'circle') {
if (this.status === 'success') {
return 'md-checkmark'
} else if (this.status === 'error') {
return 'md-close'
} else if (this.status === 'warning') {
return 'md-alert'
}
} else if (this.type === 'line') {
if (this.status === 'success') {
return 'md-checkmark-circle'
} else if (this.status === 'error') {
return 'md-close-circle'
} else if (this.status === 'warning') {
return 'md-alert'
}
} return ''
}
},
watch: {
percentage (newPercentage) {
if (this.indicatorPosition === 'inside-label') {
this.$nextTick().then(() => {
this.indicatorPercentage = this.calcIndicatorPercentage()
})
}
}
},
mounted () {
if (this.indicatorPosition === 'inside-label') {
this.$nextTick().then(() => {
this.indicatorPercentage = this.calcIndicatorPercentage()
this.$nextTick().then(() => {
this.indicatorPercentageIsCaculated = true
})
})
}
},
methods: {
calcIndicatorPercentage () {
const lineRect = this.$refs.line.getBoundingClientRect()
const indicator = this.$refs.indicator.getBoundingClientRect()
const quotient = indicator.width / lineRect.width
let indicatorPercentage = 100 - this.percentage - quotient / 2 * 100
indicatorPercentage = Math.min(indicatorPercentage, 100 - quotient * 100)
indicatorPercentage = Math.max(indicatorPercentage, 0)
return indicatorPercentage
} }
} }
} }

183
styles/Progress.scss Normal file
View File

@ -0,0 +1,183 @@
@import "./mixins/mixins.scss";
@import "./theme/default.scss";
.n-progress {
color: rgba(98, 187, 252, 1);
&.n-progress--line {
width: 350px;
.n-progress-content {
display: flex;
align-items: center;
.n-progress-graph {
flex: 1;
}
}
.n-progress-icon {
width: 46px;
padding-left: 14px;
height: 24px;
font-size: 24px;
}
.n-progress-text {
color: inherit;
white-space: nowrap;
font-weight: bold;
line-height: 24px;
width: 60px;
.n-progress-text__percentage {
font-size: 18px;
margin-left: 14px;
}
.n-progress-text__unit {
font-size: 18px;
}
}
}
&.n-progress--circle {
width: 120px;
.n-progress-text, .n-progress-icon {
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
display: flex;
align-items: center;
color: inherit;
font-size: 36px;
}
.n-progress-text {
white-space: nowrap;
font-weight: bold;
.n-progress-text__percentage {
font-size: 28px;
}
.n-progress-text__unit {
font-size: 24px;
margin-left: 6px;
}
}
}
&.n-progress--success{
color: rgba(99, 226, 183, 1);
.n-progress-graph {
.n-progress-graph__circle {
.n-progress-graph__circle-fill {
stroke: rgba(99, 226, 183, 1);
}
}
.n-progress-graph__line {
.n-progress-graph__line-fill, .n-progress-graph__line-indicator {
background-color: rgba(99, 226, 183, 1);
}
}
}
}
&.n-progress--error{
color: rgba(255, 146, 164, 1);
.n-progress-graph {
.n-progress-graph__circle {
.n-progress-graph__circle-fill {
stroke: rgba(255, 146, 164, 1);
}
}
.n-progress-graph__line {
.n-progress-graph__line-fill, .n-progress-graph__line-indicator {
background-color: rgba(255, 146, 164, 1);
}
}
}
}
&.n-progress--warning{
color: rgba(255, 138, 0, 1);
.n-progress-graph {
.n-progress-graph__circle {
.n-progress-graph__circle-fill {
stroke: rgba(255, 138, 0, 1);
}
}
.n-progress-graph__line {
.n-progress-graph__line-fill, .n-progress-graph__line-indicator {
background-color: rgba(255, 138, 0, 1);
}
}
}
}
.n-progress-content {
position: relative;
}
.n-progress-graph {
position: relative;
.n-progress-graph__circle {
vertical-align: bottom;
.n-progress-graph__circle-rail {
stroke: rgba(255, 255, 255, .3);
}
.n-progress-graph__circle-fill {
transition: stroke-dasharray .3s $default-cubic-bezier;
stroke: rgba(98, 187, 252, 1);
}
}
.n-progress-graph__line {
&.n-progress-graph__line--indicator-inside {
.n-progress-graph__line-rail {
height: 33px;
border-radius: 16.5px;
}
.n-progress-graph__line-fill {
height: 33px;
border-radius: 16.5px;
}
.n-progress-graph__line-indicator {
background-color: none;
color: rgba(23, 29, 51, 1);
white-space: nowrap;
text-align: right;
font-weight: bold;
margin-left: 14px;
margin-right: 14px;
height: 33px;
font-size: 18px;
line-height: 33px;
}
}
&.n-progress-graph__line--indicator-inside-label {
height: 33px;
display: flex;
align-items: center;
.n-progress-graph__line-rail {
flex: 1;
}
.n-progress-graph__line-indicator {
transition: right .2s $default-cubic-bezier;
height: 33px;
line-height: 33px;
padding: 0 10px;
border-radius: 16.5px;
position: absolute;
color: rgba(23, 29, 51, 1);
white-space: nowrap;
font-weight: bold;
font-size: 18px;
}
}
.n-progress-graph__line-rail {
overflow: hidden;
height: 15px;
background-color: rgba(255, 255, 255, .3);
border-radius: 7.5px;
}
.n-progress-graph__line-fill {
background-color: rgba(98, 187, 252, 1);
border-radius: 7.5px;
height: 15px;
width: 100%;
max-width: 0%;
transition: max-width .2s $default-cubic-bezier;
}
.n-progress-graph__line-indicator {
background-color: rgba(98, 187, 252, 1);
}
}
}
}

View File

@ -26,6 +26,7 @@
@import './TimePicker.scss'; @import './TimePicker.scss';
@import './Scrollbar.scss'; @import './Scrollbar.scss';
@import './Steps.scss'; @import './Steps.scss';
@import './Progress.scss';
@import "./NimbusServiceLayout.scss"; @import "./NimbusServiceLayout.scss";
@import "./Popover.scss"; @import "./Popover.scss";