HTML のキャンバスに基づくスクリーンショットのデモ

HTML のキャンバスに基づくスクリーンショットのデモ

冒頭に書いた

以前、Renren で JS ベースのスクリーンショット ソリューションについて説明した共有を見たのを覚えています。詳細は覚えていませんが、非常に興味深く、キャンバスを使用しているようだったことを覚えています。そこで今回は、著者の考えを皆さんと共有するために、自分でも書いてみようと思います。これは単なる簡単なデモです。バグを見つけた場合は問題を報告してください。コードアドレスを投稿するには、規則に従ってください。

レンダリング

全体的なアイデア

  • 開始/終了ショートカットキーを設定する
  • 開始後、DOMをキャンバスに描画して元のDOMインターフェースを覆います
  • マウスのスクリーンショット領域をシミュレートするキャンバスを追加する
  • マウスのスクリーンショット領域に対応するブラウザインターフェースを描画するためのキャンバスを追加します(最初のキャンバスからキャプチャされます)
  • 撮影した画像を保存する

1. 開始/終了ショートカットキーを設定する

ショートカット キーは競合を引き起こす可能性があるため、最初はショートカット キーの数に制限がないことを望んでおり、配列を使用して最初のパラメーターでショートカット キーを渡します。

関数スクリーンショット(quickStartKey, EndKey) {
  //使用しないでください...拡張文字列 var keyLength = quickStartKey.length
  var isKeyTrigger = {}
  var cantStartShot = false
  ...
  quickStartKey.forEach(function(item) { //パラメータ配列を走査します isKeyTrigger[item] = false //デフォルト配列内のすべてのキーはトリガーされません})
  $('html').on('keyup', 関数(e) {
    var キーコード = e.which
    if(keyCode === EndKey) {
      ...
    } そうでない場合(!ショットを開始できない場合) {
      isKeyTrigger[キーコード] = true
      var notTrigger = Object.keys(isKeyTrigger).filter(function(item) {
        return isKeyTrigger[item] === false // トリガーする必要があるショートカットキーがあるかどうかを確認します})
      if(notTrigger.length === 0) { //スクリーンショットを開始するためにショートカットキーをトリガーする必要はありません cantStartShot = true
        beginShot(ショットを開始できない)
      }
    }
  })

2. DOMをキャンバスに描画して、元のDOMインターフェースを覆う

ネイティブ方式を使用する場合は、MDN のキャンバスで DOM を描画する方法の紹介を参照してください。難しいのは、<foreignObject> 要素に含まれる XML を含む SVG イメージを作成する必要があることです。現在のブラウザで表示されている DOM を計算して抽出する方法が、実は最も面倒です。実は、著者は = を手動で実装するための良いアイデアを持っていません。 =なので、これを実行するために html2canvas ライブラリを選択しました。一般的な呼び出し方法は次のとおりです。

関数beginShot(cantStartShot) {
    if(cantStartShot) {
        html2canvas(ドキュメント.body, {
            レンダリング時: function(canvas) {
                //インターフェースと一致するキャンバス画像を取得します}
        })
    }
}

3. マウスのスクリーンショット領域をシミュレートするキャンバスを追加する

この部分の実装は、もともとネイティブのキャンバス API を使用する予定でしたが、マウスが押されてドラッグが開始された後、キャンバスをリアルタイムで描画する必要があるという問題がありました。これには、PS レイヤーに似た概念が必要です。マウスが移動するたびに、現在のスクリーンショット フレームが描画されますが、次にマウスが移動すると、前のスクリーンショット フレームが削除されます。これはリアルタイムの描画プロセスをシミュレートします。残念ながら、作者はキャンバスのネイティブ API を使用する方法を見つけていません。もしあるのであれば、描画したイメージにマークを付ける方法を教えてください。ここで著者は、Jcanvas と呼ばれる Jq ベースのキャンバス ライブラリを使用します。このライブラリはレイヤーの概念を提供します。つまり、レイヤーには 1 つの画像のみを描画でき、レイヤーには名前を付けることができます。これは著者のニーズを満たしており、次のように実装されています。

$('#' + canvasId).mousedown(function(e) {
    $("#"+canvasId).removeLayer(layerName) //前のレイヤーを削除する layerName += 1
    startX = that._calculateXY(e).x //マウスの位置を計算します startY = that._calculateXY(e).y
    isShot = true
    $("#"+キャンバスID).addLayer({
        タイプ: 'rectangle', //rectangle...
        name:layerName, //レイヤー名 x: startX,
        y: 開始Y、
        幅: 1,
        高さ: 1
    })
}).mousemove(関数(e) {
    if(isShot) {
        $("#"+canvasId).removeLayer(レイヤー名)
        var moveX = that._calculateXY(e).x
        var moveY = that._calculateXY(e).y
        var 幅 = 移動X - 開始X
        var 高さ = 移動Y - 開始Y
        $("#"+キャンバスID).addLayer({
            タイプ: '長方形'、
            ...
            名前:レイヤー名、
            fromCenter: false、
            x: 開始X、
            y: 開始Y、
            幅: 幅、
            高さ: 高さ
        })
        $("#"+canvasId).drawLayers(); //描画}
    })

4. マウスのスクリーンショット領域に対応するブラウザインターフェースを描画するためのキャンバスを追加します。

var キャンバス結果 = document.getElementById('キャンバス結果')
              var ctx = canvasResult.getContext("2d");
              ctx.drawImage(copyDomCanvas, moveX - startX > 0 ? startX : moveX, moveY - startY > 0 ? startY : moveY, width, height, 0, 0, width, height )
              var dataURL = canvasResult.toDataURL("image/png");

画像はdrawImageでキャプチャされ、toDataURLメソッドを使用して画像をbase64エンコードに変換します。

5. 撮影した画像を保存する

関数downloadFile(el, ファイル名, href){
      el.attr({
        'ダウンロード':ファイル名、
        'href': href
      })
  }
  ...
ダウンロードファイル($('.ok'), 'screenShot' + Math.random().toString().split('.')[1] || Math.random() + '.png', dataURL)
// ボタンオブジェクト、画像を保存するためのランダムな名前、および base64 でエンコードされた画像を渡します

a タグのダウンロード属性を使用し、ユーザーがクリックすると直接ダウンロードを実行できます。

展開する

依存関係

<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/jcanvas/16.7.3/jcanvas.min.js"></script>
<script src="https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.min.js"></script>

ショートカットキーを設定する

screenShot([16, 65], 27) // 開始ショートカットキーはshift+a、終了キーはESC

やっと

記事の一番嫌な部分(キャンバスへのDOM書き込み、キャンバス設定レイヤー)は、それぞれ2つのライブラリを使用して実装されています。今後、ネイティブAPIを使用してこれらの操作を実装する方法に焦点を当てていきますが、個人的には私の文章はまだ少し... 。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

<<:  Eclipse は Tomcat を構成しますが、Tomcat には無効なポート解決策があります

>>:  体験したい17 404ページ

推薦する

Navicat Premiumを使用してMySQLデータベースにリモート接続する方法

新しい接続を作成する側がクライアントに相当し、接続される側がサーバーに相当します。手順は次のとおりで...

Nginx タイムアウト設定の詳細な説明

最近、プロジェクトで nginx を使用し、バックエンドで Java を使用しました。バックエンドで...

mysql8.0.11クライアントがログインできない問題の解決方法

この記事では、mysql8.0.11クライアントがログインできない問題の解決策を紹介します。参考まで...

JS でタブ効果を書く

この記事の例では、タブ効果を記述するためのJSの具体的なコードを参考までに共有しています。具体的な内...

バントリストコンポーネントをスクロールしても、スクロールバーの位置は保持されます。

バントリストコンポーネントをスクロールするときに、スクロールバーの位置が保持されます。これは、kee...

CSS でテキストシャドウと要素シャドウ効果を使用する

テキストシャドウの紹介CSSでは、 text-shadowプロパティを使用してテキストの影を設定しま...

レスポンシブなアコーディオン効果を実現するための CSS3 の詳細な説明

最近、外国人が CSS3 を使用してアコーディオン効果を実現しているビデオを見たので、自分で学習した...

Nginx ソースコード調査における nginx 電流制限モジュールの詳細な説明

目次1. 電流制限アルゴリズム2. nginxの基礎知識4. 実戦要約する高並行性システムには、キャ...

Docker Compose の実践とまとめ

Docker Compose は、Docker コンテナ クラスターのオーケストレーションを実現しま...

Vueの7つの値転送メソッドの詳細な説明

1. 父から息子へ子コンポーネントにpropsフィールドを定義し、その型は配列です (フィールド値の...

MySQL の分離レベルの包括的な分析

データベースが同じデータ バッチを同時に追加、削除、および変更すると、ダーティ書き込み、ダーティ読み...

jQueryチェーン呼び出しの詳細な説明

目次チェーン呼び出し小さなケースチェーン呼び出しjQuery オブジェクトが任意のメソッド (ノード...

sqlとmysqlの違いは何ですか?

SQL とは何ですか? SQL はデータベースを操作するために使用される言語です。 SQL はすべ...