Skip to content

V2 loader option #90

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Oct 30, 2020
Merged
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ After you have initialized the component, use it everywhere you want in your app
dash="60 0.9"
animation="reverse 700 400"
:noData="false"
:loading="false"
:loading="false"
:loader="{ color: 'green' }"
fontColor="white"
:half="false"
:gap="10"
Expand Down Expand Up @@ -115,6 +116,7 @@ This table below provides a quick overview over all available options. To gain m
| **[`legendFormatter`](#legendformatter)** [![npm](https://img.shields.io/badge/v1.3.0-blue?style=flat-square)](#legendformatter) | Function | Function that returns formatted value | |
| **[`animation`](#animation)** | String | "default \| rs \| loop \| reverse \| bounce [duration delay]" | "default 1000 400"|
| **[`loading`](#loading)** | Boolean | |false|
| **[`loader`](#loading)** | Object | { [thickness, color, lineMode, line, opacity ]} | |
| **[`determinate`](#determinate)** | Boolean | |false|
| **[`noData`](#nodata)** | Boolean | |false|
| **[`angle`](#angle)** | Number | any Number |-90|
Expand Down Expand Up @@ -406,6 +408,21 @@ Forces loading state. The component provides an indeterminate loading state for

<br>

- ### `loader`

With this option defined as Object you can customize the loading circle that is shown in the states
[loading](#loading) and [determinate](#determinate). Accepted properties are [`color`](#color), [`thickness`](#thickness), [`line`](#line),
[`lineMode`](#linemode) and `opactity`. `opacity` is specific for loading circle and can be any valid CSS opacity value. If the option is not specified, the loading circle replicates the progress circle with a 0.55 default value for `opacity`.

###### Example: :scroll:

```vue
<vue-ellipse-progress :loader="{ color: 'green', lineMode: 'in 10', opacity: '0.6' }" />

```

<br>

- ### `determinate`

Provides a determinate loading state that indicates that your data loading is still in progress but allows to show the **[`progress`](#progress)**.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vue-ellipse-progress",
"version": "2.0.0-alpha.2",
"version": "2.0.0-alpha.3",
"private": false,
"description": "A Vue.js component to create beautiful animated circular progress bars",
"main": "./dist/vue-ellipse-progress.umd.min.js",
Expand Down
2 changes: 2 additions & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
:thickness="20"
:empty-thickness="10"
dot="10 red"
:loader="{ thickness: 40, color: 'red' }"
line-mode="bottom"
:no-data="noData"
:determinate="determinate"
Expand All @@ -73,6 +74,7 @@
line-mode="out 20"
:no-data="noData"
:determinate="determinate"
:loader="{ thickness: 40, color: 'red' }"
>
<template v-slot:legend-caption>
<p slot="legend-caption">TASKS DONE</p>
Expand Down
24 changes: 3 additions & 21 deletions src/components/Circle/Circle.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,7 @@
</circle>
<fade-in-transition>
<g v-if="isLoading">
<g class="ep-circle--loading__container" :style="{ opacity: `${options.loading ? 1 : 0.45}` }">
<circle
class="ep-circle--loading animation__loading"
:r="radius"
:cx="position"
:cy="position"
fill="transparent"
:stroke="computedColor"
:stroke-width="thickness"
:stroke-linecap="options.line"
:stroke-dasharray="circumference"
:style="{
transitionTimingFunction: styles.transitionTimingFunction,
transformOrigin: styles.transformOrigin,
'--ep-loading-stroke-offset': styles['--ep-loading-stroke-offset'],
'--ep-circumference': styles['--ep-circumference'],
}"
>
</circle>
</g>
<circle-loader :options="options.loader" />
</g>
</fade-in-transition>
<circle
Expand All @@ -67,10 +48,11 @@
<script>
import CircleMixin from "./circleMixin";
import FadeInTransition from "../FadeInTransition.vue";
import CircleLoader from "./CircleLoader.vue";

export default {
name: "CircleProgress",
components: { FadeInTransition },
components: { CircleLoader, FadeInTransition },
mixins: [CircleMixin],
computed: {
position() {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Circle/CircleContainer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import CircleProgress from "./Circle.vue";
import CircleDot from "./CircleDot.vue";

export default {
name: "EpCircleContainer",
name: "CircleContainer",
components: { CircleDot, CircleProgress, HalfCircleProgress, Gradient },
props: {
options: {
Expand Down
44 changes: 44 additions & 0 deletions src/components/Circle/CircleLoader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<template>
<g class="ep-circle--loader__container" :style="{ opacity: opacity }">
<circle
class="ep-circle--loader animation__loading"
:r="radius"
:cx="position"
:cy="position"
fill="transparent"
:stroke="computedColor"
:stroke-width="thickness"
:stroke-linecap="options.line"
:stroke-dasharray="circumference"
:style="{
transitionTimingFunction: styles.transitionTimingFunction,
transformOrigin: styles.transformOrigin,
'--ep-loading-stroke-offset': styles['--ep-loading-stroke-offset'],
'--ep-circumference': styles['--ep-circumference'],
}"
>
</circle>
</g>
</template>

<script>
import CircleMixin from "./circleMixin";

export default {
name: "CircleLoader",
mixins: [CircleMixin],
computed: {
position() {
return this.options.size / 2;
},
circumference() {
return this.radius * 2 * Math.PI;
},
opacity() {
return this.options.opacity && this.options.opacity >= 0 ? this.options.opacity : 0.55;
},
},
};
</script>

<style scoped lang="scss"></style>
23 changes: 3 additions & 20 deletions src/components/Circle/HalfCircle.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,7 @@
</path>
<fade-in-transition>
<g v-if="isLoading">
<g :style="{ opacity: `${options.loading ? 1 : 0.45}` }">
<path
:stroke-width="thickness"
class="ep-half-circle--loading animation__loading"
:d="path"
:fill="computedColorFill"
:stroke="computedColor"
:stroke-dasharray="circumference"
:stroke-linecap="options.line"
:style="{
transitionTimingFunction: styles.transitionTimingFunction,
transformOrigin: styles.transformOrigin,
'--ep-loading-stroke-offset': styles['--ep-loading-stroke-offset'],
'--ep-circumference': styles['--ep-circumference'],
'--ep-negative-circumference': styles['--ep-negative-circumference'],
}"
>
</path>
</g>
<half-circle-loader :options="options.loader" />
</g>
</fade-in-transition>

Expand All @@ -63,10 +45,11 @@
<script>
import CircleMixin from "./circleMixin";
import FadeInTransition from "../FadeInTransition.vue";
import HalfCircleLoader from "./HalfCircleLoader.vue";

export default {
name: "HalfCircleProgress",
components: { FadeInTransition },
components: { HalfCircleLoader, FadeInTransition },
mixins: [CircleMixin],
computed: {
circumference() {
Expand Down
57 changes: 57 additions & 0 deletions src/components/Circle/HalfCircleLoader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<template>
<g :style="{ opacity: opacity }">
<path
:stroke-width="thickness"
class="ep-half-circle--loader animation__loading"
:d="path"
:fill="computedColorFill"
:stroke="computedColor"
:stroke-dasharray="circumference"
:stroke-linecap="options.line"
:style="{
transitionTimingFunction: styles.transitionTimingFunction,
transformOrigin: styles.transformOrigin,
'--ep-loading-stroke-offset': styles['--ep-loading-stroke-offset'],
'--ep-circumference': styles['--ep-circumference'],
'--ep-negative-circumference': styles['--ep-negative-circumference'],
}"
>
</path>
</g>
</template>
<script>
import CircleMixin from "./circleMixin";

export default {
name: "HalfCircleLoader",
mixins: [CircleMixin],
computed: {
circumference() {
return (this.radius * 2 * Math.PI) / 2;
},
path() {
return ` M ${this.position}, ${this.options.size / 2} a ${this.radius},${this.radius} 0 1,1 ${this.radius * 2},0`;
},
emptyPath() {
return ` M ${this.emptyPosition}, ${this.options.size / 2} a ${this.emptyRadius},${this.emptyRadius} 0 1,1 ${
this.emptyRadius * 2
},0`;
},
position() {
return this.options.size / 2 - this.radius;
},
emptyPosition() {
return this.options.size / 2 - this.emptyRadius;
},
opacity() {
return this.options.opacity && this.options.opacity >= 0 ? this.options.opacity : 0.55;
},
},
};
</script>

<style scoped lang="scss">
g.ep-half-circle {
transform-origin: 50% 50%;
}
</style>
24 changes: 13 additions & 11 deletions src/components/VueEllipseProgress.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import { getNumberIfValid, isValidNumber } from "../utils";
import props from "./interface";
import CircleContainer from "./Circle/CircleContainer.vue";
import Counter from "./Counter.vue";
import parseOptions from "./optionsParser";
import { parseOptions, calcThickness, lineModeParser } from "./optionsParser";

export default {
name: "VueEllipseProgress",
Expand Down Expand Up @@ -84,17 +84,19 @@ export default {
const previousCircles = [];
for (let i = 0; i < this.circlesData.length; i++) {
const options = this.circlesData[i];
normalizedCircles.push({
...parseOptions({
index: i,
id: i,
...options,
globalDot: this.dot,
globalGap: this.gap,
globalThickness: this.thickness,
previousCircles: [...previousCircles],
}),
const parsedOptions = parseOptions({
index: i,
id: i,
...options,
globalDot: this.dot,
globalGap: this.gap,
globalThickness: this.thickness,
previousCircles: [...previousCircles],
});
const loaderOptions = { ...parsedOptions, ...parsedOptions.loader };
loaderOptions.thickness = calcThickness(loaderOptions.thickness, parsedOptions.size);
loaderOptions.lineMode = parsedOptions.loader.lineMode ? lineModeParser(loaderOptions) : parsedOptions.lineMode;
normalizedCircles.push({ ...parsedOptions, loader: loaderOptions });
const { gap, thickness, dot } = normalizedCircles[i];
previousCircles.push({ gap, thickness, dot });
}
Expand Down
21 changes: 20 additions & 1 deletion src/components/interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ const colorConfig = (defaultColor = "transparent") => ({
},
});

export default {
const validateLoaderProps = (loaderOptions) =>
Object.keys(loaderOptions).every((p) => options[p].validator(loaderOptions[p]));

const options = {
data: {
type: Array,
required: false,
Expand Down Expand Up @@ -164,4 +167,20 @@ export default {
type: Function,
required: false,
},
loader: {
type: Object,
required: false,
default: () => ({}),
validator: (value) => {
const propsAllowed = Object.keys(value).every((prop) =>
["thickness", "color", "lineMode", "line", "opacity"].includes(prop)
);
if (propsAllowed) {
return validateLoaderProps(value);
}
return false;
},
},
};

export default options;
6 changes: 3 additions & 3 deletions src/components/optionsParser.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getNumberIfValid, isValidNumber } from "@/utils";

const lineModeParser = (options) => {
export const lineModeParser = (options) => {
const lineModeConfig = options.lineMode.trim().split(" ");
const mode = options.multiple ? "multiple" : lineModeConfig[0];
return {
Expand Down Expand Up @@ -49,12 +49,12 @@ const dotParser = (dot) => {
};
};

const calcThickness = (thickness, size) => {
export const calcThickness = (thickness, size) => {
const value = parseFloat(thickness);
return thickness.toString().includes("%") ? (value * size) / 100 : value;
};

export default (options) => {
export const parseOptions = (options) => {
const dot = dotParser(options.dot);
const globalDot = dotParser(options.globalDot);
return {
Expand Down
4 changes: 2 additions & 2 deletions src/styles/animationsUsage.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
}
}

.ep-circle--loading {
.ep-circle--loader {
&.animation__loading {
animation-name: ep-progress--loading, ep-progress--loading__rotation;
animation-iteration-count: infinite !important;
Expand All @@ -26,7 +26,7 @@
}
}

.ep-half-circle--loading {
.ep-half-circle--loader {
&.animation__loading {
animation-name: ep-half-progress--loading;
animation-iteration-count: infinite !important;
Expand Down