129 lines
2.7 KiB
Vue
129 lines
2.7 KiB
Vue
<script setup lang="ts">
|
|
import { onMounted, onUpdated, ref } from "vue";
|
|
import { ONE_MM } from "../const";
|
|
import { useStore } from "../store";
|
|
import { storeToRefs } from "pinia";
|
|
|
|
const store = useStore();
|
|
const {
|
|
imageBackgroundColor,
|
|
|
|
vMargin,
|
|
vRotation,
|
|
|
|
hMargin,
|
|
hMargin2,
|
|
|
|
marginEnable,
|
|
marginColor,
|
|
marginLeftMargin,
|
|
|
|
imageHeight,
|
|
imageWidth,
|
|
} = storeToRefs(store);
|
|
|
|
const ctx = ref<null | CanvasRenderingContext2D>(null);
|
|
|
|
const clearCanvas = () => {
|
|
|
|
if (ctx.value) {
|
|
ctx.value.shadowColor
|
|
ctx.value.fillStyle = imageBackgroundColor.value;
|
|
ctx.value.fillRect(0, 0, imageWidth.value * ONE_MM, imageHeight.value * ONE_MM);
|
|
ctx.value.beginPath();
|
|
}
|
|
};
|
|
|
|
const render = () => {
|
|
if (vMargin.value < 1 || hMargin.value < 1 || hMargin2.value < 1) {
|
|
return
|
|
}
|
|
if (imageWidth.value < 1 || imageHeight.value < 1) {
|
|
return
|
|
}
|
|
|
|
clearCanvas();
|
|
|
|
var hMargins = [hMargin.value, hMargin2.value];
|
|
|
|
var imageHeightPx = imageHeight.value * ONE_MM;
|
|
var imageWidthPx = imageWidth.value * ONE_MM;
|
|
var vMarginPx = vMargin.value * ONE_MM;
|
|
var rotationDelta = imageHeightPx / Math.tan(vRotation.value / 180 * Math.PI);
|
|
|
|
if (ctx.value) {
|
|
ctx.value.strokeStyle = "#000000";
|
|
ctx.value.beginPath();
|
|
ctx.value.stroke();
|
|
|
|
var x = 0;
|
|
var y = 0;
|
|
|
|
let i = 0;
|
|
while (y < imageHeightPx) {
|
|
y += hMargins[i % 2] * ONE_MM;
|
|
ctx.value.moveTo(0, y);
|
|
ctx.value.lineTo(imageWidthPx, y);
|
|
ctx.value.stroke();
|
|
i++;
|
|
}
|
|
|
|
x = 0;
|
|
y = 0;
|
|
i = 0;
|
|
while (x - rotationDelta < imageWidthPx) {
|
|
x = i * vMarginPx;
|
|
var x0 = x;
|
|
var y0 = 0;
|
|
var x1 = x - rotationDelta;
|
|
var y1 = imageHeightPx;
|
|
ctx.value.moveTo(x0, y0);
|
|
ctx.value.lineTo(x1, y1);
|
|
ctx.value.stroke();
|
|
i++;
|
|
}
|
|
|
|
|
|
x = marginLeftMargin.value * ONE_MM;
|
|
if (marginEnable.value) {
|
|
ctx.value.strokeStyle = marginColor.value;
|
|
ctx.value.lineWidth = 2;
|
|
ctx.value.beginPath();
|
|
ctx.value.moveTo(x, 0);
|
|
ctx.value.lineTo(x, imageHeightPx);
|
|
ctx.value.stroke();
|
|
}
|
|
}
|
|
};
|
|
|
|
onMounted(() => {
|
|
const canvas = document.getElementById("canvas") as HTMLCanvasElement;
|
|
|
|
if (canvas) {
|
|
ctx.value = canvas.getContext("2d");
|
|
}
|
|
|
|
render();
|
|
});
|
|
|
|
onUpdated(() => {
|
|
render();
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<canvas id="canvas" :width="imageWidth * ONE_MM" :height="imageHeight * ONE_MM" />
|
|
<!-- Костыль, чтобы обновлялся стейт, неужели vue не может красиво это делать -->
|
|
<div style="display: none;">
|
|
{{ store }}
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
canvas {
|
|
border: 1px solid black;
|
|
margin: 20px;
|
|
height: calc(100vh - 40px);
|
|
}
|
|
</style>
|