Files
vue-flow/src/additional-components/Background/Background.vue
T
2021-10-21 13:57:20 +02:00

74 lines
2.0 KiB
Vue

<script lang="ts" setup>
import { SVGAttributes } from 'vue'
import { BackgroundVariant } from '~/types'
import { useStore } from '~/composables'
export interface BackgroundProps extends SVGAttributes {
variant?: BackgroundVariant
gap?: number
color?: string
size?: number
}
const props = withDefaults(defineProps<BackgroundProps>(), {
variant: BackgroundVariant.Dots,
gap: 10,
size: 0.4,
})
const defaultColors: Record<BackgroundVariant, string> = {
[BackgroundVariant.Dots]: '#81818a',
[BackgroundVariant.Lines]: '#eee',
}
const store = useStore()
const background = computed(() => {
const scaledGap = props.gap && props.gap * store.transform[2]
const xOffset = scaledGap && store.transform[0] % scaledGap
const yOffset = scaledGap && store.transform[1] % scaledGap
const size = props.size || 0.4 * store.transform[2]
return {
scaledGap,
xOffset,
yOffset,
size,
}
})
// when there are multiple flows on a page we need to make sure that every background gets its own pattern.
const patternId = `pattern-${Math.floor(Math.random() * 100000)}`
</script>
<template>
<svg
class="vue-flow__background"
:style="{
width: '100%',
height: '100%',
}"
>
<pattern
:id="patternId"
:x="background.xOffset"
:y="background.yOffset"
:width="background.scaledGap"
:height="background.scaledGap"
patternUnits="userSpaceOnUse"
>
<template v-if="props.variant === BackgroundVariant.Lines">
<path
:stroke="props.color ? props.color : defaultColors[props.variant || BackgroundVariant.Dots]"
:stroke-width="props.size"
:d="`M${background.scaledGap / 2} 0 V${background.scaledGap} M0 ${background.scaledGap / 2} H${background.scaledGap}`"
/>
</template>
<template v-else>
<circle :cx="background.size" :cy="background.size" :r="background.size" :fill="bgColor" />
</template>
</pattern>
<rect x="0" y="0" width="100%" height="100%" :fill="`url(#${patternId})`" />
<slot></slot>
</svg>
</template>