mirror of
https://github.com/dataease/dataease.git
synced 2026-06-14 17:51:43 +08:00
feat(数据大屏): 内置动态装饰
This commit is contained in:
@@ -79,6 +79,36 @@ export const CANVAS_MATERIAL = [
|
||||
title: t('visualization.decoration'),
|
||||
span: 8,
|
||||
details: [
|
||||
{
|
||||
value: 'DeDecoration1',
|
||||
type: 'de_decoration',
|
||||
title: t('visualization.decoration_name', [11]),
|
||||
icon: 'DeDecoration1'
|
||||
},
|
||||
{
|
||||
value: 'DeDecoration2',
|
||||
type: 'de_decoration',
|
||||
title: t('visualization.decoration_name', [12]),
|
||||
icon: 'DeDecoration2'
|
||||
},
|
||||
{
|
||||
value: 'DeDecoration3',
|
||||
type: 'de_decoration',
|
||||
title: t('visualization.decoration_name', [12]),
|
||||
icon: 'DeDecoration3'
|
||||
},
|
||||
{
|
||||
value: 'DeDecoration4',
|
||||
type: 'de_decoration',
|
||||
title: t('visualization.decoration_name', [12]),
|
||||
icon: 'DeDecoration4'
|
||||
},
|
||||
{
|
||||
value: 'DeDecoration5',
|
||||
type: 'de_decoration',
|
||||
title: t('visualization.decoration_name', [12]),
|
||||
icon: 'DeDecoration5'
|
||||
},
|
||||
{
|
||||
value: 'DeBoard1',
|
||||
type: 'de_decoration',
|
||||
|
||||
@@ -501,6 +501,10 @@ const list = [
|
||||
style: {
|
||||
width: 400,
|
||||
height: 300,
|
||||
color0: null,
|
||||
color1: null,
|
||||
color2: null,
|
||||
dur: 6,
|
||||
borderActive: false,
|
||||
backdropFilter: 'blur(0px)'
|
||||
}
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
<template>
|
||||
<div class="dv-decoration-1" :style="border_style" :ref="refName">
|
||||
<svg
|
||||
:width="`${svgWH[0]}px`"
|
||||
:height="`${svgWH[1]}px`"
|
||||
:style="`transform:scale(${svgScale[0]},${svgScale[1]});`"
|
||||
>
|
||||
<template v-for="(point, i) in points" :key="i">
|
||||
<rect
|
||||
v-if="Math.random() > 0.6"
|
||||
:fill="mergedColor[0]"
|
||||
:x="point[0] - halfPointSideLength"
|
||||
:y="point[1] - halfPointSideLength"
|
||||
:width="pointSideLength"
|
||||
:height="pointSideLength"
|
||||
>
|
||||
<animate
|
||||
v-if="Math.random() > 0.6"
|
||||
attributeName="fill"
|
||||
:values="`${mergedColor[0]};transparent`"
|
||||
dur="1s"
|
||||
:begin="Math.random() * 2"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</rect>
|
||||
</template>
|
||||
|
||||
<rect
|
||||
v-if="rects[0]"
|
||||
:fill="mergedColor[1]"
|
||||
:x="rects[0][0] - pointSideLength"
|
||||
:y="rects[0][1] - pointSideLength"
|
||||
:width="pointSideLength * 2"
|
||||
:height="pointSideLength * 2"
|
||||
>
|
||||
<animate
|
||||
attributeName="width"
|
||||
:values="`0;${pointSideLength * 2}`"
|
||||
dur="2s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
<animate
|
||||
attributeName="height"
|
||||
:values="`0;${pointSideLength * 2}`"
|
||||
dur="2s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
<animate
|
||||
attributeName="x"
|
||||
:values="`${rects[0][0]};${rects[0][0] - pointSideLength}`"
|
||||
dur="2s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
<animate
|
||||
attributeName="y"
|
||||
:values="`${rects[0][1]};${rects[0][1] - pointSideLength}`"
|
||||
dur="2s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</rect>
|
||||
|
||||
<rect
|
||||
v-if="rects[1]"
|
||||
:fill="mergedColor[1]"
|
||||
:x="rects[1][0] - 40"
|
||||
:y="rects[1][1] - pointSideLength"
|
||||
:width="40"
|
||||
:height="pointSideLength * 2"
|
||||
>
|
||||
<animate attributeName="width" values="0;40;0" dur="2s" repeatCount="indefinite" />
|
||||
<animate
|
||||
attributeName="x"
|
||||
:values="`${rects[1][0]};${rects[1][0] - 40};${rects[1][0]}`"
|
||||
dur="2s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</rect>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, watch, onMounted } from 'vue'
|
||||
import { cloneDeep, merge } from 'lodash-es'
|
||||
|
||||
interface Props {
|
||||
color?: string[]
|
||||
curStyle: object
|
||||
scale: number
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
color: () => [],
|
||||
curStyle: () => {
|
||||
return {
|
||||
width: '320px',
|
||||
height: '240px'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const width = computed(() => {
|
||||
return parseInt(props.curStyle.width) / props.scale
|
||||
})
|
||||
|
||||
const height = computed(() => {
|
||||
return parseInt(props.curStyle.height) / props.scale
|
||||
})
|
||||
|
||||
const border_style = computed(() => {
|
||||
return {
|
||||
width: `${width.value}px`,
|
||||
height: `${height.value}px`,
|
||||
zoom: props.scale
|
||||
}
|
||||
})
|
||||
|
||||
const pointSideLength = 2.5
|
||||
const refName = ref('decoration-1')
|
||||
const svgWH = ref([200, 50])
|
||||
const svgScale = ref([1, 1])
|
||||
const rowNum = 4
|
||||
const rowPoints = 20
|
||||
const halfPointSideLength = computed(() => pointSideLength / 2)
|
||||
const points = ref<number[][]>([])
|
||||
const rects = ref<number[][]>([])
|
||||
const defaultColor = ref(['#fff', '#0de7c2'])
|
||||
const mergedColor = ref<string[]>([])
|
||||
|
||||
const calcPointsPosition = () => {
|
||||
const [w, h] = svgWH.value
|
||||
const horizontalGap = w / (rowPoints + 1)
|
||||
const verticalGap = h / (rowNum + 1)
|
||||
|
||||
let pointsArray = new Array(rowNum)
|
||||
.fill(0)
|
||||
.map((_, i) =>
|
||||
new Array(rowPoints).fill(0).map((_, j) => [horizontalGap * (j + 1), verticalGap * (i + 1)])
|
||||
)
|
||||
|
||||
points.value = pointsArray.reduce((all, item) => [...all, ...item], [])
|
||||
}
|
||||
|
||||
const calcRectsPosition = () => {
|
||||
const rect1 = points.value[rowPoints * 2 - 1]
|
||||
const rect2 = points.value[rowPoints * 2 - 3]
|
||||
rects.value = [rect1, rect2]
|
||||
}
|
||||
|
||||
const calcScale = () => {
|
||||
const [w, h] = svgWH.value
|
||||
svgScale.value = [width.value / w, height.value / h]
|
||||
}
|
||||
|
||||
const calcSVGData = () => {
|
||||
calcPointsPosition()
|
||||
calcRectsPosition()
|
||||
calcScale()
|
||||
}
|
||||
|
||||
const mergeColor = () => {
|
||||
mergedColor.value = merge(cloneDeep(defaultColor.value), props.color || []) as string[]
|
||||
}
|
||||
|
||||
const onResize = () => {
|
||||
calcSVGData()
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.color,
|
||||
() => {
|
||||
mergeColor()
|
||||
}
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
mergeColor()
|
||||
calcSVGData()
|
||||
})
|
||||
|
||||
// Handle autoResize mixin
|
||||
// Note: In Vue 3, consider converting autoResize to a composable
|
||||
watch([width, height], () => {
|
||||
onResize()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.dv-decoration-1 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
svg {
|
||||
transform-origin: left top;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<div class="dv-decoration-2" :style="border_style" :ref="refName">
|
||||
<svg :width="`${width}px`" :height="`${height}px`">
|
||||
<rect :x="x" :y="y" :width="w" :height="h" :fill="mergedColor[0]">
|
||||
<animate
|
||||
:attributeName="reverse ? 'height' : 'width'"
|
||||
from="0"
|
||||
:to="reverse ? height : width"
|
||||
:dur="`${dur}s`"
|
||||
calcMode="spline"
|
||||
keyTimes="0;1"
|
||||
keySplines=".42,0,.58,1"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</rect>
|
||||
|
||||
<rect :x="x" :y="y" width="1" height="1" :fill="mergedColor[1]">
|
||||
<animate
|
||||
:attributeName="reverse ? 'y' : 'x'"
|
||||
from="0"
|
||||
:to="reverse ? height : width"
|
||||
:dur="`${dur}s`"
|
||||
calcMode="spline"
|
||||
keyTimes="0;1"
|
||||
keySplines="0.42,0,0.58,1"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</rect>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, watch, onMounted } from 'vue'
|
||||
import { cloneDeep, merge } from 'lodash-es'
|
||||
|
||||
interface Props {
|
||||
color?: string[]
|
||||
curStyle: object
|
||||
scale: number
|
||||
reverse?: boolean
|
||||
dur?: number
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
color: () => [],
|
||||
curStyle: () => {
|
||||
return {
|
||||
width: '320px',
|
||||
height: '240px'
|
||||
}
|
||||
},
|
||||
reverse: false,
|
||||
dur: 6
|
||||
})
|
||||
|
||||
const refName = ref('decoration-2')
|
||||
const x = ref(0)
|
||||
const y = ref(0)
|
||||
const w = ref(0)
|
||||
const h = ref(0)
|
||||
const defaultColor = ref(['#3faacb', '#fff'])
|
||||
const mergedColor = ref<string[]>([])
|
||||
|
||||
const width = computed(() => {
|
||||
return parseInt(props.curStyle.width) / props.scale
|
||||
})
|
||||
|
||||
const height = computed(() => {
|
||||
return parseInt(props.curStyle.height) / props.scale
|
||||
})
|
||||
|
||||
const border_style = computed(() => {
|
||||
return {
|
||||
width: `${width.value}px`,
|
||||
height: `${height.value}px`,
|
||||
zoom: props.scale
|
||||
}
|
||||
})
|
||||
|
||||
const calcSVGData = () => {
|
||||
if (props.reverse) {
|
||||
w.value = 1
|
||||
h.value = height.value
|
||||
x.value = width.value / 2
|
||||
y.value = 0
|
||||
} else {
|
||||
w.value = width.value
|
||||
h.value = 1
|
||||
x.value = 0
|
||||
y.value = height.value / 2
|
||||
}
|
||||
}
|
||||
|
||||
const mergeColor = () => {
|
||||
mergedColor.value = merge(cloneDeep(defaultColor.value), props.color || []) as string[]
|
||||
}
|
||||
|
||||
// Watchers
|
||||
watch(
|
||||
() => props.color,
|
||||
() => {
|
||||
mergeColor()
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.reverse,
|
||||
() => {
|
||||
calcSVGData()
|
||||
}
|
||||
)
|
||||
|
||||
watch([width, height], () => {
|
||||
calcSVGData()
|
||||
})
|
||||
|
||||
// Lifecycle hooks
|
||||
onMounted(() => {
|
||||
mergeColor()
|
||||
calcSVGData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.dv-decoration-2 {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<div class="dv-decoration-3" :style="border_style" :ref="refName">
|
||||
<svg
|
||||
:width="`${svgWH[0]}px`"
|
||||
:height="`${svgWH[1]}px`"
|
||||
:style="`transform:scale(${svgScale[0]},${svgScale[1]});`"
|
||||
>
|
||||
<rect
|
||||
v-for="(point, i) in points"
|
||||
:key="i"
|
||||
:fill="mergedColor[0]"
|
||||
:x="point[0] - halfPointSideLength"
|
||||
:y="point[1] - halfPointSideLength"
|
||||
:width="pointSideLength"
|
||||
:height="pointSideLength"
|
||||
>
|
||||
<animate
|
||||
v-if="Math.random() > 0.6"
|
||||
attributeName="fill"
|
||||
:values="mergedColor.join(';')"
|
||||
:dur="`${Math.random() + 1}s`"
|
||||
:begin="`${Math.random() * 2}s`"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</rect>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, watch, onMounted } from 'vue'
|
||||
import { cloneDeep, merge } from 'lodash-es'
|
||||
|
||||
interface Props {
|
||||
color?: string[]
|
||||
curStyle: object
|
||||
scale: number
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
color: () => [],
|
||||
curStyle: () => {
|
||||
return {
|
||||
width: '320px',
|
||||
height: '240px'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const width = computed(() => {
|
||||
return parseInt(props.curStyle.width) / props.scale
|
||||
})
|
||||
|
||||
const height = computed(() => {
|
||||
return parseInt(props.curStyle.height) / props.scale
|
||||
})
|
||||
|
||||
const border_style = computed(() => {
|
||||
return {
|
||||
width: `${width.value}px`,
|
||||
height: `${height.value}px`,
|
||||
zoom: props.scale
|
||||
}
|
||||
})
|
||||
|
||||
const mergeColor = () => {
|
||||
mergedColor.value = merge(cloneDeep(defaultColor.value), props.color || []) as string[]
|
||||
}
|
||||
|
||||
// Constants
|
||||
const pointSideLength = 7
|
||||
const rowNum = 2
|
||||
const rowPoints = 25
|
||||
|
||||
// Refs
|
||||
const refName = ref('decoration-3')
|
||||
const svgWH = ref([300, 35])
|
||||
const svgScale = ref([1, 1])
|
||||
const points = ref<number[][]>([])
|
||||
const defaultColor = ref(['#7acaec', 'transparent'])
|
||||
const mergedColor = ref<string[]>([])
|
||||
|
||||
// Computed
|
||||
const halfPointSideLength = computed(() => pointSideLength / 2)
|
||||
|
||||
// Methods
|
||||
const calcPointsPosition = () => {
|
||||
const [w, h] = svgWH.value
|
||||
const horizontalGap = w / (rowPoints + 1)
|
||||
const verticalGap = h / (rowNum + 1)
|
||||
|
||||
const pointsArray = Array.from({ length: rowNum }, (_, i) =>
|
||||
Array.from({ length: rowPoints }, (_, j) => [horizontalGap * (j + 1), verticalGap * (i + 1)])
|
||||
)
|
||||
|
||||
points.value = pointsArray.flat()
|
||||
}
|
||||
|
||||
const calcScale = () => {
|
||||
const [w, h] = svgWH.value
|
||||
svgScale.value = [width.value / w, height.value / h]
|
||||
}
|
||||
|
||||
const calcSVGData = () => {
|
||||
calcPointsPosition()
|
||||
calcScale()
|
||||
}
|
||||
|
||||
const onResize = () => {
|
||||
calcSVGData()
|
||||
}
|
||||
|
||||
// Watchers
|
||||
watch(() => props.color, mergeColor)
|
||||
watch([width, height], onResize)
|
||||
|
||||
// Lifecycle
|
||||
onMounted(() => {
|
||||
mergeColor()
|
||||
calcSVGData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.dv-decoration-3 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
svg {
|
||||
transform-origin: left top;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,136 @@
|
||||
<template>
|
||||
<div class="dv-decoration-4" :style="border_style" :ref="refName">
|
||||
<div :class="['container', reverse ? 'reverse' : 'normal']" :style="containerStyle">
|
||||
<svg :width="reverse ? width : 5" :height="reverse ? 5 : height">
|
||||
<polyline
|
||||
:stroke="mergedColor[0]"
|
||||
:points="reverse ? `0, 2.5 ${width}, 2.5` : `2.5, 0 2.5, ${height}`"
|
||||
/>
|
||||
<polyline
|
||||
class="bold-line"
|
||||
:stroke="mergedColor[1]"
|
||||
stroke-width="3"
|
||||
stroke-dasharray="20, 80"
|
||||
stroke-dashoffset="-30"
|
||||
:points="reverse ? `0, 2.5 ${width}, 2.5` : `2.5, 0 2.5, ${height}`"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, watch, onMounted } from 'vue'
|
||||
import { cloneDeep, merge } from 'lodash-es'
|
||||
|
||||
interface Props {
|
||||
color?: string[]
|
||||
curStyle: object
|
||||
scale: number
|
||||
reverse?: boolean
|
||||
dur?: number
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
color: () => [],
|
||||
curStyle: () => {
|
||||
return {
|
||||
width: '320px',
|
||||
height: '240px'
|
||||
}
|
||||
},
|
||||
reverse: false,
|
||||
dur: 6
|
||||
})
|
||||
|
||||
const refName = ref('decoration-4')
|
||||
const defaultColor = ref(['rgba(255, 255, 255, 0.3)', 'rgba(255, 255, 255, 0.3)'])
|
||||
const mergedColor = ref<string[]>([])
|
||||
const width = computed(() => {
|
||||
return parseInt(props.curStyle.width) / props.scale
|
||||
})
|
||||
|
||||
const height = computed(() => {
|
||||
return parseInt(props.curStyle.height) / props.scale
|
||||
})
|
||||
|
||||
const border_style = computed(() => {
|
||||
return {
|
||||
width: `${width.value}px`,
|
||||
height: `${height.value}px`,
|
||||
zoom: props.scale
|
||||
}
|
||||
})
|
||||
|
||||
const mergeColor = () => {
|
||||
mergedColor.value = merge(cloneDeep(defaultColor.value), props.color || []) as string[]
|
||||
}
|
||||
|
||||
// Computed properties
|
||||
const containerStyle = computed(() => ({
|
||||
width: props.reverse ? `${width.value}px` : '5px',
|
||||
height: props.reverse ? '5px' : `${height.value}px`,
|
||||
animationDuration: `${props.dur}s`
|
||||
}))
|
||||
|
||||
// Watchers
|
||||
watch(() => props.color, mergeColor)
|
||||
|
||||
// Lifecycle
|
||||
onMounted(mergeColor)
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.dv-decoration-4 {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
flex: 1;
|
||||
|
||||
&.normal {
|
||||
animation: ani-height ease-in-out infinite;
|
||||
left: 50%;
|
||||
margin-left: -2px;
|
||||
}
|
||||
|
||||
&.reverse {
|
||||
animation: ani-width ease-in-out infinite;
|
||||
top: 50%;
|
||||
margin-top: -2px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ani-height {
|
||||
0% {
|
||||
height: 0%;
|
||||
}
|
||||
|
||||
70% {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
100% {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ani-width {
|
||||
0% {
|
||||
width: 0%;
|
||||
}
|
||||
|
||||
70% {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
100% {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<div class="dv-decoration-5" :style="border_style" :ref="refName">
|
||||
<svg :width="width" :height="height">
|
||||
<polyline fill="transparent" :stroke="mergedColor[0]" stroke-width="3" :points="line1Points">
|
||||
<animate
|
||||
attributeName="stroke-dasharray"
|
||||
attributeType="XML"
|
||||
:from="`0, ${line1Length / 2}, 0, ${line1Length / 2}`"
|
||||
:to="`0, 0, ${line1Length}, 0`"
|
||||
:dur="`${dur}s`"
|
||||
begin="0s"
|
||||
calcMode="spline"
|
||||
keyTimes="0;1"
|
||||
keySplines="0.4,1,0.49,0.98"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</polyline>
|
||||
<polyline fill="transparent" :stroke="mergedColor[1]" stroke-width="2" :points="line2Points">
|
||||
<animate
|
||||
attributeName="stroke-dasharray"
|
||||
attributeType="XML"
|
||||
:from="`0, ${line2Length / 2}, 0, ${line2Length / 2}`"
|
||||
:to="`0, 0, ${line2Length}, 0`"
|
||||
:dur="`${dur}s`"
|
||||
begin="0s"
|
||||
calcMode="spline"
|
||||
keyTimes="0;1"
|
||||
keySplines=".4,1,.49,.98"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</polyline>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, watch, onMounted } from 'vue'
|
||||
import { getPointDistances } from '@/custom-component/de-decoration/component_details/config'
|
||||
import { cloneDeep, merge, sum } from 'lodash-es'
|
||||
|
||||
interface Props {
|
||||
color?: string[]
|
||||
curStyle: object
|
||||
scale: number
|
||||
dur?: number
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
color: () => [],
|
||||
curStyle: () => {
|
||||
return {
|
||||
width: '320px',
|
||||
height: '240px'
|
||||
}
|
||||
},
|
||||
dur: 3
|
||||
})
|
||||
|
||||
const refName = ref('decoration-5')
|
||||
const line1Points = ref('')
|
||||
const line2Points = ref('')
|
||||
const line1Length = ref(0)
|
||||
const line2Length = ref(0)
|
||||
const defaultColor = ref(['#3f96a5', '#3f96a5'])
|
||||
const mergedColor = ref<string[]>([])
|
||||
|
||||
const width = computed(() => {
|
||||
return parseInt(props.curStyle.width) / props.scale
|
||||
})
|
||||
|
||||
const height = computed(() => {
|
||||
return parseInt(props.curStyle.height) / props.scale
|
||||
})
|
||||
|
||||
const border_style = computed(() => {
|
||||
return {
|
||||
width: `${width.value}px`,
|
||||
height: `${height.value}px`,
|
||||
zoom: props.scale
|
||||
}
|
||||
})
|
||||
|
||||
const mergeColor = () => {
|
||||
mergedColor.value = merge(cloneDeep(defaultColor.value), props.color || []) as string[]
|
||||
}
|
||||
|
||||
const calcSVGData = () => {
|
||||
const line1PointsArray = [
|
||||
[0, height.value * 0.2],
|
||||
[width.value * 0.18, height.value * 0.2],
|
||||
[width.value * 0.2, height.value * 0.4],
|
||||
[width.value * 0.25, height.value * 0.4],
|
||||
[width.value * 0.27, height.value * 0.6],
|
||||
[width.value * 0.72, height.value * 0.6],
|
||||
[width.value * 0.75, height.value * 0.4],
|
||||
[width.value * 0.8, height.value * 0.4],
|
||||
[width.value * 0.82, height.value * 0.2],
|
||||
[width.value, height.value * 0.2]
|
||||
]
|
||||
|
||||
const line2PointsArray = [
|
||||
[width.value * 0.3, height.value * 0.8],
|
||||
[width.value * 0.7, height.value * 0.8]
|
||||
]
|
||||
|
||||
line1Length.value = sum(getPointDistances(line1PointsArray))
|
||||
line2Length.value = sum(getPointDistances(line2PointsArray))
|
||||
|
||||
line1Points.value = line1PointsArray.map(point => point.join(',')).join(' ')
|
||||
line2Points.value = line2PointsArray.map(point => point.join(',')).join(' ')
|
||||
}
|
||||
|
||||
// Watchers
|
||||
watch(() => props.color, mergeColor)
|
||||
watch([width, height], calcSVGData)
|
||||
|
||||
// Lifecycle
|
||||
onMounted(() => {
|
||||
mergeColor()
|
||||
calcSVGData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.dv-decoration-5 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -8,6 +8,11 @@ import DeBoard7 from '@/custom-component/de-decoration/component_details/DeBoard
|
||||
import DeBoard8 from '@/custom-component/de-decoration/component_details/DeBoard8.vue'
|
||||
import DeBoard9 from '@/custom-component/de-decoration/component_details/DeBoard9.vue'
|
||||
import DeBoard10 from '@/custom-component/de-decoration/component_details/DeBoard10.vue'
|
||||
import DeDecoration1 from '@/custom-component/de-decoration/component_details/DeDecoration1.vue'
|
||||
import DeDecoration2 from '@/custom-component/de-decoration/component_details/DeDecoration2.vue'
|
||||
import DeDecoration3 from '@/custom-component/de-decoration/component_details/DeDecoration3.vue'
|
||||
import DeDecoration4 from '@/custom-component/de-decoration/component_details/DeDecoration4.vue'
|
||||
import DeDecoration5 from '@/custom-component/de-decoration/component_details/DeDecoration5.vue'
|
||||
|
||||
const boardInfoMap = {
|
||||
DeBoard1: DeBoard1,
|
||||
@@ -19,9 +24,32 @@ const boardInfoMap = {
|
||||
DeBoard7: DeBoard7,
|
||||
DeBoard8: DeBoard8,
|
||||
DeBoard9: DeBoard9,
|
||||
DeBoard10: DeBoard10
|
||||
DeBoard10: DeBoard10,
|
||||
DeDecoration1: DeDecoration1,
|
||||
DeDecoration2: DeDecoration2,
|
||||
DeDecoration3: DeDecoration3,
|
||||
DeDecoration4: DeDecoration4,
|
||||
DeDecoration5: DeDecoration5
|
||||
}
|
||||
|
||||
export const findDecoration = name => {
|
||||
return boardInfoMap[name]
|
||||
}
|
||||
|
||||
export const calcTwoPointDistance = (pointA, pointB) => {
|
||||
const minusX = Math.abs(pointA[0] - pointB[0])
|
||||
const minusY = Math.abs(pointA[1] - pointB[1])
|
||||
|
||||
return Math.sqrt(Math.pow(minusX, 2) + Math.pow(minusY, 2))
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取多个点,每个点之间的距离
|
||||
* @param {Point[]} points
|
||||
* @return {number[]}
|
||||
*/
|
||||
export function getPointDistances(points) {
|
||||
return new Array(points.length - 1)
|
||||
.fill(0)
|
||||
.map((_, i) => calcTwoPointDistance(points[i], points[i + 1]))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user