diff --git a/canvas.html b/canvas.html index 34a671b..e3bdeac 100644 --- a/canvas.html +++ b/canvas.html @@ -46,6 +46,7 @@ .anchor { cursor: pointer; + /* TODO investigate scroll-snap-align: center; having scroll-snap-type: y proximity; on html*/ } /*Filenames with code blocks: https://stackoverflow.com/a/58199362*/ @@ -87,38 +88,40 @@ background-color: rgba(255, 255, 255, 0.8); } - .anchor{ + .anchor { position: relative; } - .anchor.active:not(.playing)::before{ - content:'⏵'; + .anchor.active:not(.playing)::before { + content: '⏵'; position: absolute; width: 40px; height: 40px; - background:gray; + background: gray; left: calc(50% - 20px); top: calc(50% - 20px); vertical-align: middle; line-height: 35px; border-radius: 5px; - color:white; + color: white; } - .anchor.active:not(.playing):hover::before{ - background:black + + .anchor.active:not(.playing):hover::before { + background: black } - .anchor.playing:hover::before{ - content:'⏸︎'; + + .anchor.playing:hover::before { + content: '⏸︎'; position: absolute; width: 40px; height: 40px; - background:black; + background: black; left: calc(50% - 20px); top: calc(50% - 20px); vertical-align: middle; line-height: 35px; border-radius: 5px; - color:white; + color: white; } @@ -152,6 +155,10 @@ div.controls{display:none !important;}` ); + function easeInOutSine(x) { + return -(Math.cos(Math.PI * x) - 1) / 2; + + } function easeInOutQuart(x) { return x < 0.5 ? 8 * x * x * x * x : 1 - Math.pow(-2 * x + 2, 4) / 2; @@ -224,6 +231,10 @@ prev = offset } + + const sticky_dy = 200; + const intro_outro_dy = window.innerHeight + sticky_dy; + let source_pos, target_pos, source_scale, target_scale, source_color, target_color, source_x_offset, target_x_offset; const x_column_width = window.innerWidth - document.body.getBoundingClientRect().width + 200; // for some reason the 200 is neccesary @@ -232,8 +243,11 @@ const fit_scale = x_column_width / (canvasCenter[0] * 1.7) + let sticky_start = true; + let sticky_end = true; + if (prev === null) { - prev = [next[0] - window.innerHeight / 2, null] + prev = [next[0] - intro_outro_dy, null] source_scale = fit_scale target_scale = .45 @@ -246,8 +260,10 @@ source_x_offset = x_center_map; target_x_offset = x_center_column; + sticky_start = false; // no sticky before first item + } else if (next === null) { - next = [prev[0] + window.innerHeight / 2, null] + next = [prev[0] + intro_outro_dy, null] source_scale = .45 target_scale = fit_scale @@ -260,6 +276,8 @@ source_x_offset = x_center_column; target_x_offset = x_center_map; + sticky_end = false; // no sticky after last item + } else { source_pos = centerPoints[prev[1]] target_pos = centerPoints[next[1]] @@ -273,9 +291,25 @@ } - const t = Math.min(1, Math.max(0, (center_y - prev[0]) / (next[0] - prev[0]))) - t_ease = easeInOutQuart(t) - // t_ease = easeInOutBack(t) + const t_old = Math.min(1, Math.max(0, (center_y - prev[0]) / (next[0] - prev[0]))) + const s = (center_y - prev[0] - (sticky_dy * sticky_start)) / (next[0] - prev[0] - (sticky_start + sticky_end) * sticky_dy); + const t = Math.min(1, Math.max(0, s)) + // console.log(t_old, t) + t_ease = easeInOutSine(t) + // t_ease = easeInOutQuart(t) // use this if not snapping + + let sticky_offset = 0; + if (s > 0 && s < 1) { + // scrolling from one item to the next + sticky_offset = t_ease * (sticky_start + sticky_end) * sticky_dy - (sticky_dy * sticky_start); + } else { + // sticky item + if (sticky_end && center_y > next[0] - sticky_dy) { + sticky_offset = sticky_dy - (center_y - next[0] + sticky_dy) + } else if (sticky_start && s <= 0) { + sticky_offset = ((center_y - prev[0]) / sticky_dy) * (- sticky_dy); + } + } const dx = target_pos[0] - source_pos[0]; const dy = target_pos[1] - source_pos[1]; @@ -288,7 +322,7 @@ scale = source_scale + t_ease * ds; x_offset = (target_x_offset - source_x_offset) * t_ease + source_x_offset x = -1 * (source_pos[0] + dx * t_ease) * scale + x_offset; - y = -1 * (source_pos[1] + dy * t_ease) * scale + window.innerHeight / 2; + y = -1 * (source_pos[1] + dy * t_ease) * scale + window.innerHeight / 2 + sticky_offset; const color = (target_color - source_color) * t_ease + source_color // sheet.rules[0].style.setProperty('--override-color', `rgba(${color},${color},${color},0.7)`); @@ -350,7 +384,7 @@ let options = { // root: document.querySelector("#scrollArea"), // viewport by default - rootMargin: `${-Math.floor((window.innerHeight-10) / 2)}px 0px`, //"0px", + rootMargin: `${-Math.floor((window.innerHeight - 10) / 2)}px 0px`, //"0px", threshold: 0, }; diff --git a/paper.css b/paper.css index 4c10616..2305598 100644 --- a/paper.css +++ b/paper.css @@ -3,7 +3,7 @@ html { font-family: sans-serif; font-size: 20px; color: #1a1a1a; - background-color: #fafafa; + background-color: white; } body { margin: 0 50px 0 auto;