[解決済み] 点の拡大表示(拡大縮小、平行移動の使用)
2022-04-22 08:31:30
質問
HTML 5のキャンバスで、マウスの下にある点をズームできるようにしたい。 グーグルマップ . どうすれば実現できるのでしょうか?
どのように解決するのですか?
ようやく解決しました。
const zoomIntensity = 0.2;
const canvas = document.getElementById("canvas");
let context = canvas.getContext("2d");
const width = 600;
const height = 200;
let scale = 1;
let originx = 0;
let originy = 0;
let visibleWidth = width;
let visibleHeight = height;
function draw(){
// Clear screen to white.
context.fillStyle = "white";
context.fillRect(originx, originy, width/scale, height/scale);
// Draw the black square.
context.fillStyle = "black";
context.fillRect(50, 50, 100, 100);
// Schedule the redraw for the next display refresh.
window.requestAnimationFrame(draw);
}
// Begin the animation loop.
draw();
canvas.onwheel = function (event){
event.preventDefault();
// Get mouse offset.
const mousex = event.clientX - canvas.offsetLeft;
const mousey = event.clientY - canvas.offsetTop;
// Normalize mouse wheel movement to +1 or -1 to avoid unusual jumps.
const wheel = event.deltaY < 0 ? 1 : -1;
// Compute zoom factor.
const zoom = Math.exp(wheel * zoomIntensity);
// Translate so the visible origin is at the context's origin.
context.translate(originx, originy);
// Compute the new visible origin. Originally the mouse is at a
// distance mouse/scale from the corner, we want the point under
// the mouse to remain in the same place after the zoom, but this
// is at mouse/new_scale away from the corner. Therefore we need to
// shift the origin (coordinates of the corner) to account for this.
originx -= mousex/(scale*zoom) - mousex/scale;
originy -= mousey/(scale*zoom) - mousey/scale;
// Scale it (centered around the origin due to the trasnslate above).
context.scale(zoom, zoom);
// Offset the visible origin to it's proper position.
context.translate(-originx, -originy);
// Update scale and others.
scale *= zoom;
visibleWidth = width / scale;
visibleHeight = height / scale;
}
<canvas id="canvas" width="600" height="200"></canvas>
として、キーは タタライズさんご指摘の ズーム後にズームポイント(マウスポインタ)が同じ場所に残るような軸位置を計算することです。
本来、マウスは距離
mouse/scale
にあるため、ズーム後もマウスの下の点が同じ場所にあるようにしたいのですが、この場合、コーナーから
mouse/new_scale
コーナーから離れる。したがって
origin
(コーナーの座標)を考慮する必要があります。
originx -= mousex/(scale*zoom) - mousex/scale;
originy -= mousey/(scale*zoom) - mousey/scale;
scale *= zoom
残りのコードでは、描画コンテキストにスケーリングとトランスレートを適用して、その原点がキャンバスの角と一致するようにする必要があります。
関連
-
[解決済み】React - TypeError: 未定義のプロパティ 'props' を読み取ることができない。
-
[解決済み] textareaのresizableプロパティを無効にするにはどうしたらよいですか?
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] let "と "var "の使い分けは?
-
[解決済み] CSSでcellpaddingとcellspacingを設定する?
-
[解決済み] JavaScriptのオブジェクトをループスルーまたは列挙するにはどうすればよいですか?
-
[解決済み] どのラジオボタンが選択されているかをjQueryで知るにはどうしたらよいですか?
-
[解決済み] リンクのように動作するHTMLボタンを作成する方法
-
[解決済み] React JSX内のループ
-
[解決済み] スクロールバーを隠すが、スクロールはできる状態
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
vueにおけるv-forループオブジェクトのプロパティ
-
Vueのイベント処理とイベントモディファイアの解説
-
[解決済み】Uncaught SyntaxError: JSONの位置0に予期しないトークンuがあります。
-
[解決済み】"フォームが接続されていないため、フォームの送信がキャンセルされました "というエラーの取得について
-
[解決済み】TypeErrorの解決方法。未定義またはヌルをオブジェクトに変換できない
-
[解決済み】ExpressJS : res.redirect()が期待通りに動かない?
-
nodejs unhandledPromiseRejectionWarning メッセージ
-
フロントエンド非同期(アシンク)ソリューション(全ソリューション)
-
JSクリックイベント - Uncaught TypeError: プロパティ 'onclick' に null を設定できません。
-
jq は html ページとデータを動的に分割する。