gpt4 book ai didi

javascript - 如何使用 javascript 和 Canvas 2D 上下文注释一行?

转载 作者:行者123 更新时间:2023-11-28 18:53:44 26 4
gpt4 key购买 nike

我需要通过在开头和结尾放置文本来注释一行。我还需要插入文本,但文本所在的线条不可见。

有人可以告诉我如何向 2D Canvas 上下文的行添加文本吗?

最佳答案

使用 setTransform 注释线条

注释一行最好使用 CanvasRenderingContext2D.setTransform() 来完成以便将世界空间(文本)与屏幕空间(绘制线条的位置)对齐。一旦你有了这个,那么所有的绘图坐标都将就像这条线沿着 Canvas 的顶部一样。

线的起点位于 (0,0),线的终点位于 x 坐标,等于线的长度。您可以使用 CanvasRenderingContext2D.textBaseline 在线上方、上方和下方进行绘制。属性(property)。您可以使用 CanvasRenderingContext2D.textAlign 绘制与两端和中心对齐的文本。属性。

要在行中留有间隙,请使用 CanvasRenderingContext2D.measureText函数获取文本宽度并在文本周围绘制线段。

代码示例具有函数 transformToLine(ctx, x1, y1, x2, y2)它将当前 Canvas 变换设置为与线条对齐,然后返回线条的长度,以便可以使用它来添加文本。

我还提供了一些代码,展示了如何在线上、在线中、在线前、在线后、在线上和在线下进行渲染。还有三个实用函数可以帮助在行中绘制文本。

transformToLine(ctx, x1, y1, x2, y2)是一个非常方便的功能,有很多用途,不仅用于沿线绘制文本。就我个人而言,我发现它非常有用,我将其添加到 Canvas 上下文中,而不是作为全局函数。

var canvas = document.getElementById("canV"); 
var ctx = canvas.getContext("2d");

// ES6 new math function
// simple polyfill for IE on others
var hypot;
if(typeof Math.hypot === 'function'){
hypot = Math.hypot;
}else{
hypot = function(x,y){ // Untested
return Math.sqrt(Math.pow(x,2)+Math.pow(y,2));
};
}

// Sets the 2D context tranformation to the line segment x1,y1 to x2, y2 and
// returns the length of the line
function transformToLine(ctx, x1, y1, x2, y2){
var ang, xd, yd;
var ang = Math.atan2(y2 - y1, x2 - x1); // get the line direction
var xd = Math.cos(ang); // get the vector for x axis
var yd = Math.sin(ang);
ctx.setTransform(xd, yd, -yd, xd, x1, y1); // create the trnasform
return hypot(x1 - x2, y1 - y2); // return the lines length
}
// restores the 2Dcontext transformation to the default
// Use the rather than save and restore if its only the transform that you want
// to save and restore. its a lot quicker.
function transformDefault(ctx){
ctx.setTransform(1, 0, 0, 1, 0, 0);
}

// Draws text in a line, drawing the line either side of the text if there is space.
// ctx is the context to be drawn on.
// text is the text
// inset is how many pixels from the start
// x1, y1 and x2, y2 is the line
function textAtStart (ctx, text, inset, x1, y1, x2, y2) {
var len, textW, lw;
len = transformToLine(ctx, x1, y1, x2, y2); // set transform and get line length
ctx.textBaseline = "middle"; // set text over the line
ctx.textAlign = "left"; // align left
textW = ctx.measureText(text).width; // get the text size
ctx.fillText(text, inset, 0); // draw the text
ctx.beginPath(); // draw the parts of the line around the text if there is space
lw = Number(ctx.lineWidth) * 2; // leave a clearance so the line does not touch the text
if (inset - lw > 0) { // Check for space befor the text
ctx.moveTo(0, 0);
ctx.lineTo(inset - lw, 0);
if (inset + textW + lw < len) { // check for space after the text
ctx.moveTo(inset + textW + lw, 0);
ctx.lineTo(len, 0);
}
ctx.stroke(); // draw the line
}
transformDefault(ctx); // restor the transform
}
// Draws text in a line, drawing the line either side of the text if there is space.
// ctx is the context to be drawn on.
// text is the text
// inset is how many pixels from the end
// x1, y1 and x2, y2 is the line
function textAtEnd (ctx, text, inset, x1, y1, x2, y2) {
var len, textW, lw;
len = transformToLine(ctx, x1, y1, x2, y2); // set transform and get line length
ctx.textBaseline = "middle"; // set text over the line
ctx.textAlign = "right"; // align left
textW = ctx.measureText(text).width; // get the text size
ctx.fillText(text, len - inset, 0); // draw the text
ctx.beginPath(); // draw the parts of the line around the text if there is space
lw = Number(ctx.lineWidth) * 2; // leave a clearance so the line does not touch the text
if (len - inset - textW - lw > 0) { // Check for space befor the text
ctx.moveTo(0, 0);
ctx.lineTo(len - inset - textW - lw, 0);
if (len - inset + lw < len) { // check for space after the text
ctx.moveTo(len - inset + lw, 0);
ctx.lineTo(len, 0);
}
ctx.stroke(); // draw the line
}
transformDefault(ctx); // restor the transform
}

// Draws text in a line, drawing the line either side of the text if there is space.
// ctx is the context to be drawn on.
// text is the text
// x1, y1 and x2, y2 is the line
function textAtCenter (ctx, text, x1, y1, x2, y2) {
var len, textW, lw;
len = transformToLine(ctx, x1, y1, x2, y2); // set transform and get line length
ctx.textBaseline = "middle"; // set text over the line
ctx.textAlign = "center"; // align center
textW = ctx.measureText(text).width; // get the text size
ctx.fillText(text, len / 2, 0); // draw the text
ctx.beginPath(); // draw the parts of the line around the text if there is space
lw = Number(ctx.lineWidth) * 2; // leave a clearance so the line does not touch the text
if (len / 2 - textW / 2 - lw > 0) { // Check for space befor the text
ctx.moveTo(0, 0);
ctx.lineTo(len / 2 - textW / 2 - lw, 0);
if (len / 2 + textW / 2 + lw < len) { // check for space after the text
ctx.moveTo(len / 2 + textW / 2 + lw, 0);
ctx.lineTo(len, 0);
}
ctx.stroke(); // draw the line
}
transformDefault(ctx); // restor the transform
}

// Thats all you need to put text on a line.
// below is an example of how it used


// variables and constants. My coding style always has constants upperCase with
// snake case used for clarity is needed.
const PI2 = Math.PI*2;
var i;
const CW = canvas.width/2; // center Width CW
const CH = canvas.height/2; // center Height CH
var x1,y1,x2,y2,len,angleText, lengthText;

// set up the ctx
ctx.font = "12px verdana";
ctx.lineJoin = "round";

// clear the sreen
ctx.clearRect(0,0,canvas.width,canvas.height)

// draw 16 lines in a circle towards the center.
for(i = 0; i < PI2; i += PI2/16){
// get the start and end location of a line
x1 = Math.cos(i)*(CW*0.95)+CW;
y1 = Math.sin(i)*(CH*0.95)+CH;
x2 = Math.cos(i)*(CW*0.2)+CW;
y2 = Math.sin(i)*(CH*0.2)+CH;

angleText = "Ang: "+Math.round((360/PI2)*i); // get the aprox angle in deg


// set the transformation to the line
// This is the secret to drawing alon a line.
len = transformToLine(ctx,x1,y1,x2,y2);

//If you dont want the line text to be upside down

// world space is now allong the line with the orign
// at the line start x1,y1 and the end of the line at
// world coordinate len,0 with down at 90 clockwise from
// the line

lengthText = "Len: "+Math.round(len)

ctx.fillStyle = "black"; //text black
ctx.strokeStyle = "black"; //line black
// Draw the angle text above the line.
ctx.textAlign = "left"; // align to the start of the line
ctx.textBaseline = "bottom";
ctx.fillText(angleText,0,-2);

// draw the length under the line
ctx.textBaseline = "top";
ctx.fillText(lengthText,0,0);


// Draw end just befor the end of the line
// Get the size of the word end so we can make some space for it
// by not drawing the line over it
var endW = ctx.measureText("END").width;

// align to right
ctx.textAlign = "right";
ctx.textBaseline = "middle"; // draw over the line
// using stroke text for small fonts is a cheaters whay of making it bold.
ctx.strokeText("END",len-10,0); // draw it 10 pixels from the ens

// put some text befor the start of the line
ctx.fillStyle = "red";

ctx.textAlign = "right"; // align text right so its draw away from the line
ctx.fillText("->",-2,0); // draw text 2 pixels befor start

ctx.textAlign = "left"; // align text right so its draw away from the line
ctx.fillText("<-",len+2,0); // draw it 2 pixels past end pixels from the ens


// Draw a -+- in the center of the line just because we can
var centerW = ctx.measureText("-+-").width;
ctx.textAlign = "center"; // align text to center
ctx.fillText("-+-",len/2,0); // draw text at the center of the line


// draw the line. As the world space is along the line
// the line will just follow the x axies so it is easy to position
// spaces and break the line up to make space for text
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(len/2-centerW/2-2,0);
// space for center text
ctx.moveTo(len/2+centerW/2+2,0);
ctx.lineTo(len-endW - 12,0);
// Space for the word END
ctx.moveTo(len -8,0); // last part of the line
ctx.lineTo(len ,0);
ctx.stroke(); // draw it

// restore the transformation.
transformDefault(ctx);
}
.canC { width:500px;  height:500px;}
<canvas class="canC" id="canV" width=500 height=500></canvas>

关于javascript - 如何使用 javascript 和 Canvas 2D 上下文注释一行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34032370/

26 4 0
文章推荐: python - 有没有办法在 Bada 上运行 Python?
文章推荐: python - 使用 Jenkins 进行测试时处理硬件资源
文章推荐: javascript - css:没有 的图库 View