关于可以移动的标尺vue3-sketch-ruler

本文介绍了如何使用Vue3的SketchRule库实现一个可定制的标尺组件,它能随着屏幕滚动和缩放动态调整,适用于需要在网页上绘制或测量的场景,如设计工具或数据可视化应用。
摘要由CSDN通过智能技术生成
<template>
    <div class="bi-container" @click="handleMouseDown"> 
        <SketchRule 
        :key="scale"
        :thick="rulerConfig.thick"  
        :scale="scale"  
        :lines="rulerConfig.lines" 
        :startX="rulerConfig.startX" 
        :startY="rulerConfig.startY" 
        :palette="rulerConfig.palette"
        :ratio="rulerConfig.ratio"
        :shadow="rulerConfig.shadow"
        :width="centerWidth" 
        :height="centerHeight"/>
        <div class="screen" ref="$screenRef" @wheel="handleWheel" @scroll="handleScroll"
        @mousedown.stop="dragMousedown" @mouseup="dragMouseup" @mousemove="dragMousemove">
            <div class="screen-container" ref="$screenContainerRef">
                <div class="canvas" ref="$canvasRef" :style="canvasStyle">
                    <div class="wrapper" :style="wrapperStyle">
                        <div class="container" id="containercanvas" :style="containerStyle"> 
                        你的内容
                        </div>
                    </div>
                </div>
            </div>
        </div> 
    </div>
</template>
<script setup>
import { ref, computed, nextTick, inject, watchEffect, getCurrentInstance } from 'vue';

import SketchRule from 'vue3-sketch-ruler'
import 'vue3-sketch-ruler/lib/style.css' 

const { proxy } = getCurrentInstance()
const serveUrl = inject('$globalConfig') 
const rulerConfig = ref({
    scale:1, //初始化标尺的缩放 通过设置值,改变刻度尺的大小
    thick: 20,  //标尺的厚度 
    lines:{h:[],v:[]}, //不能直接写{}不然删除有问题
    startX:-20,
    startY:-20,  
    ratio:1,//标尺缩放必须设置不然标尺的不正常
    shadow:{
        x: 0,
        y: 0,
        width: 0,
        height: 0
    },
    palette:{
        bgColor: '#f9f9fa',//整体个尺子背景颜色 
        shortfgColor: '#1d2129',//尺子短刻度颜色
        fontColor: '#1d2129', //尺子刻度字体颜色  
        lineColor: '#EB5648', //标准线的颜色  
    }
})

//自定义画布宽和高
const width =1920
const height =1080 

// 292两边宽度,20尺寸宽度 64上面头部高度60和22是预留上下左右空白
const fixWidth = 292+292+20+60
const fixHeight = 64+20+22

const scale = ref(1)

// 设置标尺大小
const initScale = ()=>{
    let w = window.innerWidth-fixWidth
    let h = window.innerHeight-fixHeight
    let ratew = w/width
    let rateh = h/height   
    scale.value = Math.min(ratew, rateh)
}
initScale()

// 标尺所在中间尺寸宽604=292+292+20
const centerWidth = computed(()=>{
    return window.innerWidth-604
}) 
 
// 标尺所在中间尺寸高85=64+20+1
const centerHeight = computed(()=>{
    return window.innerHeight-85
})

// 设置画布大小
const canvasStyle = computed(()=>{ 
    return {
        width:width+'px', 
        height:height+'px', 
        transform:`scale(${scale.value})`,
    }
})

// 设置真实画布大小
const wrapperStyle = computed(()=>{
    return {
        width:width+'px', 
        height:height+'px', 
    }
})

// 设置内容区域
const containerStyle = computed(()=>{   
    return {
        transform: `scale(1, 1)`, 
        width: width+'px', 
        height: height+'px',
        backgroundColor: backgroundColor,
        backgroundImage: backgroundImage,
        backgroundPosition: '0% 0%',
        backgroundSize: '100% 100%',
        backgroundRepeat: 'initial', 
        backgroundAttachment: 'initial',
        backgroundOrigin: 'initial',
        backgroundClip: 'initial'
    }
})

// 将最大外面的div设置滚动上下各50%以让画布居中
const $screenContainerRef = ref(null)
const $screenRef = ref(null)
const $canvasRef = ref(null)
const initData = ()=>{ 
    let screenContaineDom = $screenContainerRef.value.getBoundingClientRect()
    $screenRef.value.scrollLeft = (screenContaineDom.width/2)-rulerConfig.value.thick-20;
    $screenRef.value.scrollTop = (screenContaineDom.height/2)-rulerConfig.value.thick-20;
    handleScroll()
}
nextTick(()=>{ 
    initData()
})

// 滚动鼠标标尺也跟着滚动
const handleScroll = ()=>{
    const screenRect = $screenRef.value.getBoundingClientRect()
    const canvasRect = $canvasRef.value.getBoundingClientRect() 
    let startX = (screenRect.left+rulerConfig.value.thick-canvasRect.left)/scale.value;  
    let startY = (screenRect.top+rulerConfig.value.thick-canvasRect.top)/scale.value; 
    rulerConfig.value.startX = startX >> 0
    rulerConfig.value.startY = startY >> 0 
}

// 缩放(目前缩放之后,尺寸的值与画布稍有偏差需要精确)
const handleWheel = (e)=>{ 
    if (e.ctrlKey || e.metaKey) {
        e.preventDefault(); 
        scale.value = parseFloat(scale.value - e.deltaY / 1000);  
    }
}

// 获取移动步数
const stepScale = computed(()=>{ 
    let stepscale = Number((100 / (100 * scale.value)))
    return stepscale
})

// 点击空白移动鼠标进行尺子移动
//按下鼠标
const dragSlide = ref(false)
const dragMousedown = (e) => { 
    if(e.type == 'mousedown'){
        e.preventDefault();
        dragSlide.value = true;
        window.stardragEvent = e
        window.startSlideX = $screenRef.value.scrollLeft
        window.startSlideY = $screenRef.value.scrollTop
    }
    
}
//鼠标抬起
const dragMouseup = (e) => { 
    dragSlide.value = false;
}

//鼠标移动
const dragMousemove = (e) => {
    //拖拽画布
    if (dragSlide.value) {
        let x = e.clientX - window.stardragEvent.clientX
        let y = e.clientY - window.stardragEvent.clientY
        $screenRef.value.scrollLeft = window.startSlideX - x
        $screenRef.value.scrollTop = window.startSlideY - y
    }
}
  
</script>
    
<style lang="scss" scoped> 
.bi-container{
    position: relative;
    width: 100%;
    height: 100%; 
    overflow: hidden;
    .screen{
        position: absolute;
        width:100%;
        height: 100%;
        top: 200;
        left: 0;  
        overflow-y: auto;
        overflow-x: hidden;
    }
    .screen-container{
        width: 5000px;
        height: 3000px;
        position: relative;
        background: url(/assets/images/doit.png) repeat;;
    }
    .canvas{
        position: absolute;
        left: 50%;
        top: 50%; 
        transform-origin: 0 0;    
    } 
    .container{
        background-color: #fff;
        transform-origin: 0 0;
        position: relative;
    }
}
</style>

参考链接
https://github.com/kakajun/vue3-sketch-ruler

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值