首先,我想指出的是,從你的代碼,它看起來像你正在聽的畫布上的「滾輪」事件。如here所述,'鼠標滾輪'事件是非標準的並且不符合標準。因此,聽到它時,您最終會得到混合的結果。 「滾動」事件幾乎在每個平臺上都可用,並且可能是捕獲用戶輸入的更好途徑。
就您的問題而言,您正在尋找您正在尋找的行爲的正確軌道,但您錯過了一步。
當您在畫布上下文對象上調用scale
時,其行爲非常簡單。從左上角(0,0)開始,該方法根據提供的因子縮放畫布的點。假設你有一個10×10的畫布,並有1,1個黑點。如果畫布在兩個軸上縮放2倍,則0,0點將保持在相同位置,但是點1,1將是縮放前2,2點的位置。
爲了實現您正在尋找的'縮放'行爲,縮放後的上下文必須爲翻譯爲,以便參考點佔據與縮放前相同的物理位置。在你的情況下,參考點是當執行縮放操作時用戶光標所在的點。
幸運的是,畫布上下文對象提供了一個將上下文的原點相對於畫布的0,0點移動的方法。要翻譯它的正確ammount的,你必須:
- 計算比例因子
- 變焦
- 除以距離之前從畫布原點的鼠標光標的距離由值
翻譯的由來
因爲你的代碼並不表示你的HTML的結構,下面我帶了一些意見和僞標誌着它向您展示如何實現這個算法:
//You'll need to get a reference to your canvas in order to calculate the relative position of
//the cursor to its top-left corner, and save it to a variable that is in scope inside of your
//event handler function
var canvas = document.getElementById('id_of_your_canvas');
//We're also going to set up a little helper function for returning an object indicating
//the position of the top left corner of your canvas element (or any other element)
function getElementOrigin(el){
var boundingBox = el.getBoundingClientRect();
return { x: boundingBox.left, y: boundingbox.top};
}
function OnMouseWheel (event) {
//you probably want to prevent scrolling from happening or from bubbling so:
event.preventDefault();
event.stopPropagation();
var delta = event.wheelDelta ? event.wheelDelta/40 : event.detail ? -event.detail : 0;
var canvasCorner = getElementOrigin(canvas)
//JavaScript doesn't offer a 'vector' or 'point' class natively but we don't need them
var mousePosition = {x: event.clientX, y: event.clientY};
var diff = {x: mousePostion.x - canvasCorner.x, y: mousePosition.y - canvasCorner.y};
var scaleFactor = 1.1;
if (delta) {
var factor = Math.pow(scaleFactor,delta);
var transX = (-1/factor) * diff.x;
var transY = (-1/factor) * diff.y;
context.scale(factor,factor);
context.translate(transX, transY);
}
}
0,0可能是左上角? - 這將是我的猜測 – 2014-11-14 19:25:23