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ページ

推薦する

Nginx+tomcat ロードバランシングクラスタの実装方法

実験環境は以下のとおりですここでは、4 台のサーバー (1 台の nginx、負荷用の 2 台の t...

MySQL交換パーティションの詳細な例

MySQL交換パーティションの詳細な例序文exchange パーティションを紹介する前に、まず my...

HTMLページ内の検索機能を完了する

最近、たくさんの人に改変してもらったフレームワークに取り組んでいます。毎日コードを見ていると目が回り...

Linuxパフォーマンス監視コマンドの簡単な紹介

システムでさまざまな IO ボトルネック、メモリ使用量の増加、CPU 使用率の増加などの問題が発生し...

Win10 の組み込み Linux システムを使用して Spring Boot プロジェクトを開始する方法

1. Windows10の組み込みLinuxサブシステムをインストールする1.1. Linuxサブシ...

Vue でユーザー権限に基づいてルートを動的に追加する方法

ユーザーの権限に応じて異なるメニュー ページを表示します。知識ポイントルートガード(事前ガードを使用...

MySQLリモート接続権限の詳細な説明

1. MySQLデータベースにログインするmysql -u ルート -pユーザーテーブルを表示する ...

docker システムコマンドセットの使用

目次docker システム df docker システム プルーンdocker systemc 情報...

MySQL の挿入ステートメントの使用実体験

目次1. 挿入のいくつかの構文1-1. 通常の挿入文1-2. 挿入または更新1-3. 挿入または交換...

簡単な手順で純粋な CSS3 で 3D 反転効果を実現

フロントエンド開発者の必須科目であるCSS3は、多くの基本的なアニメーション効果を実現するのに役立ち...

MySQL の CPU 負荷が高い問題のトラブルシューティング

MySQL による CPU 負荷の上昇今日の午後、MySQL によってサーバーの負荷が高くなる問題を...

JavaScript PromiseとAsync/Awaitの詳細な説明

目次概要4つの例例1: 誕生日で説明する約束の基本例2: 数字当てゲーム例3: Web APIから国...

ドメイン名を指定されたポートに転送するようにNginxを設定する方法

/usr/local/nginx/conf と入力する sudo cd /usr/local/ngi...

Trash-Cli: Linux のコマンドラインごみ箱ツール

ゴミ箱は Linux ユーザー、Windows ユーザー、Mac ユーザーにとって非常に一般的なので...

HTML テーブルタグチュートリアル (21): 行の境界線の色属性 BORDERCOLOR

テーブルを美しくするために、行ごとに異なる境界線の色を設定できます。基本的な構文<TR 境界線...