From 1f790bc00273f655870e9016e90a9c44d5df4419 Mon Sep 17 00:00:00 2001 From: KJ Shanks Date: Fri, 18 Dec 2020 13:51:14 -0500 Subject: [PATCH] Update scroll functionality to handle resized screen and wrapped text --- desktop/sources/links/main.css | 2 +- desktop/sources/scripts/go.js | 33 ++++++++++++++++++++----------- desktop/sources/scripts/reader.js | 2 +- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/desktop/sources/links/main.css b/desktop/sources/links/main.css index 49b5f32..4fdc3a9 100644 --- a/desktop/sources/links/main.css +++ b/desktop/sources/links/main.css @@ -34,7 +34,7 @@ body stats ul { height: 100%; display: inline; overflow: scroll; white-space: no body stats li { display: inline; margin-right: 10px; } body stats li.active { text-decoration: underline; font-weight: bold; } -body textarea { font-family: var(--font-family); padding: 30px 15px 0; height: calc(100vh - 90px); display: block; width: 80ch; position: fixed; left: 25vw; font-size: var(--font-size); line-height: var(--line-height); resize: none; background: transparent; overflow: auto; max-width: 90%; transition: left 200ms; margin-left:-15px; } +body textarea { box-sizing: border-box; font-family: var(--font-family); padding: 30px 15px 0; height: calc(100vh - 60px); display: block; width: 80ch; position: fixed; left: 25vw; font-size: var(--font-size); line-height: var(--line-height); resize: none; background: transparent; overflow: auto; max-width: 90%; transition: left 200ms; margin-left:-15px; } body div { left: 25vw; max-width:600px; width:80ch; line-height: var(--line-height); font-family: var(--font-family); font-size: var(--font-size); white-space: pre-wrap; word-wrap:break-word; } body drag { display: block;width: 100vw;height: 30px;position: fixed;top: 0px;-webkit-user-select: none;-webkit-app-region: drag; background-color: transparent !important;} diff --git a/desktop/sources/scripts/go.js b/desktop/sources/scripts/go.js index c6216c3..b0e3ef0 100644 --- a/desktop/sources/scripts/go.js +++ b/desktop/sources/scripts/go.js @@ -27,6 +27,8 @@ function Go () { } this.to = function (from, to, scroll = true) { + if (scroll) this.scroll_to(from, to) + if (left.textarea_el.setSelectionRange) { left.textarea_el.setSelectionRange(from, to) } else if (left.textarea_el.createTextRange) { @@ -36,11 +38,6 @@ function Go () { range.moveStart('character', from) range.select() } - left.textarea_el.focus() - - if (scroll) { - this.scroll_to(from, to) - } return from === -1 ? null : from } @@ -54,12 +51,26 @@ function Go () { } this.scroll_to = function (from, to) { - const textVal = left.textarea_el.value - const div = document.createElement('div') - div.innerHTML = textVal.slice(0, to) - document.body.appendChild(div) - animateScrollTo(left.textarea_el, div.offsetHeight - 60, 200) - div.remove() + const ta = left.textarea_el + const text = ta.value + const sliceText = text.slice(0, to) + const scrollFrom = ta.scrollTop + const taPaddingTop = 30 + + // Textarea hack to get the proper scroll position of the selection + // This relies on textarea behavior where it scrolls to the bottom when focused + ta.scrollTop = 0 + ta.blur() + ta.style.paddingTop = `${ta.clientHeight}px` + ta.value = sliceText + ta.focus() + const scrollTo = ta.scrollTop - 60 + ta.style.paddingTop = `${taPaddingTop}px` + ta.value = text + + // Reset scroll position and scroll to new position + ta.scrollTop = scrollFrom + animateScrollTo(ta, scrollTo, 200) } function animateScrollTo (element, to, duration) { diff --git a/desktop/sources/scripts/reader.js b/desktop/sources/scripts/reader.js index 4c44179..a4cc469 100644 --- a/desktop/sources/scripts/reader.js +++ b/desktop/sources/scripts/reader.js @@ -49,8 +49,8 @@ function Reader () { left.reader.index += 1 const range = words.splice(0, left.reader.index).join(' ').length - left.select(left.reader.segment.from, left.reader.segment.from + range) left.go.scroll_to(0, left.reader.segment.from + range) + left.select(left.reader.segment.from, left.reader.segment.from + range) setTimeout(left.reader.run, left.reader.speed) }