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

推薦する

Robots.txtの詳細な紹介

robots.txt の基本的な紹介Robots.txt はプレーンテキスト ファイルであり、Web...

変数が空かどうかを判定するシェルの方法の概要

シェルで変数が空かどうかを判断する方法シェルプログラミングでは、パラメータのエラーチェック項目に、変...

ウェブページ内の 2 つのボックス モデル (W3C ボックス モデル、IE ボックス モデル)

Web ページ ボックス モデルには 2 種類あります。 1: 標準 W3C ボックス モデル。2:...

CSS 配送先住所平行四辺形線スタイルの例コード

コードは次のようになります。 // 配送先住所の平行四辺形の線のスタイル <view clas...

Javascriptで戦略パターンを実装する方法

目次概要コードの実装要約する概要戦略パターンは、JavaScript デザイン パターンにおける動作...

jsはシンプルな英語-中国語辞書を実装します

この記事では、参考までに、簡単な英中辞典を実装するためのjsの具体的なコードを紹介します。具体的な内...

MySQL InnoDB ReplicaSet の簡単な紹介

目次01 InnoDBレプリカセットの紹介02 InnoDBレプリカセットの制限03 導入前に知って...

表には表示したい境界コードが表示されます

テーブルの共通プロパティ基本的な属性は、width (幅)、height (高さ)、border (...

WeChat アプレット ピッカー マルチ列セレクター (モード = multiSelector)

目次1. 効果図(複数列) 2. 通常セレクター: mode = selector、複数列セレクター...

一般的なMysql DDL操作の概要

図書館管理ライブラリを作成する データベースを作成します [存在しない場合] ライブラリ名;ライブラ...

Xiaomi公式サイトの登録・ログイン機能を模倣するJavaScript

目次まずページレイアウトを構築する必要がありますJS関数1 JS関数2 JS関数3 JS関数4効果図...

MySQLクエリキャッシュの簡単な使い方の詳細な説明

目次1. クエリキャッシュの実装プロセス2. クエリキャッシュを構成する3. クエリキャッシュを有効...

CSS でフローティングにより親要素の高さが崩れる問題を解決するいくつかの方法

以前は、フロートはレイアウトによく使用されていましたが、フローティングレイアウトを使用すると親要素の...

JS正規RegExpオブジェクトについての簡単な説明

目次1. RegExpオブジェクト2. 文法2.1 定義2.2 修飾子2.3 角括弧2.4 メタ文字...

MySQL 学習のまとめ: InnoDB ストレージ エンジンのアーキテクチャ設計の予備的な理解

1. ストレージエンジン前のセクションでは、SQL 実行プランは、エグゼキュータ コンポーネントがス...