123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- <template>
- <canvas ref="canvasRef" :width="width" :height="height"></canvas>
- <!-- <div ref="canvasContainer" class="canvas-container"></div> -->
- </template>
- <script setup>
- import { nextTick, onMounted, ref, watch, watchEffect } from "vue";
- const props = defineProps({
- width: {
- type: [String,Number],
- default: "",
- },
- height: {
- type: [String,Number],
- default: "",
- },
- sourceData: {
- type: String,
- default: "",
- },
- });
- onMounted(() => {
- clearCanvas()
- nextTick(()=>{
- draw(props.sourceData);
- })
- });
- const transformRectanglesToArrayOfObjects = (
- rectanglesArray,
- widthMultiple,
- heightMultiple
- ) => {
- return rectanglesArray.map((rectanglePoints) => {
- // 提取矩形的左上角和右下角坐标
- const [x1, y1, x2, y2] = rectanglePoints;
- // 为当前矩形生成四个顶点的对象数组
- return [
- {
- x: x1 / widthMultiple,
- y: y1 / heightMultiple,
- }, // 左上角
- {
- x: x2 / widthMultiple,
- y: y1 / heightMultiple,
- }, // 右上角
- {
- x: x2 / widthMultiple,
- y: y2 / heightMultiple,
- }, // 右下角
- {
- x: x1 / widthMultiple,
- y: y2 / heightMultiple,
- }, // 左下角
- ];
- });
- };
- const canvasRef = ref(null);
- const draw = (value) => {
- // const value = props.sourceData;
- const obj = JSON.parse(value);
- if(!obj.color_ins) return
-
- const widthMultiple = obj.width=='undefined'?obj.width:4000 / props.width;
- const heightMultiple = obj.height=='undefined'?obj.height:3000 / props.height;
- const ctx = canvasRef.value.getContext("2d");
- const boxList = transformRectanglesToArrayOfObjects(
- obj.cor,
- widthMultiple,
- heightMultiple
- );
- boxList.forEach((ele, idx) => {
- ctx.beginPath(); // 开始新的路径
- ctx.moveTo(ele[0].x, ele[0].y); // 移动到第一个点
- for (var i = 1; i < ele.length; i++) {
- ctx.lineTo(ele[i].x, ele[i].y); // 绘制线段到下一个点
- }
- ctx.lineTo(ele[0].x, ele[0].y); // 闭合图形(回到起点)
- ctx.closePath(); // 可选,因为moveTo和lineTo已经形成了一个闭环
- // 设置线条样式
- ctx.strokeStyle = `rgb(${obj.color_ins[idx][0]},${obj.color_ins[idx][1]},${obj.color_ins[idx][2]})`;
- ctx.lineWidth = 2; // 线条宽度
- // 绘制图形
- ctx.stroke(); // 只绘制轮廓
- // 添加文字
- // 设置填充颜色
- ctx.fillStyle = `rgb(${obj.color_ins[idx][0]},${obj.color_ins[idx][1]},${obj.color_ins[idx][2]})`;
- // 设置字体样式
- ctx.font = "14px Arial";
- // 在画布上绘制填充文本
- ctx.fillText(obj.label[idx], ele[0].x, ele[0].y - 5);
- });
- };
- const clearCanvas = () => {
- const canvas = canvasRef.value;
- if (canvas.getContext) {
- const ctx = canvas.getContext("2d");
- // 使用clearRect方法清空整个画布
- // 第一个和第二个参数是矩形左上角的x和y坐标,第三个和第四个参数是矩形的宽度和高度
- // 这里我们设置为0, 0, canvas.width, canvas.height来清空整个画布
- ctx.clearRect(0, 0, props.width, props.height);
- }
- };
- watch(
- () => props.sourceData,
- (newValue, oldValue) => {
- clearCanvas()
- if(newValue){
- draw(newValue)
- }
- },
- );
- </script>
- <style lang="scss" scoped>
- .canvas-container {
- width: 100%;
- height: 100%;
- display: flex;
- justify-content: center;
- }
- canvas {
- position: absolute;
- }
- </style>
|