gpt4 book ai didi

javascript - 在 Canvas 上抚摸文本

转载 作者:行者123 更新时间:2023-12-01 15:42:09 25 4
gpt4 key购买 nike

我遇到了一个有趣的混合效果setLineDashstrokeText在 Canvas 上

ctx = document.querySelector("canvas").getContext("2d")
ctx.font = "110px Arial";
i = speed = 3

function loop() {
ctx.clearRect(0, 0, 600, 160)
ctx.beginPath()
ctx.setLineDash([i, 600]);
ctx.strokeText("WORLD ふ", 10, 100);
i += speed
if (i > 600 || i < 2)
speed *= -1
}

setInterval(loop, 50)
<canvas id="c" width=600 height=160></canvas>


如您所见 W绘制时间比 O 更长在这个片段中。
是否有任何属性可以检索字母最长行的像素数(长度)?

最佳答案

您可以在每个屏幕外绘制字符并“计算”像素的出现次数(非零值):

function getAmount (char, { width, height, font, color }) {
// create temporary offscreen canvas
const canvas = document.createElement('canvas')
canvas.width = width
canvas.height = height

// draw the character
const ctx = canvas.getContext("2d")
ctx.font = font
ctx.strokeText(char, 0, 90)

// get the pixels data
const imageData = ctx.getImageData(0, 0, width, height)
let sum = 0
imageData.data.forEach(point => {
if (point > 0) sum++
})
return sum
}

const width = 90
const height = 90
const font = "90px Arial"

getAmount('W', { font, width, height }) // 940
getAmount('O', { font, width, height }) // 660
getAmount('R', { font, width, height }) // 673
getAmount('L', { font, width, height }) // 296
getAmount('D', { font, width, height }) // 613

您可以粗略地使用这些值作为加权速度并单独绘制每个字符,但请记住,您还必须管理位置等。此外,这只检测任何非零值。在您为笔画使用渐变时,您必须在渐变范围内检测图像数据。

编辑:

由于找不到真相的来源,我们可以使用另一个技巧:

查找 i的号码这会创建一个与完整虚线字符具有相同像素数量的屏幕外图像。

/**
* draws a stroked text by given params to a context
**/

function draw (char, ctx, minValue, maxValue) {
ctx.clearRect(0, 0, 600, 160)
ctx.beginPath()
if (minValue && maxValue) {
ctx.setLineDash([minValue, maxValue])
}
ctx.strokeText(char, 10, 100);
}

/**
* Returns the amount of pixels for a given character
*/
const offscreenCanvas = document.createElement('canvas')
function getAmount (char, { value, max, width, height, font }) {
// draw offscreen, then detect border pixels
offscreenCanvas.width = width
offscreenCanvas.height = height

// draw the character
const ctx = offscreenCanvas.getContext("2d")
ctx.font = font
draw(char, ctx, value, max)

// get the pixels data
const imageData = ctx.getImageData(0, 0, width, height)
let sum = 0
imageData.data.forEach(point => {
if (point > 0) sum++
})

return sum
}

/**
* Returns the number of iterations required to complete a character
**/

function getIterations (char, { font, width, height }) {
// get amount when word is fully drawn
const fullAmount = getAmount(char, { value: undefined, max: undefined, width, height, font })

let iterations = 1
let amount = 0
do {
amount = getAmount(char, { value: iterations, max: 1000, width, height, font })
iterations++
} while ((amount - fullAmount < -3) && iterations < 2000);

return iterations
}

从这里我们可以确定 i setLineDash 的值范围:

const font = "110px Arial";
const width = 110
const height = 110

const check = char => {
const amount = getIterations(char, { font, width, height })
console.log(char, amount)
}


check('W') // 620
check('O') // 243
check('R') // 331
check('L') // 248
check('D') // 248
check('ふ') // 185

使用这些值,您可以创建一个相对的 speed参数,允许您同时完成笔画。

请注意,这种方法非常贪婪,并没有真正优化性能,而是一种概念证明。

关于javascript - 在 Canvas 上抚摸文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61275814/

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