Цитата из спецификации 2d контекста холста на strokeText
и fillText
:
Эти фигуры окрашиваются без влияния на текущий путь
Это имеет смысл и согласуется с strokeRect
и fillRect
, которые также не влияют на путь. При этом, похоже, не существует эквивалента rect
(например, text
), который вместо этого просто добавлял бы форму к текущему пути. Это не похоже на техническое ограничение, так как если текст можно обводить, контур должен быть известен в какой-то момент.
Вариант использования будет использовать текстовую форму с clip
, isPointInPath
, drawFocusIfNeeded
или любая другая функция, связанная с путями.
Я не нашел ни одного предложения, ни даже людей, просящих о таком дополнении. Может ли кто-нибудь подтвердить, что в настоящее время это невозможно и что я не пропустил ни одной дискуссии по этому поводу?
Обходной путь
В моем конкретном c случае (клипе) можно было эмулировать поведение с использованием другого холста и значения source-atop
для globalCompositeOperation
. Пример:
function drawClipped(ctx, drawClipRegion, drawClippedContent) {
let sourceCanvas = ctx.canvas;
let alt = document.createElement('canvas');
alt.width = sourceCanvas.width;
alt.height = sourceCanvas.width;
let altCtx = alt.getContext('2d');
drawClipRegion(altCtx);
altCtx.globalCompositeOperation = 'source-atop';
drawClippedContent(altCtx);
ctx.drawImage(alt, 0, 0);
}
let c = document.querySelector('canvas');
let ctx = c.getContext('2d');
// Background
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, c.width, c.height);
ctx.beginPath();
for (let i = 2; i < c.width; i += 5) {
ctx.moveTo(i, 0);
ctx.lineTo(i, c.height);
}
ctx.stroke();
// Text
drawClipped(
ctx,
ctx => {
ctx.font = '900 80px Impact, "Arial Black", sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillStyle = 'white';
ctx.fillText('TEXT', c.width / 2, c.height / 2);
},
ctx => {
ctx.beginPath();
for (let i = 2; i < c.height; i += 5) {
ctx.moveTo(0, i);
ctx.lineTo(c.width, i);
}
ctx.stroke();
}
);
<canvas width="200" height="200"></canvas>
Это все еще сложнее, чем простой clip
, и не решает вариант использования isPointInPath
.