数通互联化工云平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

193 lines
4.9 KiB

<template>
<canvas
class="canvas-thumbnail"
:width="canvasConfig.thumbnailWrapWidth"
:height="canvasConfig.thumbnailWrapHeight"
ref="thumbnailRef"
v-show="showThumbnail"
@mousedown="onMoveStart"
@mousemove="onMove"
@mouseup="onMoveEnd"
@mouseleave="onMoveEnd"
>
</canvas>
</template>
<script lang="ts">
import { useEditorStore } from '@/stores/editor';
import {
defineComponent,
ref,
computed,
reactive,
watch,
onMounted,
nextTick,
onBeforeUnmount
} from 'vue';
export default defineComponent({
name: 'CanvasThumbnail',
setup(props, context) {
const editorStore = useEditorStore();
const thumbnailRef = ref();
const canvasConfig = computed(() => editorStore.canvasConfig);
let isLock = false;
const viewBox = computed({
get: () => ({ viewWidth: editorStore.viewWidth, viewHeight: editorStore.viewHeight }),
set: (v) => {
editorStore.setViewBox(v);
}
});
const unscale = computed(() => {
if (editorStore.scale > 100) {
return 1 / editorStore.thumbnailSize;
} else {
return 10;
}
});
const getViewBox = () => {
nextTick(() => {
let dashboardDom = document.getElementById('dashboard');
if (!dashboardDom) {
return;
}
viewBox.value.viewWidth = dashboardDom.offsetWidth;
viewBox.value.viewHeight = dashboardDom.offsetHeight;
drawThumbnail();
});
};
const drawThumbnail = () => {
if (!isLock) {
isLock = true;
nextTick(() => {
let startLen = 6;
const ctx = thumbnailRef.value.getContext('2d');
ctx.clearRect(
0,
0,
canvasConfig.value.thumbnailWrapWidth,
canvasConfig.value.thumbnailWrapHeight
);
ctx.beginPath();
ctx.fillStyle = 'rgba(26, 103, 255, 0.5)';
ctx.rect(
startLen,
startLen,
canvasConfig.value.thumbnailWidth,
canvasConfig.value.thumbnailHeight
);
ctx.fill();
ctx.beginPath();
ctx.strokeStyle = '#1a67ff';
ctx.rect(
Math.round(editorStore.scrollLeft * editorStore.thumbnailSize),
Math.round(editorStore.scrollTop * editorStore.thumbnailSize),
viewBox.value.viewWidth * editorStore.thumbnailSize,
viewBox.value.viewHeight * editorStore.thumbnailSize
);
ctx.stroke();
isLock = false;
});
}
};
watch(
() => editorStore.scale,
() => {
drawThumbnail();
}
);
watch(
() => editorStore.screenWidth,
() => {
drawThumbnail();
}
);
watch(
() => editorStore.screenHeight,
() => {
drawThumbnail();
}
);
watch(
() => editorStore.scrollLeft,
() => {
drawThumbnail();
}
);
watch(
() => editorStore.scrollTop,
() => {
drawThumbnail();
}
);
watch(
() => editorStore.screenHeight,
() => {
drawThumbnail();
}
);
watch(
() => editorStore.viewHeight,
() => {
drawThumbnail();
}
);
watch(
() => editorStore.viewWidth,
() => {
drawThumbnail();
}
);
onMounted(() => {
window.addEventListener('resize', getViewBox);
getViewBox();
});
onBeforeUnmount(() => {
window.removeEventListener('resize', getViewBox);
});
let moveInfo = {
startX: 0,
startY: 0,
isMove: false
};
return {
canvasConfig,
thumbnailRef,
showThumbnail: computed(() => editorStore.isThumbnail),
onMoveStart: (e: MouseEvent) => {
moveInfo.isMove = true;
moveInfo.startX = e.clientX;
moveInfo.startY = e.clientY;
},
onMove: (e: MouseEvent) => {
if (moveInfo.isMove) {
let left = editorStore.scrollLeft + (e.clientX - moveInfo.startX) * unscale.value;
let top = editorStore.scrollTop + (e.clientY - moveInfo.startY) * unscale.value;
// console.log('thumbnail', left, top);
editorStore.setScroll({ left, top });
moveInfo.startX = e.clientX;
moveInfo.startY = e.clientY;
}
},
onMoveEnd: () => {
moveInfo.isMove = false;
}
};
}
});
</script>
<style lang="scss" scoped>
.canvas-thumbnail {
background-color: var(--thumbnail-wrap-bg);
position: fixed;
right: 310px;
bottom: 48px;
z-index: 9;
cursor: move;
}
</style>