Edited at
ShoTimeDay 2

JavaScript で文字列を最大 n 文字までの長さに分割した配列に変換する

この記事は ShoTime Advent Calendar 2018 の 2 日目の記事です。

文字列を画面上に表示させる時に、1行あたりの最大表示数を、n 文字までにしたい。というような状況があり、どのようにすれば良いか悩んだことがあり、そのときの解決策です。

具体的には、例えば次のような感じで、 text という文字列リテラルを textArray のような配列に変換させることができないか考えました。

const text = 'ShoTime1,000人'

const textArray = ['ShoTime', '1,000人']

text をそのまま表示させようとすると、表示領域からはみ出てしまいます。

608836c810f63fc9ef26e1c5b5cec150.png

textArray のように配列として適切に分割された文字列であれば次のように領域内に表示できます。

f162e2ef6bd2fb7ef66ed71ca1a9dcad.png

ShoTime では、Canvas を利用して文字列を表示させたかったので、その表示させる部分を含む全体のコードを載せておきます。(簡易的に書き換えています)

jsfiddle にコード置いています

<div id="app"></div>

const WIDTH = 200

const HEIGHT = 100
const TEXTS = 'ShoTime1,000人'

canvas = document.createElement('canvas')
canvas.width = WIDTH
canvas.height = HEIGHT
ctx = canvas.getContext('2d')

// background
ctx.fillStyle = '#4fc08d'
ctx.fillRect(0, 0, WIDTH, HEIGHT)

// texts
let textArray = toArrayFromText(TEXTS, 7)
ctx.font = `700 30px "Roboto Mono"`
ctx.fillStyle = '#fff'
textArray.forEach((t, index) => {
ctx.fillText(t, 10, 40 + (index * 40))
})

// Render
const app = document.getElementById('app')
app.innerHTML = ''
app.appendChild(canvas)

function toArrayFromText (text, maxLength) {
if (typeof text !== 'string') return
else if (typeof maxLength !== 'number') maxLength = 10
return text.match(new RegExp('.{1,' + maxLength + '}', 'g'))
}

このコードの toArrayFromText によって、適切な変換ができるようにしています。

変換ができてしまえば、あとはループさせて表示させるだけとなります。

toArrayFromText 関数は、実運用時には、他にも改行コードへの対応や、サロゲートペアの考慮など課題があります。ですが、簡易的にするためここでは紹介しておりません。


さいごに

限られた領域にユーザーが入力した文字列を表示させるという課題は ShoTime(目標達成シート) で実際に利用しています。ぜひ触ってみてください!