LoginSignup
2
0

More than 1 year has passed since last update.

素の JavaScript で Google Map 風の拡大縮小機能を作る

Last updated at Posted at 2022-09-27

やりたいこと

  • google mapのように「スクロールしたとき、マウスの位置を中心に拡大する」機能を作りたい。
  • 画像の拡大縮小ライブラリは存在するが、それ以外のDOMでも同様に動くようにしたい

コード

html

<!-- boardが枠 / boxが拡大される本体 -->
<div id="board">
    <div id="box" >
        <img id="image" src="image.png">
        <div id="dom"></div>
    </div>
</div>

css

#board {
    width:500px;
    height:500px;
    border:3px solid green;
    overflow: hidden;
}
#box{
    width:500px;
    height: 500px;
    transition-duration: 200ms;
}
#image{
    width: 500px;
    height: 500px;
}
#dom{
    position: absolute;
    top:30px;
    left:30px;
    width: 30px;
    height: 30px;
    background:red;
}

この辺は適当に自分の作りたいものに合わせて

javascript

const board=document.getElementById('board')
const box=document.getElementById('box')

let scale=1
let pos={
    x:0,
    y:0,
}

box.style.transformOrigin="0 0"

board.addEventListener('wheel',(event)=>{
    event.preventDefault()

    let mousePos={
        x:event.clientX,
        y:event.clientY,
    }

    if(event.deltaY>0){
        scale*=0.9
        pos.x=pos.x*0.9+mousePos.x*0.1
        pos.y=pos.y*0.9+mousePos.y*0.1

    }else if(event.deltaY<0){
        scale*=1.1
        pos.x=pos.x*1.1-mousePos.x*0.1
        pos.y=pos.y*1.1-mousePos.y*0.1
    }
    
    box.style.transform=`translate(${pos.x}px,${pos.y}px) scale(${scale})`

},{passive:false})

何をやっているか

wheelイベント

マウスホイールを動かしたときに発火するイベントが存在する。
event.clientXでイベント発火時のマウスの位置(これは拡大率にかかわらず、画面左端からの距離に依存する)が取得できる
event.deltaYでページの移動幅(?)のような数値が出る→これが正なら拡大/負なら縮小と判断できる
 
これを利用して、現在の拡大率を保持しておく→イベント発火→deltaYの正負に基づいて拡大率を調整→要素のstyle.transform属性を書き換え の流れでホイールと同時に要素を拡大できる

位置調整

計算のしやすさの観点から、transformOriginを (0,0) (左上)にして話を進める
純粋に「ホイールの分だけscaleを大きくする」実装をすると、左上を中心に拡大されてしまい、想定と違う動きをする
image.png

そこで、scaleと同時にtranslateを使ってマウスの位置が拡大の中心になるように(無理やり)調節する
image.png

具体的な計算式について

拡大によって生じるずれは、要素端からのマウスの位置の1.1倍(今回の場合)なので、要素のtranslateXを保持しておき、event.clientXからtranslateXを引いたものに1.1をかけた値を補正値として、translateX分に加算すればよい
image.png

あとはごにょごにょ計算すると次の式が出てくる。

要素のtranslateX = 要素のtranslateX*1.1 - マウスのevent.clientX * 0.1

縮小及びyについても同様の考えで式を出せば完成

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0