inifinte scroll calender

This commit is contained in:
Alexander Mahr 2025-02-15 16:27:55 +01:00
parent cdd0ac3531
commit eef403f0cb

View file

@ -5,6 +5,28 @@
<meta content="width=device-width,initial-scale=1.0" name="viewport"> <meta content="width=device-width,initial-scale=1.0" name="viewport">
</head> </head>
<style> <style>
* {
font-family: sans;
box-sizing:border-box;
}
body,html{
margin:0;
padding:0
}
.infinityScroll{
height:50vh;
overflow:scroll;
border:1px solid red;
position:relative;
}
.space{
background:linear-gradient(white, blue);
height:300%;
opacity:0.5;
}
</style>
<style>
* { * {
font-family: sans; font-family: sans;
} }
@ -20,10 +42,10 @@ body{
background-color:rgba(255,255,255,0.5); background-color:rgba(255,255,255,0.5);
border:2px solid rgba(0,0,0,0.5); border:2px solid rgba(0,0,0,0.5);
border-radius: 10%; border-radius: 10%;
/*margin:5px;*/
min-height: 20vw;
margin:5px; margin:5px;
scroll-snap-align: center; min-height: 20vw;
/*margin:5px;*/
/* scroll-snap-align: center;*/
overflow:hidden; overflow:hidden;
} }
.label{ .label{
@ -32,153 +54,236 @@ body{
font-size:10vw; font-size:10vw;
text-align:center; text-align:center;
} }
.weekdays,.days{
.days{
display: grid; display: grid;
width: 100%; width: 100%;
grid-template-columns: repeat(7, 1fr); grid-template-columns: repeat(7, 1fr);
} }
.weekdays{ .days div {
height: 1cm;
}
.weekdays div, .days div {
text-align:center; text-align:center;
height: 2cm; height: 2cm;
align:content; align:content;
border:1px solid grey;
} }
#mainDiv{
box-sizing:border-box;
margin:0;
/* scroll-snap-type: y mandatory;*/
height:100vh;
overflow:scroll;
border: 1px solid red;
margin:0;
width:100vw;
}
.orig{
border: 3px solid blue;
}
.weekend{
color:red;
background-color:white;
}
</style> </style>
<body> <body>
<div style="margin:0;scroll-snap-type: y mandatory;height:90vh;overflow:scroll;border: 1px solid red"> <div id="mainDiv" class="infinityScroll"></div>
<div class="monthview">
<div class="label">Februar 2025</div>
<div class="weekdays">
<div>Mo</div>
<div>Di</div>
<div>Mi</div>
<div>Do</div>
<div>Fr</div>
<div>Sa</div>
<div>So</div>
</div>
<div class="days">
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
<div>1</div>
</div>
</div>
<div class="monthview">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="monthview">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="monthview">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="monthview">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="monthview">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="monthview">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="monthview">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="monthview">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="monthview">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="monthview">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="monthview">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="monthview">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="monthview">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="monthview">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
<script> <script>
window.addEventListener("error",(error)=>{ // goals:
document.body.innerHTML = "<h1>error</h1><pre>" + // 1. no/huge limits
error.filename + // 1.1. scroll basis is a number (and hence scroll can continues as long as number can increase/descrease)
"\nline:" + error.lineno + // 2. both directions
"\n"+error.message +"</pre>"; // 3. resetability
},false);
// answers
// todo: at center of scroll will be a div containing the number
// todo: onnce scrolling settled, the position reached is the new center
// questions
// Q1: what is to be scrolled ?
// A1: elements that are set to `.infinityScroll` class
// Q2: how is the scroll to infinity implemented (exponential stuff)
window.addEventListener("load",()=>{ window.addEventListener("load",()=>{
var count = localStorage.getItem("app-opened-count")|| 0;
count++; var locale = window.navigator.userLanguage || window.navigator.language || "en";
localStorage.setItem("app-opened-count",count);
var h2 = document.createElement("h2");
h2.textContent = "Javascript works! (app was opened " + count + " times)"; function createMonthView(date = new Date()){
h2.style.animation="wobble 1s ease-in-out 0s 1 forwards normal running" var monthviewDiv = document.createElement("div")
document.body.appendChild(h2); monthviewDiv.className = "monthview";
var labelDiv = document.createElement("div");
labelDiv.textContent = date.toLocaleString(locale,{"month":"long","year":"numeric"})
labelDiv.className = "label"
monthviewDiv.appendChild(labelDiv);
var daysDiv = document.createElement("div");
daysDiv.className="days";
monthviewDiv.appendChild(daysDiv);
// mainDiv.appendChild(monthviewDiv);
monthviewDiv.scrollIntoView();
// var weekendDiv = document.createElement("div");
// weekendDiv.className = "weekend";
// daysDiv.appendChild(weekendDiv);
var day = new Date(date);
day.setDate(1);
while(day.getMonth() == date.getMonth()){
var dayDiv = document.createElement("div");
dayDiv.className = "day";
var column = day.getDay();
column = column == 0 ? 7: column;
if(column>=6){
dayDiv.classList.add("weekend");
}
dayDiv.style.gridColumn = column;
dayDiv.textContent = day.getDate()
daysDiv.appendChild(dayDiv);
day.setDate(day.getDate()+1);
}
return monthviewDiv;
}
function makeInfinityScroll(element){
element.nn=element.nn||{"position":0};
var mdate;
//var before = document.createElement("div");
//var after = document.createElement("div");
//after.style.backgroundColor="blue";
//var center = document.createElement("div");
//before.className = after.className = "space";
//after.style.background="linear-gradient(yellow,red)";
//center.textContent="center "+element.nn.position;
//center.style.border="1px solid red";
//center = createMonthView();
//center.nnindex=0;
//element.appendChild(after);
for(var i = -3; i< 3; i++){
mdate = new Date();
mdate.setMonth(mdate.getMonth()+i);
var nextMonth=createMonthView(mdate);
nextMonth.nnindex=i;
element.appendChild(nextMonth);
nextMonth.classList.add('orig');
}
element.children[3].scrollIntoView({block:"center"});
setTimeout(()=>{
//console.log(element.firstChild,element.firstChild.nnindex);
var beforeind=0;
console.log("fc",element,element.firstChild);
if(element.firstChild.nnindex){
beforeind = element.firstChild.nnindex
}
mdate = new Date();
mdate.setMonth(mdate.getMonth()+beforeind-1);
var newBefore = createMonthView(mdate);
newBefore.nnindex=beforeind-1;
// newBefore.className="space";
console.log("prio "+element.scrollTop,""+element.scrollHeight,element.clientHeight);
// var savscrolltop = element.scrollTop;
element.insertBefore(newBefore,element.firstChild);
// element.scrollTop=savscrolltop-newBefore.clientHeight;
// var beforeind=0;
// console.log("fc",element,element.firstChild);
// if(element.firstChild.nnindex){
// beforeind = element.firstChild.nnindex
// }
// mdate = new Date();
// mdate.setMonth(mdate.getMonth()+beforeind-1);
// var newBefore = createMonthView(mdate);
// newBefore.nnindex=beforeind-1;
//// newBefore.className="space";
// console.log("prio "+element.scrollTop,""+element.scrollHeight,element.clientHeight);
// var savscrolltop = element.scrollTop;
// element.insertBefore(newBefore,element.firstChild);
// element.scrollTop=savscrolltop-newBefore.clientHeight;
//
// console.log("POST "+element.scrollTop,""+element.scrollHeight,element.clientHeight);
//
},100000);
element.addEventListener("scroll",()=>{
if(element.scrollUpdateSchedule!=1){
element.scrollUpdateSchedule=1;
requestAnimationFrame(()=>{
element.scrollUpdateSchedule=0;
//if(element.scrollTop/element.scrollHeight < 0.2){
// console.log("ch",element.clientHeight,element.scrollTop);
if(element.scrollTop < 3* element.clientHeight)
{
console.log(element.scrollTop)
//console.log(element.firstChild,element.firstChild.nnindex);
var beforeind=0;
if(element.firstChild.nnindex){
beforeind = element.firstChild.nnindex
}
mdate = new Date();
mdate.setMonth(mdate.getMonth()+beforeind-1);
var newBefore = createMonthView(mdate);
newBefore.nnindex=beforeind-1;
// newBefore.className="space";
console.log("prio"+element.scrollTop,element.scrollHeight);
element.insertBefore(newBefore,element.firstChild);
console.log("POST"+element.scrollTop,element.scrollHeight);
// while(element.scrollHeight>200*element.clientHeight){
// element.children[element.children.length-1].remove();
// console.log("REMOVED"+element.scrollTop);
// }
}
});
}
},false);
}
/////-- if(element.scrollTop > element.scrollHeight - 4 * element.clientHeight)
/////-- {
/////-- //var afterind = element.children[element.children.length].nnindex || 0;
/////-- var afterind=0;
/////-- if(element.children[element.children.length-1].nnindex){
/////-- afterind = element.children[element.children.length-1].nnindex;
/////-- }
/////-- var newAfter = document.createElement("div");
/////--// newBefore.className="space";
/////-- newAfter.innerHTML=new Array(200).fill("a").map((a,i)=>{return afterind+"-"+i;}).join("<br>");
/////-- newAfter.nnindex=afterind+1;
/////-- console.log("prio"+element.scrollTop);
/////-- element.appendChild(newAfter);
/////-- console.log("POST"+element.scrollTop);
/////--
/////--
/////--// while(element.scrollHeight>200*element.clientHeight){
/////--// element.children[0].remove();
/////--// console.log("REMOVED"+element.scrollTop);
/////--// }
/////--
/////--
/////-- }
/////--// console.log(Date.now(),"Udpate",element.scrollTop);
/////-- console.log(Date.now(),"Udpate",element.scrollTop/element.scrollHeight,"AAA",element.scrollTop,">",element.scrollHeight - 4 * element.clientHeight,element.scrollHeight);
/////-- element.scrollUpdateSchedule=0;
/////-- });
/////-- }
// console.log(element.scrollTop);
// },false);
// }
document.querySelectorAll('.infinityScroll').forEach(makeInfinityScroll);
},false); },false);
window.addEventListener("error",(error)=>{ document.body.innerHTML = "<h1>error</h1><pre>" + error.filename + "\nline:" + error.lineno + "\n"+error.message +"</pre>"; },false);
</script> </script>
<script src='pinch.js'></script>
</body> </body>
</html> </html>