Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/canvas/common/src/constant.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const NODE_UID = 'data-uid'
export const NODE_TAG = 'data-tag'
export const NODE_LOOP = 'loop-id'
export const NODE_INACTIVE_UID = 'data-ia-uid'

export const DESIGN_MODE = {
DESIGN: 'design', // 设计态
Expand Down
7 changes: 6 additions & 1 deletion packages/canvas/container/src/CanvasContainer.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
<template>
<canvas-action
:hoverState="hoverState"
:inactiveHoverState="inactiveHoverState"
:selectState="selectState"
:lineState="lineState"
:windowGetClickEventTarget="target"
:resize="canvasState.type === 'absolute'"
@select-slot="selectSlot"
@setting="settingModel"
></canvas-action>
<canvas-router-jumper :hoverState="hoverState" :inactiveHoverState="inactiveHoverState"></canvas-router-jumper>
<canvas-divider :selectState="selectState"></canvas-divider>
<canvas-resize-border :iframe="iframe"></canvas-resize-border>
<canvas-resize>
Expand Down Expand Up @@ -36,6 +38,7 @@ import { NODE_UID, NODE_LOOP, DESIGN_MODE } from '../../common'
import { registerHostkeyEvent, removeHostkeyEvent } from './keyboard'
import CanvasMenu, { closeMenu, openMenu } from './components/CanvasMenu.vue'
import CanvasAction from './components/CanvasAction.vue'
import CanvasRouterJumper from './components/CanvasRouterJumper.vue'
import CanvasResize from './components/CanvasResize.vue'
import CanvasDivider from './components/CanvasDivider.vue'
import CanvasResizeBorder from './components/CanvasResizeBorder.vue'
Expand All @@ -45,6 +48,7 @@ import {
dragMove,
dragState,
hoverState,
inactiveHoverState,
selectState,
lineState,
removeNodeById,
Expand All @@ -60,7 +64,7 @@ import {
} from './container'

export default {
components: { CanvasAction, CanvasResize, CanvasMenu, CanvasDivider, CanvasResizeBorder },
components: { CanvasAction, CanvasResize, CanvasMenu, CanvasDivider, CanvasResizeBorder, CanvasRouterJumper },
props: {
controller: Object,
canvasSrc: String,
Expand Down Expand Up @@ -247,6 +251,7 @@ export default {
iframe,
dragState,
hoverState,
inactiveHoverState,
selectState,
lineState,
removeNodeById,
Expand Down
25 changes: 25 additions & 0 deletions packages/canvas/container/src/components/CanvasAction.vue
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@
</div>
<div v-show="hoverState.configure?.isContainer" class="corner-mark-bottom-right">拖放元素到容器内</div>
</div>
<div v-show="inactiveHoverState.height && inactiveHoverState.width" class="canvas-rect inactive-hover">
<div class="corner-mark-left">
{{ inactiveHoverState.componentName }}
</div>
</div>
<div v-show="lineState.height && lineState.width" class="canvas-rect line">
<div :class="['hover-line', lineState.position, { forbidden: lineState.forbidden }]">
<div v-if="lineState.position === 'in' && hoverState.configure" class="choose-slots"></div>
Expand Down Expand Up @@ -165,6 +170,10 @@ export default {
type: Object,
default: () => ({})
},
inactiveHoverState: {
type: Object,
default: () => ({})
},
selectState: {
type: Object,
default: () => ({})
Expand Down Expand Up @@ -535,6 +544,22 @@ export default {
font-size: 12px;
}
}
&.inactive-hover {
border-style: dashed;
top: v-bind("inactiveHoverState.top + 'px'");
left: v-bind("inactiveHoverState.left + 'px'");
height: v-bind("inactiveHoverState.height + 'px'");
width: v-bind("inactiveHoverState.width + 'px'");
border-color: var(--te-common-border-hover);

.corner-mark-left {
height: 14px;
top: -14px;
padding-left: 0;
font-size: 12px;
color: var(--te-common-text-weaken);
}
}
&.line {
border-color: transparent;
top: v-bind("lineState.top + 'px'");
Expand Down
108 changes: 108 additions & 0 deletions packages/canvas/container/src/components/CanvasRouterJumper.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<template>
<div
v-if="state.showRouterJumper"
:class="{
'jumper-wrapper': true,
disabled: !state.targetPageId
}"
:title="state.targetPageId ? '路由跳转编辑' : '未绑定路由跳转页面'"
@click="routerPageJump"
>
<div class="jumper">
<svg-icon name="jump"></svg-icon>
</div>
</div>
</template>

<script>
import { reactive, watch } from 'vue'
import { usePage } from '@opentiny/tiny-engine-meta-register'

const LEGAL_JUMPER_COMPONENT = ['RouterLink']

export default {
props: {
hoverState: {
type: Object,
default: () => ({})
},
inactiveHoverState: {
type: Object,
default: () => ({})
}
},
setup(props) {
const switchPage = usePage().switchPageWithConfirm
const state = reactive({
showRouterJumper: false,
targetPageId: null,
left: 0,
top: 0
})

const routerPageJump = () => {
if (state.targetPageId) {
switchPage(state.targetPageId)
}
}
Comment thread
rhlin marked this conversation as resolved.

watch(
[() => props.hoverState, () => props.inactiveHoverState],
([hoverState, inactiveHoverState]) => {
const usedHoverState = [hoverState, inactiveHoverState].find(({ componentName }) =>
LEGAL_JUMPER_COMPONENT.includes(componentName)
)

if (!usedHoverState) {
state.showRouterJumper = false
return
}
const { width, left, top, element } = usedHoverState
state.showRouterJumper = true
state.left = `${left + width}px`
state.top = `${top}px`
state.targetPageId = element.getAttribute('data-router-target-page-id') || null
},
{ deep: true }
)

return {
state,
routerPageJump
}
}
}
</script>

<style lang="less" scoped>
.jumper-wrapper {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
border-radius: 50%;
background-color: var(--te-common-bg-default);
cursor: pointer;
z-index: 3;
transform: translateX(-80%) translateY(-20%);
top: v-bind('state.top');
left: v-bind('state.left');
border: 1px solid var(--te-common-border-hover);
&.disabled {
opacity: 0.3;
}
&:not(.disabled):hover {
border-color: var(--te-common-bg-primary-checked);
background-color: var(--te-common-bg-primary-checked);
.jumper {
color: var(--te-common-text-dark-inverse);
}
}
.jumper {
width: 16px;
height: 16px;
}
}
</style>
57 changes: 55 additions & 2 deletions packages/canvas/container/src/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import {
copyObject,
NODE_UID,
NODE_TAG,
NODE_LOOP
NODE_LOOP,
NODE_INACTIVE_UID
} from '../../common'
import { useCanvas, useLayout, useResource, useTranslate, useMaterial } from '@opentiny/tiny-engine-meta-register'
import { isVsCodeEnv } from '@opentiny/tiny-engine-common/js/environments'
Expand Down Expand Up @@ -119,13 +120,18 @@ export const hoverState = reactive({
...initialRectState
})

export const inactiveHoverState = reactive({
...initialRectState
})

// 拖拽时的位置状态
export const lineState = reactive({
...initialLineState
})

export const clearHover = () => {
Object.assign(hoverState, initialRectState, { slot: null })
Object.assign(inactiveHoverState, initialRectState, { slot: null })
}

export const clearSelect = () => {
Expand Down Expand Up @@ -233,6 +239,28 @@ export const getElement = (element) => {
return undefined
}

export const getInactiveElement = (element) => {
if (
!element ||
element.nodeType !== 1 ||
// 如果当前元素是body或者html,需要排除
element === element.ownerDocument.body ||
element === element.ownerDocument.documentElement ||
// 如果当前元素是RouterView, 则有可能是激活元素处于非激活元素里面,需要排除
element.getAttribute(NODE_TAG) === 'RouterView'
) {
return undefined
}

if (element.getAttribute(NODE_INACTIVE_UID)) {
return element
} else if (element.parentElement) {
return getInactiveElement(element.parentElement)
}

return undefined
}

const getRect = (element) => {
if (element === getDocument().body) {
const { innerWidth: width, innerHeight: height } = getWindow()
Expand Down Expand Up @@ -542,11 +570,36 @@ const setHoverRect = (element, data) => {
height,
top,
left,
element,
componentName
})
return undefined
}

const setInactiveHoverRect = (element) => {
if (!element) {
Object.assign(inactiveHoverState, initialRectState, { slot: null })
return
}

const componentName = element.getAttribute(NODE_TAG)
const id = element.getAttribute(NODE_INACTIVE_UID)
const configure = getConfigure(componentName)
const rect = getRect(element)
const { left, height, top, width } = rect

inactiveHoverState.configure = configure
// 设置元素hover状态
Object.assign(inactiveHoverState, {
id,
width,
height,
top,
left,
element,
componentName
})
}
let moveUpdateTimer = null

// 绝对布局
Expand Down Expand Up @@ -628,7 +681,7 @@ export const dragMove = (event, isHover) => {
if (isHover) {
lineState.position = ''
setHoverRect(getElement(event.target), null)

setInactiveHoverRect(getInactiveElement(event.target))
return
}

Expand Down
1 change: 1 addition & 0 deletions packages/canvas/render/src/builtin/CanvasRouterLink.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<template>
<span
v-bind="$attrs"
:data-router-target-page-id="to?.name"
:class="{
[activeClass]: active,
[exactActiveClass]: exactActive
Expand Down
9 changes: 7 additions & 2 deletions packages/canvas/render/src/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@

import { defineComponent, h, inject, provide, Ref } from 'vue'

import { NODE_UID as DESIGN_UIDKEY, NODE_TAG as DESIGN_TAGKEY, NODE_LOOP as DESIGN_LOOPID } from '../../common'
import {
NODE_UID as DESIGN_UIDKEY,
NODE_TAG as DESIGN_TAGKEY,
NODE_LOOP as DESIGN_LOOPID,
NODE_INACTIVE_UID
} from '../../common'
import { getDesignMode, DESIGN_MODE } from './canvas-function'
import { parseCondition, parseData, parseLoopArgs } from './data-function'
import { blockSlotDataMap, getComponent, generateCollection, Mapper, configure } from './material-function'
Expand Down Expand Up @@ -88,7 +93,7 @@ const getBindProps = (schema, scope, context, pageContext) => {
const bindProps = {
...parseData(schema.props, scope, context),
...(cssScopeId ? { [cssScopeId]: '' } : {}),
...(active ? { [DESIGN_UIDKEY]: id } : {}),
...(active ? { [DESIGN_UIDKEY]: id } : { [NODE_INACTIVE_UID]: id }),
[DESIGN_TAGKEY]: componentName
}

Expand Down
18 changes: 18 additions & 0 deletions packages/design-core/assets/jump.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.