docs: add transition example

This commit is contained in:
braks
2022-10-07 23:49:03 +02:00
parent 40d59d9d84
commit 447699cb05
11 changed files with 265 additions and 7 deletions
@@ -0,0 +1,50 @@
<script setup>
import { ref } from 'vue'
import { ConnectionMode, Position, VueFlow, useVueFlow } from '@braks/vue-flow'
import TransitionEdge from './TransitionEdge.vue'
const elements = ref([
{
id: '1',
type: 'input',
label: 'Dblclick me',
position: { x: 0, y: 0 },
sourcePosition: Position.Right,
},
{
id: '2',
type: 'output',
label: 'Dblclick me',
position: { x: 1000, y: 1000 },
targetPosition: Position.Left,
},
{ id: 'e1-2', type: 'custom', source: '1', target: '2', animated: true, style: { stroke: '#fff' } },
])
const bgColor = ref('#1A192B')
const connectionLineStyle = { stroke: '#fff' }
const snapGrid = [16, 16]
const { onPaneReady } = useVueFlow({
connectionMode: ConnectionMode.Loose,
connectionLineStyle,
snapToGrid: true,
snapGrid,
defaultZoom: 1.5,
})
onPaneReady((i) => {
i.fitView({
nodes: ['1'],
})
console.log('flow loaded:', i)
})
</script>
<template>
<VueFlow v-model="elements" :style="{ backgroundColor: bgColor }">
<template #edge-custom="props">
<TransitionEdge v-bind="props" />
</template>
</VueFlow>
</template>
@@ -0,0 +1,165 @@
<script setup>
import { TransitionPresets, useDebounceFn, useTransition, watchDebounced } from '@vueuse/core'
import { getBezierPath, useVueFlow } from '@braks/vue-flow'
import { computed, ref } from 'vue'
const props = defineProps({
id: {
type: String,
required: true,
},
source: {
type: String,
required: true,
},
target: {
type: String,
required: true,
},
sourceX: {
type: Number,
required: true,
},
sourceY: {
type: Number,
required: true,
},
targetX: {
type: Number,
required: true,
},
targetY: {
type: Number,
required: true,
},
sourcePosition: {
type: String,
required: true,
},
targetPosition: {
type: String,
required: true,
},
data: {
type: Object,
required: false,
},
markerEnd: {
type: String,
required: false,
},
style: {
type: Object,
required: false,
},
})
const curve = ref()
const dot = ref()
const transform = ref({ x: 0, y: 0 })
const showDot = ref(false)
const { onNodeDoubleClick, fitBounds, fitView } = useVueFlow()
const edgePath = computed(() =>
getBezierPath({
sourceX: props.sourceX,
sourceY: props.sourceY,
sourcePosition: props.sourcePosition,
targetX: props.targetX,
targetY: props.targetY,
targetPosition: props.targetPosition,
}),
)
const debouncedFitBounds = useDebounceFn(fitBounds, 1, { maxWait: 1 })
onNodeDoubleClick(({ node }) => {
const isSource = props.source === node.id
const isTarget = props.target === node.id
if (!showDot.value && (isSource || isTarget)) {
showDot.value = true
let totalLength = curve.value.getTotalLength()
const initialPos = ref(isSource ? 0 : totalLength)
let stopHandle
const output = useTransition(initialPos, {
duration: 4000,
transition: TransitionPresets.easeOutCubic,
onFinished: () => {
stopHandle?.()
showDot.value = false
fitView({
nodes: [isSource ? props.target : props.source],
duration: 500,
})
},
})
transform.value = curve.value.getPointAtLength(output.value)
debouncedFitBounds(
{
width: 100,
height: 200,
x: transform.value.x - 100,
y: transform.value.y - 100,
},
{ duration: 500 },
)
setTimeout(() => {
initialPos.value = isSource ? totalLength : 0
stopHandle = watchDebounced(
output,
(next) => {
if (!showDot.value) return
const nextLength = curve.value.getTotalLength()
if (totalLength !== nextLength) {
totalLength = nextLength
initialPos.value = isSource ? totalLength : 0
}
transform.value = curve.value.getPointAtLength(next)
debouncedFitBounds({
width: 100,
height: 200,
x: transform.value.x - 100,
y: transform.value.y - 100,
})
},
{ debounce: 1 },
)
}, 500)
}
})
</script>
<script>
export default {
inheritAttrs: false,
}
</script>
<template>
<path :id="id" ref="curve" :style="style" class="vue-flow__edge-path" :d="edgePath" :marker-end="markerEnd" />
<Transition name="fade">
<circle
v-if="showDot"
ref="dot"
r="5"
cy="0"
cx="0"
:transform="`translate(${transform.x}, ${transform.y})`"
style="fill: #fdd023"
/>
</Transition>
</template>
@@ -0,0 +1,3 @@
export { default as TransitionApp } from './App.vue?raw'
export { default as TransitionEdge } from './TransitionEdge.vue?raw'
export { default as TransitionCSS } from './style.css'
@@ -0,0 +1,9 @@
.fade-enter-active,
.fade-leave-active {
transition: opacity 300ms ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}