【发布时间】:2020-12-31 10:23:10
【问题描述】:
我有一个带有画布的 html 页面,该画布连接到网络服务器并接收一些需要在画布上绘制的点数组。
连接建立后,我得到一个形状作为主模板。这将在整个会话中保持不变。然后我得到了一些其他的形状。
我的问题是我不知道如何只绘制一次主要形状(模板),然后轻松地在画布上绘制和清理其他形状。这是我的申请流程:
1 - 绘制主模板形状 2 - 当一个新形状到达时,在画布上绘制它(不清除已经绘制的模板) 3- 当新形状出现时,绘制旧形状(不是模板)并绘制新形状
我只需要绘制第一个模板一次,因为我得到了大量的点并且我对它们进行了耗时的计算。我不想每次出现新形状时都重绘这个模板...
这是实现这一目标的方法吗?它还应该考虑页面大小调整等...
我已经准备了下面的最小示例来模拟我需要什么......
// Main template shape
let template = [{x: 10, y:10}, {x: 120, y:10}, {x: 110, y:110}, {x: 50, y:175}];
// Some shapes
let shapes = [
[{x: 20, y:20}, {x: 110, y:20}, {x: 100, y:100}, {x: 60, y:145}],
[{x: 30, y:30}, {x: 100, y:30}, {x: 90, y:90}, {x: 70, y:135}],
[{x: 40, y:40}, {x: 90, y:40}, {x: 80, y:70}, {x: 80, y:125}],
];
let shapeIndex = 0; // To cycle through shapes array
let canvas = {}; // Canvas to draw on
let ctx = {}; // Context of the Canvas
// Init elements
$( document ).ready(function() {
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
});
// Draw the template
function drawTemplate() {
ctx.save();
ctx.beginPath();
ctx.strokeStyle = 'yellow';
ctx.fillStyle = 'red';
for(let point of template) {
ctx.lineTo(point.x, point.y);
}
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.restore();
}
// Draw one shape from the shapes array
function drawShape() {
ctx.save();
ctx.strokeStyle = 'white';
ctx.fillStyle = 'rgba(127,127,127,0.5)';
ctx.beginPath();
let points = getShapeFromArray();
for(point of points) {
ctx.lineTo(point.x, point.y);
}
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.restore();
}
// Draw one shape from the shapes array
function drawShape() {
// How to clear the perviously drawn shape, if any?
ctx.save();
ctx.strokeStyle = 'white';
ctx.fillStyle = 'rgba(127,127,127,0.5)';
ctx.beginPath();
let points = getShapeFromArray();
for(point of points) {
ctx.lineTo(point.x, point.y);
}
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.restore();
}
// Helper to get next element in the array
function getShapeFromArray() {
if(shapeIndex == shapes.length) {
shapeIndex = 0;
}
return shapes[shapeIndex++];
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<title>Hahaha!</title>
</head>
<body>
<canvas id="myCanvas" width="200" height="200" style="border:1px solid #000000;"></canvas>
<p style="text-align: left">
<button onclick="drawTemplate()">draw template</button>
<button onclick="drawShape()">draw shape</button>
</p>
</body>
</html>
【问题讨论】:
-
不是一个很好的解决方案,但如果它只是一个图形表示,只需在此下方放置一个新的 Canvas,并在下面的画布上绘制模板,以便您可以使用
clearRect或任何您需要的东西在上面一个 -
每次有变化时清除画布并只重绘可见的部分
-
@Blindman67 Clearing 将返回白色(默认背景颜色)画布。也许我没明白你的意思?有没有特别的清除功能?
-
没有特殊的清除功能,从调用
ctx.clearRect(0,0,width,height)后清除(透明)的画布重绘所有可见的内容 -
如果重绘很麻烦,您应该考虑使用库来为您完成:fabricjs.com 听起来不错,这样您就可以显示、隐藏、删除和添加对象和形状更少的头痛......把你的时间集中在你真正想做的事情上
标签: javascript html canvas html5-canvas