工具栏-拖动 折叠
This commit is contained in:
parent
ee53207d31
commit
dbf6b665a8
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* @description: v-drag
|
||||
* @author zdg
|
||||
* @date 2023-06-07
|
||||
*/
|
||||
// 工具包
|
||||
const utils = {
|
||||
// Creates an event handler that can be used in Vue code
|
||||
// setup start moving end
|
||||
vueDragEvent: (el, action) => {
|
||||
el.dispatchEvent(new Event(`drag-${action}`))
|
||||
},
|
||||
dragStart: (el, target, axis, snap, e) => {
|
||||
// el.style.cursor = 'move'
|
||||
// el.onmousedown = function (e) {
|
||||
// const disX = e.clientX - el.offsetLeft
|
||||
// const disY = e.clientY - el.offsetTop
|
||||
// document.onmousemove = function (e) {
|
||||
// const left = e.clientX - disX
|
||||
// const top= e.clientY - disY
|
||||
// }
|
||||
// }
|
||||
},
|
||||
}
|
||||
// 首次向元素添加可拖动配置 | Add draggable configuration to element for the first time
|
||||
const mountedHook = (el, binding) => {
|
||||
console.log(el, binding)
|
||||
const value = binding.value || {}
|
||||
const handleSelector = value instanceof Object ? value.el : value // 获取元素
|
||||
const isOpen = value instanceof Object ? value.open || true : true // 是否开启拖拽 默认:开启
|
||||
const handleArray = [] // 拖拽元素
|
||||
if (!isOpen) return false // 没有开启不加载后面的代码
|
||||
let axis
|
||||
// Store all the DOM elements that will be used as handles.
|
||||
// They can be declared using a string with a CSS tag, class or id, or using Vue refs.
|
||||
if (!!handleSelector) {
|
||||
if (handleSelector instanceof HTMLElement) {
|
||||
handleArray.push(handleSelector);
|
||||
} else {
|
||||
// handleArray.push(document.querySelectorAll(handleSelector));
|
||||
document.querySelectorAll(handleSelector).forEach((child) => {
|
||||
handleArray.push(child);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (handleArray.length !== 0) {
|
||||
// Define move element and apply CSS class
|
||||
// el.classList.add(window.data.class.usesHandle);
|
||||
|
||||
handleArray.forEach((grabElement) => {
|
||||
// Apply CSS class to each grab element
|
||||
// grabElement.classList.add(window.data.class.handle);
|
||||
|
||||
// Add events to start drag with handle
|
||||
grabElement.onmousedown = (e) => utils.dragStart(grabElement, el, axis, e);
|
||||
grabElement.ontouchstart = (e) => utils.dragStart(grabElement, el, axis, e);
|
||||
});
|
||||
} else {
|
||||
// Add events to start drag without handle
|
||||
el.onmousedown = (e) => utils.dragStart(el, el, axis, e);
|
||||
el.ontouchstart = (e) => utils.dragStart(el, el, axis, e);
|
||||
}
|
||||
// Vue event on setup
|
||||
utils.vueDragEvent(el, 'setup')
|
||||
}
|
||||
export default {
|
||||
// Hooks for Vue3
|
||||
mounted(el, binding) {
|
||||
mountedHook(el, binding)
|
||||
},
|
||||
// Hooks for Vue2
|
||||
inserted(el, binding) {
|
||||
mountedHook(el, binding)
|
||||
},
|
||||
|
||||
update(el, binding){
|
||||
},
|
||||
updated(el, binding){
|
||||
|
||||
},
|
||||
}
|
|
@ -175,9 +175,9 @@ const eventHandles = (type, win) => {
|
|||
const setIgnore = (_, ignore) => {win.setIgnoreMouseEvents(ignore, {forward: true})}
|
||||
Remote.ipcMain.on('tool-sphere:set:ignore', setIgnore)
|
||||
// 关闭窗口
|
||||
Remote.ipcMain.once('tool-sphere:close', () => { win.destroy() })
|
||||
Remote.ipcMain.once('tool-sphere:close', () => { win&&win.destroy() })
|
||||
// 放大监听-测试
|
||||
Remote.ipcMain.once('maximize-window', () => {win.destroy()})
|
||||
Remote.ipcMain.once('maximize-window', () => {win&&win.destroy()})
|
||||
const on = {
|
||||
onClosed: () => {Remote.ipcMain.off('tool-sphere:set:ignore', setIgnore)}
|
||||
}
|
||||
|
@ -185,8 +185,7 @@ const eventHandles = (type, win) => {
|
|||
break}
|
||||
case 'open-PDF': {
|
||||
// 最小化窗口 minimize()
|
||||
Remote.ipcMain.once('open-PDF:minimize', () => {win.destroy()})
|
||||
win.webContents.openDevTools()
|
||||
Remote.ipcMain.once('open-PDF:minimize', () => {win&&win.destroy()})
|
||||
publicMethods() // 加载公共方法
|
||||
break}
|
||||
default:
|
||||
|
|
|
@ -2,11 +2,16 @@
|
|||
<div class="warp-all">
|
||||
<board-vue v-model="tabActive"></board-vue>
|
||||
<!-- 底部工具栏 -->
|
||||
<el-row id="test" class="tool-bottom-all" @mouseenter="mouseChange(0)" @mouseleave="mouseChange(1)">
|
||||
<el-col :span="3" class="flex justify-center items-center">
|
||||
<div class="c-logo"><el-image :src="logo" @click="tabChange('close')" /></div>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<div ref="tool" class="tool-bottom-all" :style="dataPos.style"
|
||||
@mouseenter="mouseChange(0)" @mouseleave="mouseChange(1)">
|
||||
<div @mousedown="e => dargHandle(e,'down')"
|
||||
@mousemove="e => dargHandle(e,'move')"
|
||||
@mouseup="e => dargHandle(e,'up')">
|
||||
<div class="c-logo" @click="logoHandle" title="拖动 | 折叠 | 展开">
|
||||
<el-image :src="logo" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="tool-btns" v-show="!isFold">
|
||||
<el-segmented class="c-btns" v-model="tabActive" :options="btnList" size="large" block
|
||||
@change="tabChange">
|
||||
<template #default="{item}">
|
||||
|
@ -16,22 +21,27 @@
|
|||
</div>
|
||||
</template>
|
||||
</el-segmented>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// 功能说明:electron 悬浮球
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { onMounted, ref, reactive } from 'vue'
|
||||
import logo from '@root/resources/icon.png' // logo
|
||||
import boardVue from './components/board.vue'
|
||||
import boardVue from './components/board.vue' // 画板
|
||||
import vDrag from '@/directive/drag'
|
||||
import { tryOnUnmounted } from '@vueuse/core'
|
||||
// const Remote = require('@electron/remote') // remote对象
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
|
||||
const tabActive = ref('select')
|
||||
const btnList = [
|
||||
const tool = ref()
|
||||
const tabActive = ref('select') // 工具栏当前选中项
|
||||
const isFold = ref(false) // 折叠工具栏
|
||||
const isDrag = ref(false) // 开始拖拽
|
||||
const dataPos = reactive({style:{}}) // 对象属性
|
||||
const btnList = [ // 工具栏按钮列表
|
||||
{ label: '选择', value: 'select', icon: 'icon-mouse' },
|
||||
{ label: '画笔', value: 'brush', icon: 'icon-huabi' },
|
||||
{ label: '板擦', value: 'eraser', icon: 'icon-xiangpica' },
|
||||
|
@ -39,7 +49,7 @@ const btnList = [
|
|||
{ label: '聚焦', value: 'focus', icon: 'icon-jujiao' },
|
||||
{ label: '更多', value: 'more', icon: 'icon-xiazai9' },
|
||||
]
|
||||
|
||||
let offsetX = 0, offsetY = 0, dragtime = 0
|
||||
// ==== 方法 ===
|
||||
const tabChange = (val) => { // 切换tab-change
|
||||
switch (val) {
|
||||
|
@ -60,6 +70,48 @@ const tabChange = (val) => { // 切换tab-change
|
|||
break
|
||||
}
|
||||
}
|
||||
const logoHandle = (e,t) => { // logo 点击-事件 折叠|展开
|
||||
if (Date.now() - dragtime < 200) {
|
||||
isFold.value = !isFold.value
|
||||
}
|
||||
console.log('click', isDrag.value)
|
||||
}
|
||||
const dargHandle = (e, type) => { // 拖拽处理
|
||||
e.preventDefault(); // 阻止默认的拖拽行为
|
||||
if (type == 'down') {
|
||||
dragtime = Date.now()
|
||||
return isDrag.value = true
|
||||
} else if (type == 'up') {
|
||||
return isDrag.value = false
|
||||
} else {
|
||||
if (!isDrag.value) return false
|
||||
if (!e.clientX&&!e.clientY){ // 最后一次松开坐标为0
|
||||
offsetX = 0
|
||||
offsetY = 0
|
||||
return false
|
||||
}
|
||||
if (!offsetX&&!offsetY) { // 第一次, 获取元素坐标
|
||||
setStyle()
|
||||
} else {
|
||||
const x = e.clientX - offsetX
|
||||
const y = e.clientY - offsetY
|
||||
setStyle(x, y)
|
||||
}
|
||||
offsetX = e.clientX
|
||||
offsetY = e.clientY
|
||||
}
|
||||
}
|
||||
const setStyle = (x, y) => { // 拖拽-设置值
|
||||
if (offsetX && offsetY) { // 有值
|
||||
const {left, top} = dataPos.style
|
||||
const ox = parseInt(left.replace('px',''))
|
||||
const oy = parseInt(top.replace('px',''))
|
||||
dataPos.style = {...dataPos.style, left: ox + x + 'px', top: oy + y + 'px'}
|
||||
} else { // 初始值
|
||||
const {left, top} = tool.value.getBoundingClientRect() // 获取元素位置
|
||||
dataPos.style = {bottom: 'unset', transform:'unset', left: left+'px', top: top+'px'}
|
||||
}
|
||||
}
|
||||
const mouseChange = (bool) => { // 鼠标移入工具栏 是否穿透
|
||||
let resBool = false
|
||||
if (tabActive.value == 'select') resBool = !!bool
|
||||
|
@ -73,7 +125,8 @@ const mouseChange = (bool) => { // 鼠标移入工具栏 是否穿透
|
|||
}
|
||||
// 底部工具栏
|
||||
.tool-bottom-all{
|
||||
width: 45vw;
|
||||
// width: 45vw;
|
||||
display: flex;
|
||||
position: fixed;
|
||||
bottom: 3em;
|
||||
left: 50%;
|
||||
|
@ -88,9 +141,11 @@ const mouseChange = (bool) => { // 鼠标移入工具栏 是否穿透
|
|||
height: 5rem;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0px 0px 8px rgb(0 0 0 / 40%);
|
||||
position: absolute;
|
||||
left: 0;
|
||||
// &:hover{
|
||||
// .el-image{transform: scale(1.1);}
|
||||
// }
|
||||
}
|
||||
.tool-btns{margin: 0 35px 0 7px;}
|
||||
.c-btn{
|
||||
i{font-size: 2rem;}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue