我正在使用 HTML 和 JavaScript 在画布中开发一个可拖动的圆形容器,但每次用户在容器内滚动时,我很难让滚动条自动更新。尽管容器正确滚动,但滚动条并未实时反映这些变化。如何解决这个问题以确保滚动条与圆形容器内内容的移动正确同步?
const canvas = document.getElementById('canvas');
const container = document.getElementById('container');
const ctx = canvas.getContext('2d');
const resizeCanvas = () => {
canvas.height = container.clientHeight;
canvas.width = container.clientHeight;
}
let containerHeight, containerScrollHeight,scrolled, docHeight, scrollPer;
const render = () => {
containerHeight = container.offsetHeight;
containerScrollHeight = container.scrollHeight;
scrolled = container.scrollTop;
scrollPer = scrolled / (containerScrollHeight - containerHeight);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.lineWidth = 5;
makeArc('#666666', canvas.width / 2, canvas.height / 2, canvas.height / 2.05, 0, 2 * Math.PI);
makeArc('#000000', canvas.width / 2, canvas.height / 2, canvas.height / 2.05, ((container.scrollTop - 0.1) * 2) * Math.PI, (container.scrollTop * 2) * Math.PI);
};
const makeArc = (color, one, two, three, four, five) => {
ctx.beginPath();
ctx.strokeStyle = color;
ctx.arc(one, two, three, four, five);
ctx.stroke();
};
resizeCanvas();
render();
window.addEventListener('resize', function() {
resizeCanvas();
render();
});
container.addEventListener('scroll', render);
:root{
--item-size: 40dvw;
}
*{
box-sizing: content-box;
}
html {
scrollbar-width:none;
-ms-overflow-style:none;
overflow-y:-moz-scrollbars-none
}
.hide-scrollbar::-webkit-scrollbar {
width:0;
display: none
}
body{
display: flex;
flex-wrap: wrap;
flex-direction: column;
align-content: center;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: rgba(185, 212, 235, 0.698);
}
section{
border-radius: 50%;
width: calc(var(--item-size) + 5.9px);
height: calc(var(--item-size) + 5.9px);
gap: 2px;
position: relative;
overflow: hidden;
}
main{
display: grid;
grid-auto-flow: row;
width: 100%;
height: 100%;
gap: 2px;
overflow: scroll;
scrollbar-width: none;
scroll-snap-type: y mandatory;
scroll-behavior: auto;
position: relative;
box-sizing: border-box;
}
main>.item{
background-color: aliceblue;
border: 3px;
border-color: black;
border-style: dashed;
border-radius: 50%;
aspect-ratio: 1;
width: 100%;
box-sizing: border-box;
display: flex;
flex-wrap: wrap;
align-content: center;
justify-content: center;
scroll-snap-align: start;
}
.canvas{
position: absolute;
right: 0px; top: 0px;
border-radius: 50%;
pointer-events: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Hi</h1>
<section class="scrollbar" id="container">
<main>
<div class="item">
<p>hola</p>
</div>
<div class="item">
<p>hola</p>
</div>
<div class="item">
<p>hola</p>
</div>
</main>
<canvas width="100" height="100" class="canvas" id="canvas"></canvas>
</section>
</body>
</html>
你的问题不太清楚...
我将重点关注我认为是您的问题,您想要在我眼中创建的“滚动”是随着用户在页面中滚动而增长的圆弧,但实际上什么也没有发生。
您的
container.addEventListener('scroll', render)
未触发
我将使用:
document.addEventListener('wheel', scroll);
参见下面的工作原型
const canvas = document.getElementById('canvas');
const container = document.getElementById('container');
const ctx = canvas.getContext('2d');
let scrollValue = 0.2
const resizeCanvas = () => {
canvas.height = container.clientHeight;
canvas.width = container.clientHeight;
render();
}
const scroll = (e) => {
scrollValue += (e.deltaY > 0)? 0.5: -0.5
render()
}
const render = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.lineWidth = 5;
makeArc('gray', canvas.width/2, canvas.height/2, canvas.height/2.05, 0, 2 * Math.PI);
makeArc('red' , canvas.width/2, canvas.height/2, canvas.height/2.05, 0, scrollValue);
};
const makeArc = (color, one, two, three, four, five) => {
ctx.beginPath();
ctx.strokeStyle = color;
ctx.arc(one, two, three, four, five);
ctx.stroke();
};
resizeCanvas();
window.addEventListener('resize', resizeCanvas);
document.addEventListener('wheel', scroll);
:root {
--item-size: 40dvw;
}
* {
box-sizing: content-box;
}
html {
scrollbar-width: none;
-ms-overflow-style: none;
overflow-y: -moz-scrollbars-none
}
.hide-scrollbar::-webkit-scrollbar {
width: 0;
display: none
}
body {
display: flex;
flex-wrap: wrap;
flex-direction: column;
align-content: center;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: rgba(185, 212, 235, 0.698);
}
section {
border-radius: 50%;
width: calc(var(--item-size) + 5.9px);
height: calc(var(--item-size) + 5.9px);
gap: 2px;
position: relative;
overflow: hidden;
}
main {
display: grid;
grid-auto-flow: row;
width: 100%;
height: 100%;
gap: 2px;
overflow: scroll;
scrollbar-width: none;
scroll-snap-type: y mandatory;
scroll-behavior: auto;
position: relative;
box-sizing: border-box;
}
main>.item {
background-color: aliceblue;
border: 3px;
border-color: black;
border-style: dashed;
border-radius: 50%;
aspect-ratio: 1;
width: 100%;
box-sizing: border-box;
display: flex;
flex-wrap: wrap;
align-content: center;
justify-content: center;
scroll-snap-align: start;
}
.canvas {
position: absolute;
right: 0px;
top: 0px;
border-radius: 50%;
pointer-events: none;
}
<body>
<section class="scrollbar" id="container">
<main>
<div class="item">
<p>aaa</p>
</div>
<div class="item">
<p>bbb</p>
</div>
<div class="item">
<p>ccc</p>
</div>
<div class="item">
<p>ddd</p>
</div>
<div class="item">
<p>eee</p>
</div>
<div class="item">
<p>fff</p>
</div>
</main>
<canvas width="100" height="100" class="canvas" id="canvas"></canvas>
</section>
</body>