gpt4 book ai didi

javascript - Canvas lineTo 中的 lineWidth 变化更平滑

转载 作者:行者123 更新时间:2023-12-03 11:43:10 26 4
gpt4 key购买 nike

所以我试图在 HTML5 Canvas 中创建一个绘图工具,其中笔划的粗细随着鼠标移动的速度越快而增加,并且随着鼠标移动的速度越慢而减少。我正在使用 ctx.lineTo() 但在我第一次尝试时注意到,如果我移动得太快,厚度的变化会被记录为明显的平方增量(而不是重量的平滑增加)

first try

所以我将 ctx.lineJoin 和 ctx.lineCap 更改为“round”,效果好一点了

current state

但这仍然没有我想要的那么顺利。我正在拍摄这样的东西

what i'd like

任何有关如何使体重变化更平滑的建议都会很棒!这是一个工作演示:http://jsfiddle.net/0fhag522/1/

这里是我的“点”对象(笔)和绘图函数的预览:

    var dot = {         
start: false,
weight: 1,
open: function(x,y){
ctx.lineJoin = "round";
ctx.lineCap = "round";
ctx.beginPath();
ctx.moveTo(x,y);
},
connect: function(x,y){
ctx.lineWidth = this.weight;
ctx.lineTo(x,y);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(x,y);
},
close: function(){
ctx.closePath();
}
}

function draw(){
if(down){
if(!dot.start){
dot.close();
prevx = mx; prevy = my;
dot.open(mx,my);
dot.start=true;
}
else {
var dx = (prevx>mx) ? prevx-mx : mx-prevx;
var dy = (prevy>my) ? prevy-my : my-prevy;
dot.weight = Math.abs(dx-dy)/2;
dot.connect( mx,my );
prevx = mx; prevy = my;
}
}
}

最佳答案

这是一个简单的函数,用于创建带有圆形线帽生长线:

/* 
* this function returns a Path2D object
* the path represents a growing line between two given points
*/
function createGrowingLine (x1, y1, x2, y2, startWidth, endWidth) {
// calculate direction vector of point 1 and 2
const directionVectorX = x2 - x1,
directionVectorY = y2 - y1;
// calculate angle of perpendicular vector
const perpendicularVectorAngle = Math.atan2(directionVectorY, directionVectorX) + Math.PI/2;
// construct shape
const path = new Path2D();
path.arc(x1, y1, startWidth/2, perpendicularVectorAngle, perpendicularVectorAngle + Math.PI);
path.arc(x2, y2, endWidth/2, perpendicularVectorAngle + Math.PI, perpendicularVectorAngle);
path.closePath();
return path;
}

const ctx = myCanvas.getContext('2d');
// create a growing line between P1(10, 10) and P2(250, 100)
// with a start line width of 10 and an end line width of 50
let line1 = createGrowingLine(10, 10, 250, 100, 10, 50);
ctx.fillStyle = 'green';
// draw growing line
ctx.fill(line1);
<canvas width="300" height="150" id="myCanvas"></canvas>

说明:函数createGrowingLine通过以下方式在两个给定点之间构造一个形状:

  1. 计算两点的方向向量
  2. 计算垂直向量的弧度 Angular
  3. 创建一条从计算 Angular 到以起点为中心和半径的计算 Angular + 180 度的半圆路径
  4. 从计算的 Angular + 180 度到以终点的中心和半径计算的 Angular 创建另一条半圆路径
  5. 通过连接第一个圆的起点和第二个圆的终点来闭合路径

如果您不想使用圆 Angular 线帽,请使用以下函数:

/* 
* this function returns a Path2D object
* the path represents a growing line between two given points
*/
function createGrowingLine (x1, y1, x2, y2, startWidth, endWidth) {
const startRadius = startWidth/2;
const endRadius = endWidth/2;
// calculate direction vector of point 1 and 2
let directionVectorX = x2 - x1,
directionVectorY = y2 - y1;
// calculate vector length
const directionVectorLength = Math.hypot(directionVectorX, directionVectorY);
// normalize direction vector (and therefore also the perpendicular vector)
directionVectorX = 1/directionVectorLength * directionVectorX;
directionVectorY = 1/directionVectorLength * directionVectorY;
// construct perpendicular vector
const perpendicularVectorX = -directionVectorY,
perpendicularVectorY = directionVectorX;
// construct shape
const path = new Path2D();
path.moveTo(x1 + perpendicularVectorX * startRadius, y1 + perpendicularVectorY * startRadius);
path.lineTo(x1 - perpendicularVectorX * startRadius, y1 - perpendicularVectorY * startRadius);
path.lineTo(x2 - perpendicularVectorX * endRadius, y2 - perpendicularVectorY * endRadius);
path.lineTo(x2 + perpendicularVectorX * endRadius, y2 + perpendicularVectorY * endRadius);
path.closePath();
return path;
}

const ctx = myCanvas.getContext('2d');
// create a growing line between P1(10, 10) and P2(250, 100)
// with a start line width of 10 and an end line width of 50
let line1 = createGrowingLine(10, 10, 250, 100, 10, 50);
ctx.fillStyle = 'green';
// draw growing line
ctx.fill(line1);
<canvas width="300" height="150" id="myCanvas"></canvas>

关于javascript - Canvas lineTo 中的 lineWidth 变化更平滑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26171610/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com