fix: edge anchor
This commit is contained in:
@@ -25,11 +25,13 @@ const sourceHandleStyleB: CSSProperties = { ...targetHandleStyle, bottom: '10px'
|
||||
const onConnect = (params: Connection | Edge) => console.log('handle onConnect', params)
|
||||
</script>
|
||||
<template>
|
||||
<Handle type="target" :position="Position.Left" :style="targetHandleStyle" :on-connect="onConnect" />
|
||||
<div>
|
||||
Custom Color Picker Node: <strong>{{ data.color }}</strong>
|
||||
<div class="revue-flow__node-color-selector">
|
||||
<Handle type="target" :position="Position.Left" :style="targetHandleStyle" :on-connect="onConnect" />
|
||||
<div>
|
||||
Custom Color Picker Node: <strong>{{ data.color }}</strong>
|
||||
</div>
|
||||
<input class="nodrag" type="color" :value="data.color" @input="props.data.onChange" />
|
||||
<Handle id="a" type="source" :position="Position.Right" :style="sourceHandleStyleA" />
|
||||
<Handle id="b" type="source" :position="Position.Right" :style="sourceHandleStyleB" />
|
||||
</div>
|
||||
<input class="nodrag" type="color" :value="data.color" @input="props.data.onChange" />
|
||||
<Handle id="a" type="source" :position="Position.Right" :style="sourceHandleStyleA" />
|
||||
<Handle id="b" type="source" :position="Position.Right" :style="sourceHandleStyleB" />
|
||||
</template>
|
||||
|
||||
@@ -47,9 +47,7 @@ onMounted(() => {
|
||||
if (isEdge(e) || e.id !== '2') {
|
||||
return e
|
||||
}
|
||||
|
||||
const color = (event.target as HTMLInputElement).value
|
||||
|
||||
bgColor.value = color
|
||||
|
||||
return {
|
||||
|
||||
@@ -87,7 +87,9 @@ const onEdgeUpdaterTargetMouseDown = (event: MouseEvent) => {
|
||||
|
||||
const updating = ref<boolean>(false)
|
||||
const onEdgeUpdaterMouseEnter = () => (updating.value = true)
|
||||
|
||||
const onEdgeUpdaterMouseOut = () => (updating.value = false)
|
||||
|
||||
const isVisible = ({ sourceX, sourceY, targetX, targetY }: ReturnType<typeof getEdgePositions>) => {
|
||||
return store.onlyRenderVisibleElements
|
||||
? isEdgeVisible({
|
||||
@@ -99,14 +101,14 @@ const isVisible = ({ sourceX, sourceY, targetX, targetY }: ReturnType<typeof get
|
||||
})
|
||||
: true
|
||||
}
|
||||
|
||||
const edgePos = computed(() =>
|
||||
getEdgePositions(props.nodes.sourceNode, sourceHandle, sourcePosition, props.nodes.targetNode, targetHandle, targetPosition),
|
||||
)
|
||||
const visible = computed(() => !props.edge.isHidden && isVisible(edgePos.value))
|
||||
</script>
|
||||
<template>
|
||||
<g
|
||||
v-if="visible"
|
||||
v-if="!props.edge.isHidden && isVisible(edgePos)"
|
||||
:class="[
|
||||
'revue-flow__edge',
|
||||
`revue-flow__edge-${props.type.name || 'default'}`,
|
||||
@@ -189,9 +191,9 @@ const visible = computed(() => !props.edge.isHidden && isVisible(edgePos.value))
|
||||
</g>
|
||||
<g @mousedown="onEdgeUpdaterTargetMouseDown" @mouseenter="onEdgeUpdaterMouseEnter" @mouseout="onEdgeUpdaterMouseOut">
|
||||
<EdgeAnchor
|
||||
:position="sourcePosition"
|
||||
:center-x="edgePos.sourceX"
|
||||
:center-y="edgePos.sourceY"
|
||||
:position="targetPosition"
|
||||
:center-x="edgePos.targetX"
|
||||
:center-y="edgePos.targetY"
|
||||
:radius="props.edgeUpdaterRadius"
|
||||
/>
|
||||
</g>
|
||||
|
||||
@@ -29,16 +29,12 @@ const selectedNodes = computed(() =>
|
||||
: [],
|
||||
)
|
||||
|
||||
const style = computed(() => ({
|
||||
transform: `translate(${store.transform[0]}px,${store.transform[1]}px) scale(${store.transform[2]})`,
|
||||
}))
|
||||
|
||||
const innerStyle = computed(() => ({
|
||||
const innerStyle = {
|
||||
width: `${store.selectedNodesBbox.width}px`,
|
||||
height: `${store.selectedNodesBbox.height}px`,
|
||||
top: `${store.selectedNodesBbox.y}px`,
|
||||
left: `${store.selectedNodesBbox.x}px`,
|
||||
}))
|
||||
}
|
||||
|
||||
const onStart: DraggableEventListener = ({ event }) => {
|
||||
hooks.selectionDragStart.trigger({ event, nodes: selectedNodes.value })
|
||||
@@ -73,7 +69,12 @@ const onContextMenu = (event: MouseEvent) => {
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div class="revue-flow__nodesselection" :style="style">
|
||||
<div
|
||||
class="revue-flow__nodesselection"
|
||||
:style="{
|
||||
transform: `translate(${store.transform[0]}px,${store.transform[1]}px) scale(${store.transform[2]})`,
|
||||
}"
|
||||
>
|
||||
<Draggable
|
||||
:scale="store.transform[2]"
|
||||
:grid="store.snapToGrid ? store.snapGrid : undefined"
|
||||
|
||||
@@ -8,21 +8,15 @@ const el = templateRef('user-selection', null)
|
||||
|
||||
const onMouseDown = (event: MouseEvent) => {
|
||||
const mousePos = getMousePosition(event)
|
||||
if (!mousePos) {
|
||||
return
|
||||
}
|
||||
if (!mousePos) return
|
||||
|
||||
store.setUserSelection(mousePos)
|
||||
}
|
||||
|
||||
const onMouseMove = (event: MouseEvent) => {
|
||||
if (!store.selectionActive) {
|
||||
return
|
||||
}
|
||||
if (!store.selectionActive) return
|
||||
const mousePos = getMousePosition(event)
|
||||
if (!mousePos) {
|
||||
return
|
||||
}
|
||||
if (!mousePos) return
|
||||
|
||||
store.updateUserSelection(mousePos)
|
||||
}
|
||||
@@ -41,17 +35,15 @@ useEventListener(el, 'mousemove', onMouseMove)
|
||||
useEventListener(el, 'click', onMouseUp)
|
||||
useEventListener(el, 'mouseup', onMouseUp)
|
||||
useEventListener(el, 'mouseleave', onMouseLeave)
|
||||
|
||||
const userSelectionRect = computed(() => store.userSelectionRect)
|
||||
</script>
|
||||
<template>
|
||||
<div ref="user-selection" class="revue-flow__selectionpane">
|
||||
<SelectionRect
|
||||
v-if="userSelectionRect.draw"
|
||||
:width="userSelectionRect.width"
|
||||
:height="userSelectionRect.height"
|
||||
:x="userSelectionRect.x"
|
||||
:y="userSelectionRect.y"
|
||||
v-if="store.userSelectionRect.draw"
|
||||
:width="store.userSelectionRect.width"
|
||||
:height="store.userSelectionRect.height"
|
||||
:x="store.userSelectionRect.x"
|
||||
:y="store.userSelectionRect.y"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -3,9 +3,10 @@ import { pointer, select } from 'd3-selection'
|
||||
import { Ref } from 'vue'
|
||||
import { get } from '@vueuse/core'
|
||||
import { FlowTransform, PanOnScrollMode, Transform, UseZoom, UseZoomOptions } from '~/types'
|
||||
import { clamp } from '~/utils'
|
||||
import { clamp, onLoadGetElements, onLoadProject, onLoadToObject } from '~/utils'
|
||||
import useKeyPress from '~/composables/useKeyPress'
|
||||
import { Hooks, Store } from '~/context'
|
||||
import { useZoomPanHelper } from '~/composables/index'
|
||||
|
||||
const viewChanged = (prevTransform: FlowTransform, eventTransform: ZoomTransform): boolean =>
|
||||
prevTransform.x !== eventTransform.x || prevTransform.y !== eventTransform.y || prevTransform.zoom !== eventTransform.k
|
||||
@@ -59,6 +60,18 @@ export default function (el: Ref<HTMLDivElement>, options: UseZoomOptions): UseZ
|
||||
const updatedTransform = zoomIdentity.translate(clampedX, clampedY).scale(clampedZoom)
|
||||
d3z.transform(d3s, updatedTransform)
|
||||
store.initD3Zoom({ d3Zoom: d3z, d3Selection: d3s, d3ZoomHandler })
|
||||
const { zoomIn, zoomOut, zoomTo, transform: setTransform, fitView } = useZoomPanHelper(store)
|
||||
hooks.load.trigger({
|
||||
fitView: (params = { padding: 0.1 }) => fitView(params),
|
||||
zoomIn,
|
||||
zoomOut,
|
||||
zoomTo,
|
||||
setTransform,
|
||||
project: onLoadProject(store),
|
||||
getElements: onLoadGetElements(store),
|
||||
toObject: onLoadToObject(store),
|
||||
})
|
||||
|
||||
const applyZoomHandlers = () => {
|
||||
d3z.on('start', (event: D3ZoomEvent<HTMLDivElement, any>) => {
|
||||
if (viewChanged(prevTransform.value, event.transform)) {
|
||||
|
||||
@@ -5,8 +5,7 @@ import { Store } from '~/context'
|
||||
|
||||
const DEFAULT_PADDING = 0.1
|
||||
|
||||
export default function (): UseZoomPanHelper {
|
||||
const store = inject(Store)!
|
||||
export default function (store = inject(Store)!): UseZoomPanHelper {
|
||||
return {
|
||||
zoomIn: () => store.d3Selection && store.d3Zoom?.scaleBy(store.d3Selection, 1.2),
|
||||
zoomOut: () => store.d3Selection && store.d3Zoom?.scaleBy(store.d3Selection, 1 / 1.2),
|
||||
|
||||
@@ -37,21 +37,15 @@ const hooks = inject(Hooks)!
|
||||
const zoomPaneEl = templateRef<HTMLDivElement>('zoom-pane', null)
|
||||
const { transform } = useZoom(zoomPaneEl, props)
|
||||
const { width, height } = useElementBounding(zoomPaneEl)
|
||||
watch(width, (val) => (store.dimensions.width = val), { flush: 'post' })
|
||||
watch(height, (val) => (store.dimensions.height = val), { flush: 'post' })
|
||||
watch(transform, (val) => (store.transform = val), { flush: 'post' })
|
||||
watch(width, (val) => (store.dimensions.width = val))
|
||||
watch(height, (val) => (store.dimensions.height = val))
|
||||
watch(transform, (val) => (store.transform = val))
|
||||
|
||||
const { zoomIn, zoomOut, zoomTo, transform: setTransform, fitView } = useZoomPanHelper()
|
||||
hooks.load.trigger({
|
||||
fitView: (params = { padding: 0.1 }) => fitView(params),
|
||||
zoomIn,
|
||||
zoomOut,
|
||||
zoomTo,
|
||||
setTransform,
|
||||
project: onLoadProject(store),
|
||||
getElements: onLoadGetElements(store),
|
||||
toObject: onLoadToObject(store),
|
||||
})
|
||||
store.transform = transform.value
|
||||
store.dimensions = {
|
||||
width: width.value,
|
||||
height: height.value,
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div ref="zoom-pane" class="revue-flow__renderer revue-flow__zoompane">
|
||||
|
||||
15
src/shims-tsx.d.ts
vendored
15
src/shims-tsx.d.ts
vendored
@@ -1,15 +0,0 @@
|
||||
import Vue, { VNode } from 'vue'
|
||||
|
||||
declare global {
|
||||
namespace JSX {
|
||||
// tslint:disable no-empty-interface
|
||||
interface Element extends VNode {}
|
||||
|
||||
// @ts-ignore
|
||||
interface ElementClass extends Vue {}
|
||||
|
||||
interface IntrinsicAttributes {
|
||||
[prop: string]: any
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user