ホームページ  >  記事  >  ウェブフロントエンド  >  キャンバス内のスティッキーポイントをズームインまたはズームアウトする

キャンバス内のスティッキーポイントをズームインまたはズームアウトする

WBOY
WBOYオリジナル
2024-07-18 05:56:57903ブラウズ

スティックポイントを使用したズームイン/ズームアウトは、Figma などのデザインツールやビルダーツールでよく見られる使用例です。このブログでは、JavaScript、HTML、CSS でそれを処理するための基本的なアルゴリズムを紹介します。

デモ

デモンストレーション

ステップバイステップでコーディングする

1.コンテナとスケーラブルなアイテムを作成します

<div id="app">
      <div class="parent">
        <div class="scalable-child"></div>
      </div>
</div>
.scalable-child {
  width: 300px;
  height: 300px;
  position: relative;
  top: 0;
  left: 0;
  pointer-events: none;
  transform-origin: left top;
  background-image: url('https://cdn4.vectorstock.com/i/1000x1000/17/58/caro-pattern-background-vector-2261758.jpg');
  background-size: contain;
}
.parent {
  position: relative;
  background-color: white;
  width: 100vw;
  height: 100vh;
}

この例では、クラス「scalable-child」を持つスケーラブルなアイテムとして div を使用し、そのコンテナーはクラス「parent」を持つ div です。
一部のプロパティについてはご注意ください:

  • 上、左: 0 がデフォルトの位置です

  • ポインタ イベント: なし。親にイベントを追加するため、ポインタ イベント !== なしの場合、アルゴリズムは失敗します。

  • Transform-origin: 左上、位置を計算するための座標原点を作成します

2.ホイールイベントリスナーを追加

const parent = document.querySelector('.parent');
const child = document.querySelector('.scalable-child');

parent.addEventListener('wheel', wheelEventHandler, {
  passive: false,
  capture: true,
});

WheelEvent を使用して、ズームイン、ズームアウト、および子の移動を処理します

注: この例はトラックパッドのみを示しています。 (Ctrl +、Ctr -) などのホットキーやマウスのイベントも処理する必要があります。

let left = 0;
let top = 0;
let scale = 1;

const wheelEventHandler = (e) => {
  e.preventDefault();
  // Handle zoom with touch pad and hot key.
  const isZooming = e.ctrlKey || e.metaKey;
  let newValues = {};
  if (isZooming) {
    newValues = calculateOnZooming(e, scale, left, top);
  } else {
    newValues = calculateOnMoving(e, scale, left, top);
  }

  left = newValues.newLeft;
  top = newValues.newTop;
  scale = newValues.newScale;

  Object.assign(child.style, {
    transform: `scale(${scale})`,
    left: `${left}px`,
    top: `${top}px`,
  });
};

まず、子要素がズームまたは移動しているかどうかを確認するための isZooming 変数があります。

次に、子要素の新しい位置とスケールを計算します。 left、top、scale は温度変数として使用されます。

そして、次は 2 つの計算関数にアルゴリズムを集中させます:

3.ズーム時に計算

const calculateOnZooming = (e, oldScale, oldLeft, oldTop) => {
  let newScale = oldScale - e.deltaY * oldScale * 0.01;
  newScale = Math.max(newScale, 0.1);
  const newLeft = oldLeft - (e.offsetX - oldLeft) * (newScale / scale - 1);
  const newTop = oldTop - (e.offsetY - oldTop) * (newScale / scale - 1);
  return {
    newScale,
    newLeft,
    newTop,
  };
};

ズームすると、wheelEvent はスケール比として deltaY を返し、それを使用して newScale を計算できます

  • デルタY> 0 =>ズームアウト

  • デルタY
    0 =>ズームイン

    スケーリング速度を制御するための detalScale = e.deltaY * oldScale * 0.01

newLeft 変数と newTop 変数の計算方法をさらに理解するために、以下の画像を見てみましょう:

Image description

マウスが A 点にあるときに子のズームインを開始します。その時点で、いくつかの値を取得できます:
  • e.offsetX: マウスから親の左端までの距離
  • e.offsetY: マウスから親の上端までの距離
  • left: 現在の子の左スタイル値
  • top: 現在の子のトップスタイル値


子はスケール比からスケール' 比にスケールされ、点 A は A' に進みます。

したがって、A ポイントを (親と) スティッキーにするには、deltaX と deltaY を計算し、正確に px で子を元に戻す必要があります。


detalX = x’ - x
= x * (スケール’ / スケール) - x
= x * (スケール’ / スケール - 1)

= (e.offsetX - 左) * (スケール’ / スケール - 1)


詳細Y = y’ - y
= y * (スケール’ / スケール) - y
= y * (スケール’ / スケール - 1)

= (e.offsetY - トップ) * (スケール’ / スケール - 1)


newLeft = left - detalX

newTop = トップ - 詳細

4.移動計算

const calculateOnMoving = (e, oldScale, oldLeft, oldTop) => {
  return {
    newLeft: oldLeft - e.deltaX * 2,
    newTop: oldTop - e.deltaY * 2,
    newScale: oldScale,
  };
};

移動イベントでは、newLeft と newTop の値のみを計算する必要があります。また、各デルタ値を *2 して速度も向上させます。


私たちが対処する必要があるのはこれだけです。お役に立てば幸いです。ご覧いただきありがとうございます!

ここで完全なソース コードを表示できます。

以上がキャンバス内のスティッキーポイントをズームインまたはズームアウトするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。