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

推薦する

JavaScript - Vue でのスロットの使用: スロット

目次Vue でのスロットの使用: slotスコープ付きスロット: テンプレートタグで囲む要約するVu...

高度なクローラー - JS 自動レンダリングのための Scrapy_splash コンポーネントの使用

目次1. scrapy_splash とは何ですか? 2. scrapy_splashの役割3. s...

docker compose を使用して fastDFS ファイル サーバーを構築する方法

前回の記事では、docker compose を使用して FastDfs ファイル サーバーをインス...

Python スクリプトを Ubuntu で直接実行する方法

翻訳プログラムを例に挙げてみます。前回はWindowsでのアプリケーションのパッケージ化についてお話...

MySQL binlog の解析

目次1. binlogの紹介2. Binlog関連のパラメータ3. バイナリログの内容を分析するIV...

Nginx コンテンツ キャッシュと共通パラメータ設定の詳細

使用シナリオ:プロジェクトのページでは、頻繁に変更されず、個別のカスタマイズも伴わない大量のデータを...

1つの記事でNavicat for MySQLの基本を理解する

目次1. データベース操作2. データ型3. バックアップとリカバリ3. 操作4. 上級5. 知識補...

HTTP および HTTP コラボレーション Web サーバー アクセス フロー図

Web サーバーは、独立したドメイン名を持つ複数の Web サイトを構築できるほか、通信経路上のトラ...

魔法のMySQLデッドロックトラブルシューティング記録

背景MySQL のデッドロックについて言えば、私は以前 MySQL のロックに関する基本的な紹介記事...

フレックスレイアウトの互換性の問題の概要

1. W3C バージョンの flex 2009年版フラグ: display: box; または bo...

Linux のメモリ管理とアドレス指定の詳細な紹介

目次1. コンセプトメモリ管理モード住所種別分類例: 2. ページ管理x86 アーキテクチャ 32 ...

JS で単一ファイルコンポーネントを実装する方法

目次概要単一ファイルコンポーネント基本概念シンプルなローダーコンポーネントコンテンツの解析コンポーネ...

WeChatアプレットコンポーネント開発:視覚的な映画座席選択機能

目次1. はじめに1. コンポーネントデータ2. コンポーネントページのレイアウト1. ロゴエリアの...

Baidu サイト検索が https をサポートしていない問題の解決策 (テスト済み)

最近、携帯電話で https が有効になりました。緑色のロックを取得するには、次の問題を解決する必要...