VueでKonva.jsとcanvasを使ってお絵描き(その5)


その4はこちら

直線を引けるようにする

モードで直線を選択したら直線を引けるようにしようと思います。

・描画開始(マウスダウン)時にその時の座標を取得
・描画中(マウスムーブ)は何もしない
・描画終了(マウスアップ)時にその時の座標を取得

...開始・終了の座標を結んだら直線引けるんじゃね?って思ってやってみたらできました。

親(CallCanvas.vue)のほうはすでに直線モードを子に渡せる状態になっているので変更はありません。

子(FreeDrawing.vue)を修正します。
以下のようなコメント行の間にあるソースが直線を引くために追加したソースコードです。

/** 追加 */
...
..
.
/** 追加ここまで */
FreeDrawing.vue
...
..
.

<script>
import Konva from 'konva'

export default {
  ...
  ..
  .
  methods: {
    mousedown: function () {
      this.isPaint = true

      // マウスダウン時の座標を取得しておく
      this.lastPointerPosition = this.stage.getPointerPosition()

      // 戻す配列に描画前のキャンバスの状態を保存
      this.undoDataStack.push(this.context.getImageData(0, 0, this.canvas.width, this.canvas.height))

      /** 追加 */
      // 直線モード時はマウスダウン時に描画開始座標を指定する
      if (this.isTargetMode('line')) {
        this.context.beginPath()

        this.localPos.x = this.lastPointerPosition.x - this.drawingScope.x()
        this.localPos.y = this.lastPointerPosition.y - this.drawingScope.y()

        // 描画開始座標を指定する
        this.context.moveTo(this.localPos.x, this.localPos.y)
      }
      /** 追加ここまで */
    },
    mouseup: function () {
      this.isPaint = false

      /** 追加 */
      // 直線モード時はマウスアップ時に描画する
      if (this.isTargetMode('line')) {
        this.pos = this.stage.getPointerPosition()
        this.localPos.x = this.pos.x - this.drawingScope.x()
        this.localPos.y = this.pos.y - this.drawingScope.y()

        // 描画開始座標から、lineToに指定された座標まで描画する
        this.context.lineTo(this.localPos.x, this.localPos.y)
        this.context.closePath()
        this.context.stroke()
        this.drawingLayer.draw()

        this.lastPointerPosition = this.pos
      }
      /** 追加ここまで */
    },
    mousemove: function () {
      if (!this.isPaint) {
        return
      }
      // ペンモード時
      if (this.isTargetMode('brush') || this.isTargetMode('line')) {
        this.context.globalCompositeOperation = 'source-over'
      }
      // 消しゴムモード時
      if (this.isTargetMode('eraser')) {
        this.context.globalCompositeOperation = 'destination-out'
      }

      /** 追加 */
      // 直線モード時は何もしない
      if (this.isTargetMode('line')) {
        return
      }
      /** 追加ここまで */

      ...
      ..
      .
    },
    ...
    ..
    .
}
</script>

引けました!ただ斜め線引いた時に少しギザギザなってしまうところが難点。
(考えを安直にソースにしただけなので仕方ないかもしれないですが。)

備考

直線を引くときにガイドラインを表示してあげたりとかできるとさらに良くなりますね。
気が向いたらやってみます。