LoginSignup
0
1

More than 1 year has passed since last update.

[Nuxt.js]Canvasで線を描画する

Posted at

資料に線を描画するという描画を実装したのですが、思ったより簡単に実装できたので共有します。
Composition APIを使用しています。

こちら完成形です。
aef10ae0522b11bb5f2b832781810bb8.gif

こちらコードになります。

index.vue
<template>
  <div id="canvasContainer">
    <h1>キャンバス</h1>
    <canvas
      id="penCanvas"
      width="600px"
      height="800px"
      @mousedown="onDragStart"
      @mousemove="drawLine"
      @mouseup="onDragEnd"
      @mouseout="onDragEnd"
    ></canvas>
  </div>
</template>

<script lang="ts">
import {
  onMounted,
  defineComponent,
  ref,
} from '@nuxtjs/composition-api'

export default defineComponent({
  setup() {
    const canvas = ref()
    const context = ref()
    const isDrawable = ref(false)

    onMounted(() => {
      canvas.value = document.querySelector('#penCanvas')
      context.value = canvas.value.getContext('2d')
      context.value.lineCap = 'round'
      context.value.lineJoin = 'round'
      context.value.lineWidth = 5
      context.value.storokeStyle = '#000000'
    })

    /**
     * キャンバスをドラッグした際の処理
     * @param {MouseEvent} e
     */
    const onDragStart = (e: MouseEvent) => {
      const posX = e.offsetX
      const posY = e.offsetY
      context.value.beginPath()
      context.value.lineTo(posX, posY)
      context.value.stroke()
      isDrawable.value = true
    }

    /**
     * 線を描画する
     * @param {MouseEvent} e
     */
    const drawLine = (e: MouseEvent) => {
      if (!isDrawable.value) return
      // ポインターの位置を格納
      const posX = e.offsetX
      const posY = e.offsetY
      context.value.lineTo(posX, posY)
      context.value.stroke()
    }

    /**
     * 描画終了時の処理
     */
    const onDragEnd = () => {
      context.value.closePath()
      isDrawable.value = false
    }

    return {
      canvas,
      context,
      isDrawable,
      onDragStart,
      drawLine,
      onDragEnd,
    }
  },
})
</script>

<style lang="scss">
#penCanvas {
  background: #6c757d;
}
</style>

それぞれ説明していきます。

onMounted

    onMounted(() => {
      canvas.value = document.querySelector('#penCanvas')
      context.value = canvas.value.getContext('2d')
      context.value.lineCap = 'round'
      context.value.lineJoin = 'round'
      context.value.lineWidth = 5
      context.value.storokeStyle = '#000000'
    })

DOMが作成された直後に行う処理です。
document.querySelector('#penCanvas') ・・・ canvasを取得
canvas.value.getContext('2d') ・・・ canvas上でペンを描画できるようにします。
context.value.lineCap = 'round' ・・・ 線端の形状指定します。今回は、丸にしています。
context.value.lineJoin = 'round' ・・・ 線の接合箇所の形状を指定します。今回は、丸にしています。
context.value.lineWidth = 5 ・・・ 線の幅を指定します。
context.value.storokeStyle = '#000000' 線の色を指定します。

onDragStart

ドラッグを開始した際に行われる処理です。

    /**
     * キャンバスをドラッグした際の処理
     * @param {MouseEvent} e
     */
    const onDragStart = (e: MouseEvent) => {
      const posX = e.offsetX
      const posY = e.offsetY
      context.value.beginPath()
      context.value.lineTo(posX, posY)
      context.value.stroke()
      isDrawable.value = true
    }

posX, posY ・・・ カーソルの位置を格納します。
context.value.beginPath ・・・ 現在のパスをリセットする際に使用します。
context.value.lineTo(posX, posY) ・・・ 直前の座標と指定座標を結ぶ直線を引く際に使用します。
context.value.stroke() ・・・ キャンバス上に線を描画します。

drawLine

ドラッグ中に行われる処理です。

    /**
     * 線を描画する
     * @param {MouseEvent} e
     */
    const drawLine = (e: MouseEvent) => {
      if (!isDrawable.value) return
      // ポインターの位置を格納
      const posX = e.offsetX
      const posY = e.offsetY
      context.value.lineTo(posX, posY)
      context.value.stroke()
    }

説明はonDragStartの際にしているので省略します。

onDragEnd

ドラッグ終了時に行われる処理です。

context.value.closePath()
isDrawable.value = false

context.value.closePath() ・・・ 最終座標と開始座標を結んでパスを閉じる際に使用します。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1