我正在一个允许在Konva JS画布阶段内滚轮滚动的项目中。目的是模仿DIV可以完成的传统CSS溢出滚动。我认为我正在做的问题与扩展舞台有关。
为了简化这个问题,我创建了一个演示,演示在缩放舞台时会发生什么。理想情况下,图像的底部应固定在舞台的底部,就像滚动到此SO页面或任何网站的底部时一样(一旦到达底部,它将停止)。
滚动演示时,您会发现图像并没有停留在舞台底部,而是不断滚动过去。
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/[email protected]/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/[email protected]/konva.min.js"></script>
<title>JS Bin</title>
</head>
<body>
<div id="container"></div>
</body>
</html>