javascript - 随着时间的推移 trim HTML Canvas 中随机绘制线条的长度

标签 javascript canvas html5-canvas

我有下面的代码,它在 Canvas 上绘制一条连续线。该线路使用 slider 的实时输入,如此处所示 My test page ,这模拟了 3 轴呼吸描记器。 (编辑!您必须移动 slider 才能开始)

我想使线条保持设定的长度,删除尾部,但因为 slider 实时更新线条,我不确定如何最好地做到这一点,并且除非我记录时间,否则我无法简单地重新计算线条值(value)观发生变化。

我想我可以将所有点的列表存储在一个数组中,以组成我感兴趣的线的长度,然后每次都清除并重新绘制,但这似乎有很多重复。这将是一个由 100 到 1000 个点组成的数组。

我认为这是要走的路,只是在计算新点时将旧点推到底部,但有人有更好的解决方案吗?

    // Your code here!
var globalID;
var r1 = 80;
var ang1 = 0;
var ang2 = 0;
var ang3 = 0;
var flag = null;
var x2 = 0;
var y2 = 0

function drawpatten() {
    var canvas = document.getElementById("graphicsView");
    var ctx = canvas.getContext('2d');
    ctx.strokeStyle = "#0000FF";


    ctx.beginPath();
    // move the start if the line to the last know point caculated
    ctx.moveTo(x2 + 200, y2 + 200);

    // get current value of sliders and devide the value by 1000 (sliders are -100 to + 100 so this gives a value of 0.1 to 0.0001 for each ajustment of angle)
    S1 = document.getElementById("slider1");
    angm1 = S1.value / 1000;
    S2 = document.getElementById("slider2");
    angm2 = S2.value / 1000;
    S3 = document.getElementById("slider3");
    angm3 = S3.value / 1000;

    // we are only going to draw to screen for each 10 points we caculate, this allows us to have finer resolutions with out the over head of writing to screen so often

    for (i = 0; i < 10; i++) {


    //increments the angle and reset after 360 full circle
    ang1 = ang1 + angm1; 
    ang2 = ang2 + angm2;
    ang3 = ang3 + angm3;
        if (ang1 > 360) { ang1 = ang1 - 360 };
        if (ang2 > 360) { ang2 = ang2 - 360 };
        if (ang3 > 360) { ang3 = ang3 - 360 };

    // caculate the x y cordinates the points on each circle and of sets them 
    x = (Math.cos(ang1) * r1);
    y = (Math.sin(ang1) * r1);
    x1 = (Math.cos(ang2) * r1) + x;
    y1 = (Math.sin(ang2) * r1) + y;
    x2 = (Math.cos(ang3) * r1) + x1;
    y2 = (Math.sin(ang3) * r1) + y1;

    // draws the next sections of the line       
    ctx.lineTo(x2 + 200, y2 + 200);

    }

    // better way to do this but this flag just skips drawing the first time, this is becasue the first step will have a line from 0,0 to first cacualted point) 
    if (flag > 0) {
        ctx.stroke();
     }
    // set flag after first caculate and stroke
    flag = 1

    // recussivaly call function
    globalID = requestAnimationFrame(drawpatten);

}

最佳答案

一如既往,清除所有帧​​并重新绘制所有帧。

将所有点保留在一个数组中,迭代它们以在每一帧创建一个新路径,然后绘制它。

var r1 = 80;
var ang1 = 0;
var ang2 = 0;
var ang3 = 0;
var points = [];
// the anim loop
function anim()  {
  // push new points
  makepattern();
  // remove old points
  cleanoldies();
  // draw all
  draw();
  // do it again
  requestAnimationFrame(anim);
}
anim();

function cleanoldies() {
  var max_length = slider4.value * 2;
  while(points.length > max_length) {
    points.shift();
  }
}

function draw() {
  //Here we'll only draw
  var canvas = document.getElementById("graphicsView");
  var ctx = canvas.getContext('2d');
  ctx.strokeStyle = "#0000FF";
  // clear all
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  // a single Path
  ctx.beginPath();
  // points are stored in a flat array [x, y, x, y, x...]
  for (let i = 0; i < points.length; i += 2)
    ctx.lineTo(points[i], points[i + 1]);
  ctx.stroke();
}

function makepattern() {
  // push new points
  S1 = document.getElementById("slider1");
  angm1 = S1.value / 1000;
  S2 = document.getElementById("slider2");
  angm2 = S2.value / 1000;
  S3 = document.getElementById("slider3");
  angm3 = S3.value / 1000;

  for (i = 0; i < 10; i++) {
    ang1 = ang1 + angm1;
    ang2 = ang2 + angm2;
    ang3 = ang3 + angm3;
    if (ang1 > 360) {
      ang1 = ang1 - 360
    };
    if (ang2 > 360) {
      ang2 = ang2 - 360
    };
    if (ang3 > 360) {
      ang3 = ang3 - 360
    };

    var x = (Math.cos(ang1) * r1),
    y = (Math.sin(ang1) * r1),
    x1 = (Math.cos(ang2) * r1) + x,
    y1 = (Math.sin(ang2) * r1) + y,
    x2 = (Math.cos(ang3) * r1) + x1,
    y2 = (Math.sin(ang3) * r1) + y1;

    // store the next sections of the line       
    points.push(x2 + 200, y2 + 200);

  }
}
<input type="range" min="-100" max="100" value="10" id="slider1"><br>
<input type="range" min="-100" max="100" value="20" id="slider2"><br>
<input type="range" min="-100" max="100" value="10" id="slider3"><br>
<label>length<input type="range" min="0" max="10000" id="slider4" value="300"></label><br>

<canvas id="graphicsView" height="400" width="500"></canvas>

关于javascript - 随着时间的推移 trim HTML Canvas 中随机绘制线条的长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53110716/

相关文章:

node.js - 在具有多个套接字的 Canvas 上定位

javascript - Rails 和 jQuery 有时不工作

javascript - D3.js 堆栈布局过渡和对齐 |用 fiddle (重做)

javascript - Angular, restangular - 如果有更多当前的搜索调用,则中​​止搜索调用

Android - 填充折线图下方的颜色

javascript - 如果支持 Canvas ,如何使用 JavaScript 验证?

javascript - 当鼠标重新进入 Canvas 时平滑的相机转换 - Three.js

javascript - 使用javascript在html5 Canvas 上拖放图像

javascript - i++循环没有任何问题,i + 2无限循环并崩溃

php - 如何在页面加载后立即提交表单