在画布上绘制平行线

问题描述

我正在尝试在画布上绘制平行线。其中一条线是固定的。用户输入两条线之间的距离,因此第二条线就这样定位了。我是JavaScript新手。请帮助我如何通过用户输入更改第二行的位置。

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
console.log('myCanvas');

//Fixed Line
ctx.beginPath();
ctx.moveTo(50,200);
ctx.lineTo(300,200);
ctx.strokeStyle='white';
ctx.stroke();

//moving line
ctx.beginPath();
ctx.moveTo(50,250);
ctx.lineTo(300,250);
ctx.strokeStyle='white';
ctx.stroke();

解决方法

平行线

绘制与现有线平行的线。

  • 获取从行首到行尾的向量。
  • 使用该向量获取线的长度
  • 将偏移距离除以线的长度即可得到偏移比例
  • 按偏移比例缩放线向量
  • 将缩放的矢量添加到线条的末端并绘制。

请参见示例功能drawLine

获取输入

要从输入元素中获取值,请使用元素value属性。

要获取值更改时的值,请使用元素addEventListener函数添加事件侦听器。 。不要将监听器直接分配给elements事件属性,例如,避免做myElement.oninput = ()=> {/* ... code */};

有各种各样的输入事件。您可以根据需要使用一种或多种。在这种情况下,有两个事件changeinput。参见示例。

  • change在用户提交对值的更改时触发
  • input在输入值发生任何更改时触发

始终为输入值分配一个有意义的值,如果空无意义,请不要将其留空。

示例

const ctx = myCanvas.getContext("2d");
const myLine = {
    from: {x: 50,y: 50},to: {x: 150,y: 200},style: {strokeStyle: "#000",lineWidth: 2}
};
distanceElement.addEventListener("input",inputEvent);
var lineOffset = distanceElement.value;
drawLines();
function inputEvent(e) {
    lineOffset = e.target.value;
    drawLines();
}
function drawLines() {
    ctx.clearRect(0,ctx.canvas.width,ctx.canvas.height);
    drawLine(myLine);
    lineOffset !== 0 && drawLine(myLine,lineOffset);
}
function drawLine(line,offset = 0) {
    var [ox,oy] = [0,0];  
    Object.assign(ctx,line.style);
    if (offset) {
        const [dx,dy] = [line.from.x - line.to.x,line.from.y - line.to.y];
        const scale = offset / (dx * dx + dy * dy) ** 0.5;
        [ox,oy] = [-dy * scale,dx * scale];
    }
    ctx.beginPath();
    ctx.lineTo(ox + line.from.x,oy + line.from.y);
    ctx.lineTo(ox + line.to.x,oy + line.to.y);
    ctx.stroke();
}
        
input {display:block;}
<label for="distanceElement">Line offset distance:</label>
<input id="distanceElement" placeholder="Enter Distance" type="number" value="0">
<canvas id="myCanvas" width="250" height="250"></canvas>

,

编辑:

虽然此答案对某些人有用,但this答案在更多情况下效果更好(特别是它支持对角线),并且对发生的情况有更详尽的解释。


旧答案:

每次输入输入时,都可以使用oninput事件来运行。这是一个示例:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

var input = document.getElementById("distance");
input.oninput = ()=>{
  // clear
  ctx.clearRect(0,c.width,c.height);
  // draw fixed line
  ctx.beginPath();
  ctx.moveTo(50,0);
  ctx.lineTo(50,200);
  ctx.strokeStyle='black';
  ctx.stroke();
  let value = parseFloat(input.value);
  // draw moved line
  ctx.beginPath();
  ctx.moveTo(50+value,0);
  ctx.lineTo(50+value,250);
  ctx.strokeStyle='black';
  ctx.stroke();
}
input {
  display:block;
}
<canvas id="myCanvas" width="150" height="150"></canvas>
<input id="distance" placeholder="Enter Distance Here (in px)" type="number">

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...