gpt4 book ai didi

javascript - 是否可以在 HTML5 canvas 中的路径上绘制图像?

转载 作者:行者123 更新时间:2023-11-30 09:43:49 24 4
gpt4 key购买 nike

例如,假设我有以下路径。

<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();

是否可以在线的弧度上绘制图像?如果是,怎么做?

最佳答案

切片图像以绘制曲线。

是的,这是可能的,尽管理想情况下这将是 WebGL 的工作。下一个最佳解决方案是扫描线渲染,但对于糟糕的 Javascript 管理来说,这是大量 CPU 负载的方式。

下一个 最好的 我的意思是“还可以”。选项是一个小图像切片。

您只需围绕圆弧以薄片形式绘制图像。 2D 渲染器并不完美,它会尽力绘制半个像素。结果是沿着每个切片的边缘都有一些噪音,您可以看到这些噪音。为了克服这个问题,我将每个切片画得稍微宽一些,以掩盖任何漏洞。

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

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

警告 给出的半径是针对内边缘的。它被审查以阻止 for 循环变得太长并阻止页面。您可能希望限制半径,使内圆周与图像宽度相同。 radius = radius < img.width / (Math.PI * 2) ? img.width / (Math.PI * 2) : radius;

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

// creates a blank image with 2d context
var createImage=function(w,h){var i=document.createElement("canvas");i.width=w;i.height=h;i.ctx=i.getContext("2d");return i;}

// create a canvas and add to dom
var can = createImage(512,512);
document.body.appendChild(can);
var ctx = can.ctx;

// create a image (canvas) to draw on the arc.
const textToDisplay = "<<Image on arc>>"

ctx.font = "64px arial";
var w = ctx.measureText(textToDisplay).width + 8;
var text = createImage(w + 64,84);
text.ctx.fillStyle = "#F90";
text.ctx.strokeStyle = "black";
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 = "Black";
text.ctx.lineWidth = 4;
text.ctx.strokeText(textToDisplay,38,58);
text.ctx.fillText(textToDisplay,38,58);



// draws image on arc
// img image to render
// x,y center of arc
// radius the inner edge (bottom of image) radius
// fromAng The angle to start drawing the image in radians
// toAng (optional if not given image width will be used to get toAng)
// returns undefined
function drawArcImage(img,x,y,radius,fromAng,toAng){

// WARNING if you let the radius get to small the ratio between the inner and out circumference
// gets very large. This will result in the image being stretched over a quintabazzilon pixels.
// so must vet the radius or you will block the page and upset the browser gods.

radius = Math.abs(radius); // only positive
radius = radius < img.height / 8 ? img.height / 8 : radius;
var outRad = radius + img.height;
var cir = Math.PI * 2 * radius; // get inner circumference
if(toAng === undefined){
var toAng = (img.width / cir) * Math.PI * 2 ; // get the angle the image will cover
}
var cirOut = toAng * outRad; // get the out edge distance in pixels
var imgStep = img.width / cirOut; // the image step per slice
var imgX = 0; // track the image line to draw
var angStep = toAng / cirOut; // the angle steps
// For each pixel on the out edge draw a slice
for(var i = 0; i < toAng; i += angStep){
var dx = Math.cos(fromAng + i);
var dy = Math.sin(fromAng + i);
// set up the transform to draw a slice from the inner to outer edges
ctx.setTransform(dy,-dx,-dx,-dy,dx * radius + x,dy * radius + y);
// get and draw the slice. I stretch it a little (2pix) to cover imperfect rendering
ctx.drawImage(img,imgX,0,imgStep,img.height,-1,-img.height,2,img.height);
// move to next slice
imgX += imgStep;
}
ctx.setTransform(1,0,0,1,0,0); // reset the transform
}


// animate the image to prove it is real.. LOL
var animTick = 0;
var animRate = 0.01;
var pos = 0;
// update function call via RAF
function update(){
animTick += animRate; // update tick
// random anim sin waves.
var rad = Math.sin(animTick) * (256-text.height - 20) + 20;
pos += Math.sin(animTick*10) * 0.02;
pos += Math.sin(animTick/ 3) * 0.02;
pos += Math.sin(animTick/ 7) * 0.05;
// clear
ctx.clearRect(0,0,can.width,can.height)
// draw
drawArcImage(text,256,256,rad,pos)
// do again and again and again
requestAnimationFrame(update);
}
update();

关于javascript - 是否可以在 HTML5 canvas 中的路径上绘制图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39859869/

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