Vue.jsは、シングルページアプリだけでなく、あらゆる種類のUIのフロントエンドを処理するために使用できるすばらしいJavaScriptライブラリです。 スクリーンショットを撮るツールは、Vue.jsがいかに強力で使いやすいかを示す完璧な例です。

スクリーンショットを撮るツールは、マウスの位置と画面の寸法に基づいた単なる大きな数のクランチャーです。 数値はJSで計算され、Vue.jsにプラグインされます。Vue.jsは、余分なJavaScriptDOM操作なしですべてのUIレンダリングを処理します。

Vue.js Screenshot-taking tool UI

このチュートリアルでは、このようなフロントエンドUIを構築する方法を紹介します。この場合、マウスをドラッグして画面の一部を選択し、Vue.jsを使用してスクリーンショットとして保存できます。

UIを3つの個別の部分に分解する

Vue.js Screenshot-taking tool all parts

このようなUIを起動して実行するために必要なコアパーツは3つだけです。 コンテナ十字線、およびオーバーレイ

1. コンテナ

これは、Vue.jsインスタンスがインスタンス化される場所です。 視覚的なスタイルのない要素です。 この要素の目的は、マウスイベントの処理とデータプロパティのレンダリングを処理して、UIをリアルタイムで更新することです。

Vueテンプレート

<div id="screenshot" class="container">
  <div class="overlay"></div>
  <div class="crosshairs"></div>
</div>

Javascript

var screenshot = new Vue({
  el: "#screenshot"
});

2. 十字線

スクリーンショットツールは、十字線のないスクリーンショットツールではありません。 これは純粋に視覚的な要素です。 目的は、ユーザーが現在ページのどこにいて、どこからマウスをドラッグし始めようとしているのかを明確に示すことです。

Screenshot-taking tool crosshairs

十字要素の位置は、マウスが移動したときにスタイル属性の上下の位置を明示的に設定することによってレンダリングされます。

これは、Vue.jsの使用が非常に強力な場所です。 すべてのJavaScriptコードは、それらのleftおよびrightプロパティを取得し、それらをVueインスタンスのデータプロパティとして保存し、Vue.jsのバインディング構文とUIは自動的に更新されます。

crossHairsLeftおよびcrossHairsTopデータプロパティをVueインスタンスに追加すると、位置がこれらのプロパティに保存されます。

コンテナ要素にmousemoveイベントを追加し、これら2つのプロパティをマウスの位置に設定すると、これらの値が取得されます。

十字線を処理するためのVueテンプレート

<div @mousemove="move">
  <div class="overlay"></div>
  <div class="crosshairs" :style="{ left: crossHairsLeft + 'px', top: crossHairsTop + 'px' }"></div>
</div>

十字線の移動を処理するJavascript

var screenshot = new Vue({
  el: "#screenshot",

  data: {
    crossHairsLeft: 0,
    crossHairsTop: 0
  },
  methods: {
    move: function (event) {
      this.crossHairsTop = event.clientY;
      this.crossHairsLeft = event.clientX;
    }
  }
});

オーバーレイ

オーバーレイは、十字線を移動しているとき、またはマウスをドラッグしているときに表示される不透明な背景要素です。 これは、もう1つの純粋に視覚的な要素です。 マウスをドラッグすると、選択した領域が完全に不透明になり、白くなり、ページのどの領域のスクリーンショットが撮られるかを確認できます。 これはborderWidthプロパティで処理されます。

Screenshot-taking tool overlay

オーバーレイをクリックして、開始マウス位置の値を取得します

ユーザーがクリックすると、マウスの初期のxとyの開始値をキャプチャして保存する必要があります。 これは、 mousedown イベントをコンテナーに追加し、2つのプロパティをVueインスタンスに追加することで実行できます。 startXおよびstartY

更新されたVueテンプレート

<div @mousemove="move" @mousedown="mouseDown">
  <div class="overlay"></div>
  <div class="crosshairs" :style="{ left: crossHairsLeft + 'px', top: crossHairsTop + 'px' }"></div>
</div>

JavaScript

var screenshot = new Vue({
  el: "#screenshot",

  data: {
    crossHairsLeft: 0,
    crossHairsTop: 0,
    startX: 0,
    startY: 0,
    isMouseDown: false
  },

  methods: {

    move: function (event) {
      this.crossHairsTop = event.clientY;
      this.crossHairsLeft = event.clientX;
    },

    mouseDown: function (event) {
      this.startX = event.clientX;
      this.startY = event.clientY;
      this.isMouseDown = true;
    }
  }
});

オーバーレイを下にドラッグして、選択した領域をレンダリングします

スクリーンショーとして使用されるページの選択を示す開口部は、境界線を使用してレンダリングされます。 JavaScriptコードが行うのは、画面のサイズと最初の開始xおよびy位置を使用して適切な境界線幅を計算することだけです。

必要な2つの新しいプロパティは、borderWidthプロパティであり、境界幅の値の計算された文字列になります。 次に、isDraggingMouseブール値プロパティを使用して、ユーザーがクリック中にドラッグを開始したかどうかを判別します。 これは、クリックイベントが発生した直後ではなく、ユーザーがドラッグを開始した後にのみ十字線を非表示にするために使用されます。

Vueテンプレート

<div id="screenshot" class="container" @mousemove="move" @mousedown="mouseDown">
  <div class="overlay" :class="{ 'highlighting' : isMouseDown }" :style="{ borderWidth: borderWidth }"></div>
  <div class="crosshairs" :class="{ 'hidden' : isDraggingMouse }" :style="{ left: crossHairsLeft + 'px', top: crossHairsTop + 'px' }"></div>
</div>

Javascript

var screenshot = new Vue({
  el: "#screenshot",

  data: {
    crossHairsLeft: 0,
    crossHairsTop: 0,
    startX: 0,
    startY: 0,
    isMouseDown: false,
    isDraggingMouse: false
  },
  methods: {
    move: function (event) {
      var startY       = this.startY,
          startX       = this.startX,
          endX         = event.clientX,
          endY         = event.clientY,
          windowWidth  = window.innerWidth,
          windowHeight = window.innerHeight;
      this.crossHairsTop = event.clientY;
      this.crossHairsLeft = event.clientX;
      if (this.isMouseDown) {
        if (endX >= startX && endY >= startY) {
          this.isDragging = true;
          this.borderWidth = startY + "px " + (windowWidth - endX) + "px " + (windowHeight - endY) + "px " + startX + "px";
        }
      }
    },
    mouseDown: function (event) {
      this.startX = event.clientX;
      this.startY = event.clientY;
      this.isMouseDown = true;
    }
  }
});

マウスを離してスクリーンショットを撮る

最後に、スクリーンショット自体の撮影は、ユーザーがマウスを離した後に行われます。

JavaScriptロジック

@mouseup="mouseUp"をコンテナーに追加すると、mouseUp関数は、別のスクリーンショットを撮る準備をするために必要なリセットを処理し、スクリーンショット自体を撮るための関数を呼び出します。

methods: {
  mouseUp: function (e) {
    this.borderWidth = 0; // resetting the overlay

    if (this.isDragging) {
      // Don't take the screenshot unless the mouse moved somehow.
      this.tookScreenShot = true;
    }

    this.isDragging = false;
    this.mouseIsDown = false;

    this.takeScreenshot();

}

スクリーンショットを撮る機能

html2canvas というライブラリは、スクリーンショットの撮影に役立ちます。 ドキュメントまたは選択した要素をキャンバスに変換します。 その後、そのキャンバスを操作、トリミングして、最終的に画像に変換できます。

スクリプトここを取得し、ページに追加します。

methods: {
  takeScreenshot: function () {
    html2canvas(document.querySelector('body')).then(canvas => {
      let croppedCanvas = document.createElement('canvas'),
          croppedCanvasContext = croppedCanvas.getContext('2d');

      croppedCanvas.width  = this.croppedImageWidth;
      croppedCanvas.height = this.croppedImageHeight;

      croppedCanvasContext.drawImage(canvas, this.startX, this.startY, this.croppedImageWidth, this.croppedImageHeight, 0, 0, this.croppedImageWidth, this.croppedImageHeight);

      this.imageUrl = croppedCanvas.toDataURL();
    });
  }
}

結論

Chrome拡張機能に使用できるスクリーンショット撮影ツールのフロントエンドUIの作成を開始するために必要なのは、これですべてです。

これ以降は、すべてを正しく計算するためのカーソルの位置と画面の寸法に基づく数学とifステートメントの集まりにすぎません。

このチュートリアルで紹介したかった最も重要なことは、Vue.jsが、SPAだけでなく、あらゆる種類のUI関連の構築を支援するために使用できる強力なライブラリであることです。

参照

スタイルが整ったこのスクリーンショット撮影ツールの完成版を見たいですか? Codepenはこちらをご覧ください。

💻🔫