<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