Javascript 可以在HTML5画布的路径上绘制图像吗?

Javascript 可以在HTML5画布的路径上绘制图像吗?,javascript,html,canvas,Javascript,Html,Canvas,例如,假设我有以下路径 <canvas id="main" width="500" height="250"></canvas> var canvas = document.getElementById("main"); var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.moveTo(20,20); ctx.lineTo(100,20); ctx.arcTo(150,20,150,70,50); ctx.l

例如,假设我有以下路径

<canvas id="main" width="500" height="250"></canvas>

var canvas = document.getElementById("main");
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(20,20);
ctx.lineTo(100,20);
ctx.arcTo(150,20,150,70,50); 
ctx.lineTo(150,120);
ctx.lineWidth = 3;
ctx.stroke();

var canvas=document.getElementById(“主”);
var ctx=canvas.getContext(“2d”);
ctx.beginPath();
ctx.moveTo(20,20);
ctx.lineTo(100,20);
ctx.arcTo(150,20150,70,50);
ctx.lineTo(150120);
ctx.lineWidth=3;
ctx.stroke();

可以在直线的圆弧上绘制图像吗?如果是,怎么做?

这是一个类似问题的答案:

您可以在绘制循环中实现一个“线条绘制算法”,该算法不精确地绘制线条,而是在该点所在的位置绘制项目。除此之外,请替换此处的直线算法以绘制圆弧

function line(x0, y0, x1, y1){
     var dx = Math.abs(x1-x0);
     var dy = Math.abs(y1-y0);
     var sx = (x0 < x1) ? 1 : -1;
     var sy = (y0 < y1) ? 1 : -1;
     var err = dx-dy;

     while(true){ // put draw loop here.
         drawImage(image,x0,y0);//setPixel(x0,y0);  // Do what you need to for this

         if ((x0==x1) && (y0==y1)) break;
             var e2 = 2*err;
             if (e2 >-dy){ err -= dy; x0  += sx; }
             if (e2 < dx){ err += dx; y0  += sy; }
    }
}
功能行(x0,y0,x1,y1){
var dx=数学绝对值(x1-x0);
var dy=数学绝对值(y1-y0);
var sx=(x0-dy){err-=dy;x0+=sx;}
如果(e2
代码取自:Javascript中的Bresenham算法


我建议使用像p5.js这样的库来做类似的事情

这是一个类似问题的答案:

您可以在绘制循环中实现一个“线条绘制算法”,该算法不精确地绘制线条,而是在该点所在的位置绘制项目。除此之外,请替换此处的直线算法以绘制圆弧

function line(x0, y0, x1, y1){
     var dx = Math.abs(x1-x0);
     var dy = Math.abs(y1-y0);
     var sx = (x0 < x1) ? 1 : -1;
     var sy = (y0 < y1) ? 1 : -1;
     var err = dx-dy;

     while(true){ // put draw loop here.
         drawImage(image,x0,y0);//setPixel(x0,y0);  // Do what you need to for this

         if ((x0==x1) && (y0==y1)) break;
             var e2 = 2*err;
             if (e2 >-dy){ err -= dy; x0  += sx; }
             if (e2 < dx){ err += dx; y0  += sy; }
    }
}
功能行(x0,y0,x1,y1){
var dx=数学绝对值(x1-x0);
var dy=数学绝对值(y1-y0);
var sx=(x0-dy){err-=dy;x0+=sx;}
如果(e2
代码取自:Javascript中的Bresenham算法

我建议使用像p5.js这样的库来做类似的事情

切片图像以在曲线上绘制。 是的,这是可能的,尽管理想情况下这将是WebGL的工作。下一个最好的解决方案是扫描线渲染,但对于糟糕的Javascript来说,这是一种CPU负载过大的方式

下一个最好的选择是“好的”。选择是一个小的图像切片

您只需围绕弧以薄片形式绘制图像。2D渲染器并不完美,它试图尽可能地绘制半像素。结果是,每个切片的边缘都会出现一些噪波,您可以从中看到。为了克服这个问题,我把每一片画得稍微宽一点,以覆盖所有的洞

如果您需要高质量,在屏幕外的画布上以两倍的大小渲染,然后缩小到屏幕上的画布(不要忘记平滑),大多数人会认为它是这样绘制的

由于圆弧的内边缘和外边缘具有不同的周长,因此必须挤压或拉伸某些图像。在演示中,我将图像的内边缘保持在正确的宽度,并拉伸外边缘。更改很容易,但请确保使用外边缘计算要绘制的切片数

警告给定的半径用于内边缘。它被检查以阻止循环过长并阻塞页面。您可能需要限制半径,使内周长与图像宽度相同<代码>半径=半径

它很容易适应直线和曲线。您所需要的只是切线或曲线法线(应为单位向量,即长度1)使用此向量设置变换
ctx。setTransform(nx、ny、tx、ty、px、py)
。前两个值从图像底部指向顶部,后两个数字沿切线从左到右。最后两个是曲线上用于绘制切片的点

//创建具有2d上下文的空白图像
var createImage=function(w,h){var i=document.createElement(“canvas”);i.width=w;i.height=h;i.ctx=i.getContext(“2d”);返回i;}
//创建画布并添加到dom
var can=createImage(512512);
document.body.appendChild(can);
var ctx=can.ctx;
//创建要在圆弧上绘制的图像(画布)。
const textToDisplay=“”
ctx.font=“64px arial”;
var w=ctx.measureText(textToDisplay).width+8;
var text=createImage(w+64,84);
text.ctx.fillStyle=“#F90”;
text.ctx.strokeStyle=“黑色”;
text.ctx.lineWidth=16;
text.ctx.fillRect(0,0,text.width,text.height);
text.ctx.strokeRect(0,0,text.width,text.height);
text.ctx.font=“64px arial”;
text.ctx.fillStyle=“#0F0”;
text.ctx.strokeStyle=“黑色”;
text.ctx.lineWidth=4;
text.ctx.strokeText(textToDisplay,38,58);
text.ctx.fillText(textToDisplay,38,58);
//在圆弧上绘制图像
//要渲染的img图像
//弧的x,y中心
//半径内边缘(图像底部)半径
//从角度开始以弧度绘制图像
//蟾蜍(可选,如果未提供图像宽度,则将用于获取蟾蜍)
//返回未定义的
函数drawArcImage(图像、x、y、半径、fromAng、toAng){
//警告:如果半径变小,则内外周长之间的比率变小
//变得非常大。这将导致图像拉伸到五分之一像素。
//所以你必须检查半径,否则你会阻塞页面,扰乱浏览器。
radius=Math.abs(radius);//仅为正
半径=半径