javascript - 画布绘制一次,翻译一次,一次没有错误
问题描述
我已经采取了几乎所有可能的对策来防止我的程序在图表上绘制两个点而不是一个点。我希望显示中间的点,而不是左上角的点。在我看来,点在左上角被绘制一次,与坐标和所有内容匹配,但随后它用该translate
方法绘制了第二个点。当然,这只是对屏幕上发生的事情的猜测。问题发生在draw()
函数、init()
函数或anim()
函数的某个地方——我无法确定问题出在哪里。
let graph = document.getElementById('chart');
let c = graph.getContext('2d');
graph.height = 754;
graph.width = 754;
function algebra() {
xVertex = 2 * 10;
yVertex = 5 * 10;
let radius = 3;
let node = [];
function Node(xVertex, yVertex, radius) {
this.r = radius;
this.xV = xVertex;
this.yV = yVertex;
this.draw = function() {
c.beginPath();
c.arc(this.xV, this.yV, this.r, 0, Math.PI * 2, false);
c.fillStyle = "red";
c.fill();
c.translate(377, 377);
c.stroke();
c.closePath();
};
this.update = function() {
this.draw();
};
};
function init() {
node.push(new Node(xVertex, yVertex, radius));
anim();
};
function anim() {
requestAnimationFrame(anim);
for (let i = 0; i < node.length; i++) {
node[i].update(node);
};
c.clearRect(0, 0, graph.width, graph.height);
console.log(node);
};
init();
};
#graph {
left: 100px;
background-color: grey;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title> Proof of concept </title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="graph">
<canvas id="chart"></canvas>
<div id="y-axis"></div>
<div id="x-axis"></div>
</div>
<div id="button" onclick="algebra()">
<div id="btext">Calculate</div>
</div>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
解决方案
我想我发现了你的错误:
1)调用anim()
时必须先清除画布,然后重绘所有点。
2) 在画布上绘制完所有点后调用下一个动画帧
主要问题:
3)您正在对绘制的每个点(以及一个大点(377、377))进行画布原点的平移。由于原点在每次迭代或绘制点时都在变化,因此被擦除的画布部分也在移动。你得到的两点是第一次和第二次迭代,其他的都在屏幕外。
您需要做的是将画布原点仅翻译一次到它的中间,紧接着:
let c = graph.getContext('2d');
graph.height = 754;
graph.width = 754;
//Translate the origin to the canvas' center (do this only once)
c.translate(graph.width/2, graph.height/2);
如果画布原点已移动到中心,那么您还必须将画布从 -width/2 擦除到 width/2 和 height/2 到 height/2。为此,您必须使用:
c.clearRect(-graph.width/2, -graph.height/2, graph.width, graph.height);
只是为了好玩,我在节点数组中添加了三个点,并在每次迭代中为每个坐标添加了一个介于 -1 和 1 之间的随机数。这会产生类似布朗运动的模拟。
let graph = document.getElementById('chart');
let c = graph.getContext('2d');
graph.height = 754;
graph.width = 754;
//Translate the origin to the canvas' center (do this only once)
c.translate(graph.width/2, graph.height/2);
function algebra() {
//Changed to 0 to plot at center
xVertex = 0;
yVertex = 0;
let radius = 3;
let node = [];
function Node(xVertex, yVertex, radius) {
this.r = radius;
this.xV = xVertex;
this.yV = yVertex;
this.draw = function() {
c.beginPath();
c.arc(this.xV, this.yV, this.r, 0, Math.PI * 2, false);
c.fillStyle = "red";
c.fill();
c.stroke();
c.closePath();
};
this.update = function() {
//this will generate random movement in x and y.
this.xV += Math.random()*2-1;
this.yV += Math.random()*2-1;
this.draw();
};
};
function init() {
node.push(new Node(xVertex, yVertex, radius));
node.push(new Node(xVertex, yVertex, radius));
node.push(new Node(xVertex, yVertex, radius));
node.push(new Node(xVertex, yVertex, radius));
anim();
};
function anim() {
//First clear the canvas then redraw
c.clearRect(-graph.width/2, -graph.height/2, graph.width, graph.height);
for (let i = 0; i < node.length; i++) {
node[i].update(node);
};
//After all are drawn, call the next Animation Frame
requestAnimationFrame(anim);
};
init();
};
#graph {
left: 100px;
background-color: grey;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title> Proof of concept </title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="graph">
<canvas id="chart"></canvas>
<div id="y-axis"></div>
<div id="x-axis"></div>
</div>
<div id="button" onclick="algebra()">
<div id="btext">Calculate</div>
</div>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
推荐阅读
- azure-devops - 添加或删除父链接时逻辑应用触发器未触发
- symfony - PhpStorm 不能自动完成存储库文件上的 Symfony Doctrine 字段名称?
- sass - Travis CI 可以编译 Sass 吗?
- c# - 如何在 C# 控制台应用程序中忽略“Enter”键?
- javascript - 导航栏没有隐藏在使用 javascript 的滚动上
- r - 通过使用管道复制和替换变量来扩展 R 中的数据框
- selenium - Java 中的 Chrome Webdriver 分离选项
- html - 如何通过迭代不同的 id 在 django 中获取发布数据
- javascript - 获取 javascript 变量值并将其存储到 django 变量中,反之亦然
- html - 使用角度存储多个单选按钮值