Вы можете рисовать символы каждый закадровый и «подсчитывать» вхождения пикселей (ненулевые значения):
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
Вы можете использовать эти значения примерно как увеличение скорости и рисовать каждый символ индивидуально но имейте в виду, что вам придется управлять размещением et c. дополнительно. Также это только обнаруживает любое ненулевое значение. Если вы используете градиенты для своего удара, вам придется обнаружить данные изображения в пределах диапазона градиента.
Редактировать:
Поскольку источник истины не найден, мы можем использовать Еще один трюк:
Найдите число 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
, который позволит вам одновременно выполнять штрихи.
Примечание То, что этот подход очень жадный и не оптимизирован по производительности, скорее доказательство концепции.