我正在尝试使用画布和动力学的组合来构建舱口模式,并且我在尝试获得连续线时遇到问题.
这个jsfiddle显示了我到目前为止所拥有的内容,但由于我的重复模式是一个方形,角落正在影响线条,我尝试使用lineJoin和lineCap属性,但似乎无法获得所需的结果.
有问题的主要代码是:
var hatchPattern = document.getElementById("canvas")
var context = hatchPattern.getContext('2d');
context.strokeStyle = "#FF0000";
context.beginPath();
context.moveTo(0, 20);
context.lineTo(20, 0);
context.lineWidth = 5;
context.stroke();
context.closePath();
Run Code Online (Sandbox Code Playgroud)
有人可以帮忙吗?
更新:
我创造了另一个jsfiddle虽然不完美,可能会为我做,但仍然不确定为什么会有一个微小的差距!
要创建覆盖画布的对角线,可以创建如下图案:
您必须用三角形填充左上角和右下角.当在图案中重复时,这些三角形将填充由您的中心线到达右上角和左下角的点引起的斜角.
然后createPattern(yourPattern,"repeat")将这样的图案填充画布:
这是示例代码和显示更细线的演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var p = document.createElement("canvas")
p.width=32;
p.height=16;
var pctx=p.getContext('2d');
var x0=36;
var x1=-4;
var y0=-2;
var y1=18;
var offset=32;
pctx.strokeStyle = "#FF0000";
pctx.lineWidth=2;
pctx.beginPath();
pctx.moveTo(x0,y0);
pctx.lineTo(x1,y1);
pctx.moveTo(x0-offset,y0);
pctx.lineTo(x1-offset,y1);
pctx.moveTo(x0+offset,y0);
pctx.lineTo(x1+offset,y1);
pctx.stroke();
ctx.fillStyle=ctx.createPattern(p,'repeat');
ctx.fillRect(0,0,canvas.width,canvas.height);Run Code Online (Sandbox Code Playgroud)
#canvas{border:1px solid red;}Run Code Online (Sandbox Code Playgroud)
<canvas id="canvas" width=300 height=300></canvas>Run Code Online (Sandbox Code Playgroud)
markE 的代码不会产生 45º 角的细条纹图案(实际上,它与他的示例 png 图像不匹配),所以我最终重写了它以概括它。
代码片段:
/** Creates a canvas filled with a 45-degree pinstripe.
* @returns the filled HTMLCanvasElement. */
function createPinstripeCanvas() {
const patternCanvas = document.createElement("canvas");
const pctx = patternCanvas.getContext('2d', { antialias: true });
const colour = "#B4645D";
const CANVAS_SIDE_LENGTH = 90;
const WIDTH = CANVAS_SIDE_LENGTH;
const HEIGHT = CANVAS_SIDE_LENGTH;
const DIVISIONS = 4;
patternCanvas.width = WIDTH;
patternCanvas.height = HEIGHT;
pctx.fillStyle = colour;
// Top line
pctx.beginPath();
pctx.moveTo(0, HEIGHT * (1 / DIVISIONS));
pctx.lineTo(WIDTH * (1 / DIVISIONS), 0);
pctx.lineTo(0, 0);
pctx.lineTo(0, HEIGHT * (1 / DIVISIONS));
pctx.fill();
// Middle line
pctx.beginPath();
pctx.moveTo(WIDTH, HEIGHT * (1 / DIVISIONS));
pctx.lineTo(WIDTH * (1 / DIVISIONS), HEIGHT);
pctx.lineTo(0, HEIGHT);
pctx.lineTo(0, HEIGHT * ((DIVISIONS - 1) / DIVISIONS));
pctx.lineTo(WIDTH * ((DIVISIONS - 1) / DIVISIONS), 0);
pctx.lineTo(WIDTH, 0);
pctx.lineTo(WIDTH, HEIGHT * (1 / DIVISIONS));
pctx.fill();
// Bottom line
pctx.beginPath();
pctx.moveTo(WIDTH, HEIGHT * ((DIVISIONS - 1) / DIVISIONS));
pctx.lineTo(WIDTH * ((DIVISIONS - 1) / DIVISIONS), HEIGHT);
pctx.lineTo(WIDTH, HEIGHT);
pctx.lineTo(WIDTH, HEIGHT * ((DIVISIONS - 1) / DIVISIONS));
pctx.fill();
return patternCanvas;
}
/** Fills the whole area of a given htmlCanvasElement with a patternCanvas.
* @param targetCanvas – the HTMLCanvasElement to fill into.
* @param patternCanvas – a HTMLCanvasElement containing a pattern to fill with.
*/
function fillWithPattern(targetCanvas, patternCanvas){
const ctx = targetCanvas.getContext('2d', { antialias: false, depth: false });
const width = targetCanvas.width;
const height = targetCanvas.height;
if (!width || !height) throw new Error("progressCanvas's width/height falsy.");
ctx.fillStyle = ctx.createPattern(patternCanvas, 'repeat');
ctx.fillRect(0, 0, width, height);
return targetCanvas;
}
fillWithPattern(document.getElementById("targetCanvas"), createPinstripeCanvas());Run Code Online (Sandbox Code Playgroud)
#targetCanvas{border:1px dotted black;}Run Code Online (Sandbox Code Playgroud)
<canvas id="targetCanvas" width=300 height=300></canvas>Run Code Online (Sandbox Code Playgroud)