Skip to content

Commit

Permalink
fix(free-dom): improve auto-sizing and mask handling
Browse files Browse the repository at this point in the history
  • Loading branch information
SepVeneto committed Jan 2, 2025
1 parent 298659d commit c3bedb9
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 42 deletions.
8 changes: 3 additions & 5 deletions packages/core/__tests__/freedom.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ describe('auto correct', () => {
test('when scene mounted', async () => {
const INIT = { x: -20, y: 100, w: 20, h: 20 }
const pos = ref(INIT)
const wrap = mount(h(
mount(h(
FreeScene,
{
style: 'width: 100px; height: 100px;',
Expand All @@ -139,9 +139,7 @@ describe('auto correct', () => {
}, () => h('span', 'test')),
))
await nextTick()
hackCss(wrap)
await nextTick()
await nextTick()

expect(pos.value.x).toBe(0)
expect(pos.value.y).toBe(80)
})
Expand All @@ -164,7 +162,7 @@ describe('auto correct', () => {
data: () => ({ nodeList: [] }),
})
await nextTick()
hackCss(wrapper)
// hackCss(wrapper)
await wrapper.setData({
nodeList,
})
Expand Down
42 changes: 15 additions & 27 deletions packages/core/src/components/freeDomWrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,20 @@ import type { ExtractPropTypes, PropType } from 'vue-demi'
import {
computed,
defineComponent,
onMounted,
provide,
reactive,
ref,
shallowRef,
toRefs,
watch,
watchEffect,
} from 'vue-demi'
import { SceneToken, createRender } from '../util'
import markLine from './markLine'
import { useDefaultSlot, useEventBus, useMask, useOperateHistory } from '../hooks'
import { freeDomProps } from './freeDom'
import type { INode, IPos } from '../types'
import { useElementBounding } from '@vueuse/core'
import debugInit from 'debug'

const debug = debugInit('freeDom:wrap')

export const freeDomWrapProps = {
diff: {
Expand Down Expand Up @@ -73,36 +70,25 @@ export const FreeDomWrap = defineComponent({
const eventBus = useEventBus()
const nodes = ref<INode[]>([])
const history = useOperateHistory(nodes)
const width = ref<number | undefined>(props.width)
const height = ref<number | undefined>(props.height)
const width = ref<number | undefined>()
const height = ref<number | undefined>()
const rectRef = shallowRef<HTMLElement>()
const wrapRect = useElementBounding(rectRef)
const wrapStyle = computed(() => ({
height: height.value + 'px',
width: width.value + 'px',
}))

watchEffect(() => {
width.value = props.width
height.value = props.height
onMounted(() => {
if (rectRef.value) {
const { width: w, height: h } = window.getComputedStyle(rectRef.value)
width.value = props.width || Math.round(parseFloat(w)) || 0
height.value = props.height || Math.round(parseFloat(h)) || 0
}
})

watch([
wrapRect.width,
wrapRect.height,
() => nodes.value.length,
], ([w, h]) => {
debug('update size')

if (!w || !h) return

width.value = w
height.value = h
emit('update:width', w)
emit('update:height', h)

watch([width, height, () => nodes.value.length], () => {
runCorrect()
}, { immediate: true })
})

const selectedNodes = computed(() => nodes.value.filter(node => node.node.selected))

Expand Down Expand Up @@ -269,14 +255,16 @@ export const FreeDomWrap = defineComponent({
const main = createRender(
'section',
{
ref: 'rectRef',
class: 'vv-free-dom--scene',
style: this.wrapStyle,
},
)(slotList)
const wrap = (comp: any) => createRender(
'section',
{},
{
ref: 'rectRef',
style: 'overflow: hidden;',
},
{},
{
onMousedown: this.mask.handleMousedown,
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/hooks/use-mask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ export function useMask(
// evt.offsetX, evt.offsetY计算的是基于target计算的
// 因此当容器内存在子元素或缩放方向会经过mask时offset不能代表在容器内的相对位置
function offsetFormat(evt: MouseEvent) {
const offsetX = evt.clientX - rect.x.value
const offsetY = evt.clientY - rect.y.value
const offsetX = (evt.clientX - rect.x.value) / props.transformScale
const offsetY = (evt.clientY - rect.y.value) / props.transformScale
return {
x: offsetX,
y: offsetY,
Expand Down
5 changes: 2 additions & 3 deletions packages/core/src/style/free-dom.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
.vv-free-dom--draggable__disabled {
cursor: initial;
}
.vv-free-dom--draggable__mask.vv-free-dom--draggable__selected::after,
.vv-free-dom--draggable__mask.vv-free-dom--draggable__selected:focus-visible {
.vv-free-dom--draggable__mask.vv-free-dom--draggable__selected::after {
content: '';
z-index: 1;
display: block;
Expand All @@ -23,7 +22,7 @@
top: 0;
left: 0;
background: var(--vv-free-dom--selected);
outline: 2px dashed var(--vv-free-dom--theme);
border: 2px dashed var(--vv-free-dom--theme);
&::selection {
background-color: transparent !important;
}
Expand Down
8 changes: 5 additions & 3 deletions packages/examples/free-dom/auto-expand/index.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<template>
<div>
<div>width: <input type="number" v-model="width"></div>
<div>height: <input type="number" v-model="height"></div>
<div style="position: absolute;">
<div>width: <input type="number" v-model="width"></div>
<div>height: <input type="number" v-model="height"></div>
</div>
<FreeScene
auto-expand
:auto-expand="10"
v-model:width="width"
v-model:height="height"
>
Expand Down
6 changes: 4 additions & 2 deletions packages/examples/free-dom/transform-scale/combine.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<FreeScene
:transform-scale="0.5"
style="transform: scale(0.5)"
:transform-scale="1.5"
style="transform: scale(1.5); transform-origin: top left; overflow: hidden;"
>
<FreeDom v-model="pos1">
测试文本1
Expand All @@ -18,6 +18,8 @@ import { ref } from 'vue'
const pos1 = ref({
x: Math.random() * 100,
y: Math.random() * 100,
w: 200,
h: 200
})
const pos2 = ref({
x: Math.random() * 100 + 100,
Expand Down

0 comments on commit c3bedb9

Please sign in to comment.