col*_*lxi 8 javascript html5 canvas zoom scale
我正在努力实现使用Vanilla Javascript的画布缩放(在鼠标滚轮上),但没有成功.
当滚轮转动时,必须在鼠标坐标上应用缩放.之前有人问过,但是我的情况完全不同,考虑到我不能使用canvasContext.translate,offsetX并且offsetY必须保持其绝对表示的值(不是缩放的)
我真的很感激一些亮点.
在下面的代码片段中,我提供了当前和功能失调的实现.当您放大和缩小保持相同的缩放坐标时,您将看到它是如何工作的,但只要您将鼠标移动到新坐标(当缩放!= 1时)并继续缩放时,新的偏移就会出错.
// initiate variabks : canvas ref, offsets, scale...
const context = document.getElementById('c').getContext('2d');
let scale = 1;
let scaleFactor = 0.2;
let offsetX=0;
let offsetY=0;
// Handle mousenwheel zoom
context.canvas.onwheel= function(e){
e.preventDefault();
// calculate scale direction 6 new value
let direction = e.deltaY > 0 ? 1 : -1;
scale += scaleFactor * direction;
// calculatethe new offsets (unscaled values)
offsetX = e.offsetX - (e.offsetX / scale);
offsetY = e.offsetY - (e.offsetY / scale);
// apply new scale
context.setTransform(1, 0, 0, 1, 0, 0);
context.scale(scale, scale);
}
// clear canvas and draw two boxes
// NO CHANGES CAN BE DONE IN THIS FUNCTION
function render(){
context.beginPath();
context.clearRect(0,0,context.canvas.width/scale,context.canvas.height/scale);
context.rect(100-offsetX,50-offsetY,50,50);
context.rect(200-offsetX,50-offsetY,50,50);
context.stroke();
document.getElementById("info").innerHTML=`
Scale : ${scale} <br>
Offets : ${ Math.round(offsetX) + ' , ' + Math.round(offsetY)} <br>
`;
requestAnimationFrame( render );
}
render()Run Code Online (Sandbox Code Playgroud)
<canvas id="c" width="350" height="150" style="border: 1px solid red;"></canvas>
<div id="info"></div>Run Code Online (Sandbox Code Playgroud)
我终于得到了... 画布任意坐标缩放而不使用context.translate()
我附上我的解决方案,有一点奖励:画布平移(光标键滚动).我希望对某人有用.
// initiate variables : canvas ref, offsets, scale...
const context = document.getElementById('c').getContext('2d');
let scale = 1;
let scaleFactor = 0.2;
let scrollX = 0;
let scrollY = 0;
let info = document.getElementById("info");
// Handle mousenwheel zoom
context.canvas.onwheel = function(e){
e.preventDefault();
let previousScale= scale;
// calculate scale direction 6 new scale value
let direction = e.deltaY > 0 ? 1 : -1;
scale += scaleFactor * direction;
// calculate the new scroll values
scrollX += ( e.offsetX / previousScale ) - (e.offsetX / scale);
scrollY += ( e.offsetY / previousScale ) - ( e.offsetY / scale);
// apply new scale in a non acumulative way
context.setTransform(1, 0, 0, 1, 0, 0);
context.scale(scale, scale);
}
// clear canvas and draw two boxes
function render(){
context.beginPath();
context.clearRect(0,0,context.canvas.width/scale, context.canvas.height/scale);
context.rect(100-scrollX,50-scrollY,50,50);
context.rect(200-scrollX,50-scrollY,50,50);
context.stroke();
info.innerHTML=`
Scale : ${scale} <br>
Scroll: ${scrollX},${scrollY} <br>
`
requestAnimationFrame( render );
}
// handlencursor keys to move scroll
window.onkeydown = function(event){
event.preventDefault();
if(event.keyCode == 37) scrollX -=10;
else if(event.keyCode == 39) scrollX +=10;
else if(event.keyCode == 38) scrollY -=10;
else if(event.keyCode == 40) scrollY +=10;
};
context.canvas.focus()
render()Run Code Online (Sandbox Code Playgroud)
<canvas id="c" width="400" height="150" style="border: 1px solid red;" tabindex="1"></canvas>
<div id="info"></div>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
635 次 |
| 最近记录: |