需求
单击按钮时开始绘画 ,当绘制结束后通过判断鼠标松开将开关置为false,再次绘画时再次单击按钮置为true,鼠标抬起false。
问题:
当切换页面的时候,单击绘画按钮,值悄悄的改变了false。导致绘画不了页面
解决方法:强制再次刷新本页面
watch: {
$route(to, from) {
window.location.reload(); //监测到路由发生跳转时刷新一次页面
},
},
mounted() {
if (location.href.indexOf("#reload") == -1) {
location.href = location.href + "#reload";
location.reload();
}
this.initPlayer();
this.initPaper();
this.loadRectanglesFromAPI();
},
<template>
<div id="wrap">
<div id="rtsp-wrap">
<div class="rtsp-video">
<!-- 视频 Canvas -->
<canvas class="video-canvas" ref="videoCanvas"></canvas>
</div>
<div class="drawing-canvas">
<!-- 绘制 Canvas -->
<canvas class="drawing-layer" ref="drawingCanvas"></canvas>
</div>
<div class="controls">
<!-- 控制按钮等 -->
<p>
<span>绘制区域</span>
<span><img @click="enableDrawing" src="../../assets/image/绘制区域@2x.png" alt="绘制区域"></span>
</p>
<p>
<span>清除区域</span>
<span><img @click="clearRectangle" src="../../assets/image/清除@2x.png" alt="清除区域"></span>
</p>
<p>
<span>灵敏度</span>
<span>
<el-slider class="skider" v-model="formData.Sensitivity" show-input></el-slider>
</span>
</p>
<p>
<span><button @click="saveRectangle">保存</button></span>
</p>
</div>
</div>
</div>
</template>
<script>
import isdownload from "./subpage/isDownload.vue";
import '../../utils/jsmpeg.min';
import paper from 'paper';
import axios from 'axios';
import SetArea from '@/api/system.js';
export default {
components: {
isdownload
},
data() {
return {
path: 'ws://127.0.0.1:8082/supersecret/device1',
player: null,
isPlaying: true,
isDrawingEnabled: false,
mouseTool: null,
rectangle: null,
canvasWidth: 600,
canvasHeight: 320,
formData: {
Coordinate_X: 0,
Coordinate_Y: 0,
Coordinate_Width: 0,
Coordinate_Height: 0,
Sensitivity: 50
}
};
},
watch: {
$route(to, from) {
window.location.reload(); //监测到路由发生跳转时刷新一次页面
},
},
mounted() {
if (location.href.indexOf("#reload") == -1) {
location.href = location.href + "#reload";
location.reload();
}
this.initPlayer();
this.initPaper();
this.loadRectanglesFromAPI();
},
methods: {
//初始化播放器
initPlayer() {
const canvas = this.$refs.videoCanvas;
if (!canvas) {
console.error('Canvas element not found');
return;
}
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
try {
this.player = new JSMpeg.Player(this.path, {
canvas: canvas,
autoplay: true,
loop: true,
contextOptions: { useWebGL: false }
});
} catch (error) {
console.error('Failed to initialize JSMpeg Player:', error);
}
},
//初始化画布
initPaper() {
console.log("initPaper" + this.isDrawingEnabled);
const canvas = this.$refs.drawingCanvas;
if (!canvas) {
console.error('Drawing canvas element not found');
return;
}
canvas.width = this.canvasWidth;
canvas.height = this.canvasHeight;
paper.setup(canvas);
this.mouseTool = new paper.Tool();
this.mouseTool.onMouseDown = this.onMouseDown;
this.mouseTool.onMouseDrag = this.onMouseDrag;
this.mouseTool.onMouseUp = this.onMouseUp;
},
//绘画按钮开关
enableDrawing() {
this.isDrawingEnabled = true;
console.log(this.isDrawingEnabled);
},
// 清除当前绘制的矩形框
clearRectangle() {
if (this.rectangle) {
this.rectangle.remove();
this.rectangle = null;
this.isDrawingEnabled = false
}
// 清除画布上的绘制内容
paper.project.clear();
// 清除formData中的矩形信息
this.formData.Coordinate_X = 0;
this.formData.Coordinate_Y = 0;
this.formData.Coordinate_Width = 0;
this.formData.Coordinate_Height = 0;
},
//保存并传参
async saveRectangle() {
if (!this.formData.Coordinate_Width || !this.formData.Coordinate_Height) {
this.$message({
type: "warning",
message: this.$t("请先绘制一个区域")
});
return;
}
//请求参数
const params = {
session: this.$cookies.get("session"),
params: { ...this.formData }
};
console.log(params);
try {
const data = await SetArea.SetRegionMonitor(params);
console.log(data);
if (data && data.result === 0) {
// Update local storage to match formData
const rectangles = JSON.parse(localStorage.getItem('rectangles') || '[]');
rectangles.push(this.formData);
localStorage.setItem('rectangles', JSON.stringify(rectangles));
this.$message({
type: "success",
message: this.$t("设置成功")
});
} else {
this.$message({
type: "error",
message: this.$t("设置失败,请重试")
});
}
} catch (error) {
console.error('保存区域监控失败:', error);
this.$message({
type: "error",
message: this.$t("保存区域监控失败,请重试")
});
}
},
//鼠标按下
onMouseDown(event) {
console.log(this.isDrawingEnabled, 'onMouseDown');
if (!this.isDrawingEnabled) return;
this.clearRectangle();
this.rectangle = new paper.Path.Rectangle({
from: event.point,
to: event.point,
fillColor: 'rgba(0, 0, 0, 0.5)',
selected: true
});
},
//鼠标拖动
onMouseDrag(event) {
console.log(33, this.isDrawingEnabled)
if (!this.isDrawingEnabled || !this.rectangle) return;
console.log(1111);
const x = Math.min(Math.max(event.point.x, 0), this.canvasWidth);
const y = Math.min(Math.max(event.point.y, 0), this.canvasHeight);
this.rectangle.segments[1].point.x = x;
this.rectangle.segments[2].point.set(x, y);
this.rectangle.segments[3].point.y = y;
},
//鼠标抬起
onMouseUp(event) {
console.log(33, this.isDrawingEnabled)
if (!this.isDrawingEnabled || !this.rectangle) return;
const x = Math.min(Math.max(event.point.x, 0), this.canvasWidth);
const y = Math.min(Math.max(event.point.y, 0), this.canvasHeight);
this.rectangle.segments[1].point.x = x;
this.rectangle.segments[2].point.set(x, y);
this.rectangle.segments[3].point.y = y;
this.saveRectangleToFormData();
this.rectangle = null;
this.isDrawingEnabled = false;
console.log(this.isDrawingEnabled, 'onMouseUp1');
},
// 保存矩形数据到表单数据
saveRectangleToFormData() {
if (this.rectangle) {
const bounds = this.rectangle.bounds;
this.formData.Coordinate_X = bounds.topLeft.x;
this.formData.Coordinate_Y = bounds.topLeft.y;
this.formData.Coordinate_Width = bounds.width;
this.formData.Coordinate_Height = bounds.height;
}
},
// 从接口加载矩形框数据
async loadRectanglesFromAPI() {
//请求参数
const params = {
session: this.$cookies.get("session"),
};
try {
const response = await SetArea.GetRegionMonitor(params);
if (response.data && response.data.result === 0) {
const params = response.data.params;
this.formData = {
Coordinate_X: params.Coordinate_X,
Coordinate_Y: params.Coordinate_Y,
Coordinate_Width: params.Coordinate_Width,
Coordinate_Height: params.Coordinate_Height,
Sensitivity: params.Sensitivity
};
this.drawRectangleFromFormData();
} else {
console.error('Failed to load rectangles:', response.data);
}
} catch (error) {
console.error('Error loading rectangles from API:', error);
}
},
// 根据 formData 绘制矩形
drawRectangleFromFormData() {
if (this.formData.Coordinate_Width && this.formData.Coordinate_Height) {
const rect = new paper.Path.Rectangle({
from: new paper.Point(this.formData.Coordinate_X, this.formData.Coordinate_Y),
to: new paper.Point(
this.formData.Coordinate_X + this.formData.Coordinate_Width,
this.formData.Coordinate_Y + this.formData.Coordinate_Height
),
fillColor: 'rgba(0, 0, 0, 0.5)',
selected: true
});
this.rectangle = rect;
}
}
},
//销毁播放器
beforeDestroy() {
if (this.player) {
this.player.destroy();
}
}
};
</script>
<style scoped>
#wrap {
height: 100%;
}
#rtsp-wrap {
position: relative;
overflow: hidden;
white-space: nowrap;
}
#rtsp-wrap .rtsp-video {
float: left;
}
#rtsp-wrap .video-canvas {
width: 600px;
height: 320px;
}
#rtsp-wrap .drawing-canvas {
z-index: 222;
position: absolute;
top: 0;
left: 0;
pointer-events: auto;
}
#rtsp-wrap .drawing-layer {
width: 600px;
height: 320px;
}
#rtsp-wrap .controls {
float: left;
margin-top: 20px;
}
#rtsp-wrap .controls p img {
width: 60px;
height: 30px;
}
#rtsp-wrap .controls p img:hover {
cursor: pointer;
}
#rtsp-wrap .controls p {
margin-top: 20px;
display: flex;
align-items: center;
}
#rtsp-wrap .controls p span {
display: inline-flex;
margin-left: 20px;
}
#rtsp-wrap .controls p span button {
width: 80px;
height: 30px;
background-color: #0078D7;
color: #fff;
border-radius: 8px;
border: none;
font-size: 14px;
margin-left: 30px;
}
#rtsp-wrap .controls p span button:hover {
cursor: pointer;
}
.skider {
width: 400px;
height: 20px;
margin-top: -13px;
margin-left: 20px;
}
</style>
完整页面
原因是因为
lQLPKdFU7HDsA_vNA6zNBQyw_A6Fc2ewTPEGkefSXGnKAA_1292_940.png
每次的**new paper.tool()重新创建了新的实例,所以重新会到这个页面的时候,paper不知道你想调用那个实例.
解决方法就是在beforeDestory中销毁掉,保证一个实例.或者使用单例模式
beforeDestroy() {
if (this.player) {
this.player.destroy();
}
// 清除 paper 相关的设置 这里解决了new paper.Tool() 重新创建了新实例 重新回到这个页面的时候,paper 不知道你想调用哪个实例
if (this.mouseTool) {
this.mouseTool.remove(); // 清除工具
}
}