我正在开发一个允许鼠标滚轮在 Konva JS Canvas 阶段内滚动的项目。目标是模仿可以使用 DIV 完成的传统 CSS 溢出滚动。我相信我所做的事情的问题与缩放舞台有关。
为了简化这个问题,我创建了一个演示,展示了缩放舞台时会发生什么。理想情况下,图像的底部将锚定到舞台的底部,就像滚动到此页面或任何网站的底部时一样(一旦到达底部,它就会停止)。
当您滚动演示时,您会发现图像并没有停在舞台底部,而是不断滚动过去。
var stageWidth = window.innerWidth;
var stageHeight = 300;
var viewportPadding = 10;
var stage = new Konva.Stage({
x: 0,
y: 0,
container: 'container',
width: stageWidth,
height: stageHeight
});
var zoom = .5;
stage.scaleX(zoom);
stage.scaleY(zoom);
stage.draw();
var layer = new Konva.Layer();
var background = new Konva.Rect({
x: 0,
y: 0,
fill: 'red',
width: stageWidth,
height: stageHeight,
});
var img = new Image();
img.onload = function() {
var imageWidth = stageWidth - (viewportPadding * 2);
var ratio = imageWidth / this.naturalWidth;
var imageHeight = this.naturalHeight * ratio;
var floorImage = new Konva.Image({
x: viewportPadding,
y: viewportPadding,
image: img,
width: imageWidth,
height: imageHeight,
});
layer.add(floorImage);
// update height of background
background.height(imageHeight + (viewportPadding * 2));
stage.draw();
};
img.src = 'https://dspncdn.com/a1/media/originals/fa/06/eb/fa06ebac2b188e309cff600400d34e41.jpg';
layer.add(background);
stage.add(layer);
stage.draw();
stage.on('wheel', function(e) {
var deltaX = e.evt.deltaX;
var deltaY = e.evt.deltaY;
var scrollStep = Math.abs(deltaY * 1);
// Scrolling up
if (deltaY < 0) {
var yPos = layer.y() + scrollStep;
if (yPos > 0) {
yPos = 0;
}
layer.y(yPos);
layer.batchDraw();
// Scrolling down
} else if (deltaY > 0) {
var yPos = layer.y() - scrollStep;
var remainingDistance = background.height() - stage.height();
if (yPos < -remainingDistance) {
yPos = -remainingDistance;
}
layer.y(yPos);
layer.batchDraw();
}
});
html,body {
margin:0;
}
#container {
border: 2px solid red;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://unpkg.com/konva@4.0.17/konva.min.js"></script>
<title>JS Bin</title>
</head>
<body>
<div id="container"></div>
</body>
</html>
最佳答案
您只需根据舞台的比例调整剩余滚动即可:
var remainingDistance = background.height() - stage.height() / stage.scaleY();
var stageWidth = window.innerWidth;
var stageHeight = 300;
var viewportPadding = 10;
var stage = new Konva.Stage({
x: 0,
y: 0,
container: 'container',
width: stageWidth,
height: stageHeight
});
var zoom = 0.5;
stage.scaleX(zoom);
stage.scaleY(zoom);
stage.draw();
var layer = new Konva.Layer();
var background = new Konva.Rect({
x: 0,
y: 0,
fill: 'red',
width: stageWidth,
height: stageHeight,
});
var img = new Image();
img.onload = function() {
var imageWidth = stageWidth - (viewportPadding * 2);
var ratio = imageWidth / this.naturalWidth;
var imageHeight = this.naturalHeight * ratio;
var floorImage = new Konva.Image({
x: viewportPadding,
y: viewportPadding,
image: img,
width: imageWidth,
height: imageHeight,
});
layer.add(floorImage);
// update height of background
background.height(imageHeight + (viewportPadding * 2));
stage.draw();
};
img.src = 'https://dspncdn.com/a1/media/originals/fa/06/eb/fa06ebac2b188e309cff600400d34e41.jpg';
layer.add(background);
stage.add(layer);
stage.draw();
stage.on('wheel', function(e) {
var deltaX = e.evt.deltaX;
var deltaY = e.evt.deltaY;
var scrollStep = Math.abs(deltaY * 1);
// Scrolling up
if (deltaY < 0) {
var yPos = layer.y() + scrollStep;
if (yPos > 0) {
yPos = 0;
}
layer.y(yPos);
layer.batchDraw();
// Scrolling down
} else if (deltaY > 0) {
var yPos = layer.y() - scrollStep;
var remainingDistance = background.height() - stage.height() / stage.scaleY();
if (yPos < -remainingDistance) {
yPos = -remainingDistance;
}
layer.y(yPos);
layer.batchDraw();
}
});
html,body {
margin:0;
}
#container {
border: 2px solid red;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://unpkg.com/konva@4.0.17/konva.min.js"></script>
<title>JS Bin</title>
</head>
<body>
<div id="container"></div>
</body>
</html>
关于javascript - 将鼠标滚轮滚动添加到 Konva JS Stage,并在最外层对象的开头和结尾处使用 anchor ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58826271/