プレゼンモード
再生
← / →で移動
fでフルスクリーン
escでおわる
お絵かき体験向上作戦
振り返り
この発表は京都.なんか #2で発表したReactとCanvasでお絵かき機能を作った話の続編です。
前回の教訓より
- React成分を取り払ったところ、ただ単なるcanvasの入門的な紹介になった
- 各自の想像でReact成分を補足してください
今回のお話
どういうリサイズを行うのか
canvasリサイズ時の意図
- キャンバスサイズを大きくしたい
- 先程のデモのようにプロパティを大きくしてやればOK
- 画像自体を拡大したい
- 拡大比率に合わせて、座標位置、フォントサイズ、線の太さなども同じ比率で大きくする
描いてる最中で拡大縮小したい
textareaとcanvas同期問題
textareaとcanvasで文字を同期させる
- 普通にやっていけばOKです
- onInputで文字列を取ってcanvasに書く
- onKeydownでカーソル移動などを取得する
- textareaとReactについては省略しますので、各自でトライしてください
IME表示とカーソル
IME表示制御
- font-sizeとline-heightをtextareaとcanvasContextで揃えておく
- textareaを良い感じの位置で重ねて、opacity:0 とかにするとすんなりうまくいきます
カーソル表示
- opacity:0にするとカーソルが視えないので、divタグとかで良い感じにカーソルモドキを表示する
- カーソル位置を取得する
- カーソル位置を取得する
- 端から文字を数えていって、何行目の何文字目かを確定させる
- その場所にカーソル風の何かを表示する
- 場所を確定させる際にはCanvasRenderingContext2D.measureText()を利用する
(下のコードは雰囲気で書いてるので、動くことを保証していません)
const textarea = document.querySelector('...') const currentCaretPosition = input.selectionStart let textCounter = 0 textarea.value.split('\n').forEach((lineText, lineIndex) => { if (textCounter + lineText.length < currentCaretPosition) { // 行内にカーソルがないなら文字数をカウントしておいて次の行へ textCounter += lineText.length } else { const canvas = document.createElement('canvas') const context = canvas.getContext('2d') context.font = `bold ${fontSize}px Arial,Sans-Serif` // 行冒頭からカーソルまでのテキストを取り出す const text = lineText.substr(currentCaretPosition - textCounter) // 文字の縁取り線などを考慮して横幅を確実に取得するために // CanvasRenderingContext2D.measureText()を利用する const cursorX = context.measureText(text).width const cursorY = lineHeight * lineIndex } })
範囲選択を表現
- 応用したら出来るので、皆さんへの宿題にします