<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
  <channel>
    <title>#scroll posts — Ben Crowder</title>
    <link>https://bencrowder.net/blog/tag/scroll/</link>
    <atom:link href="https://bencrowder.net/blog/tag/scroll/feed/" rel="self" />
    <description>Feed for blog posts tagged with #scroll.</description>
    <lastBuildDate>Sat, 04 Apr 2026 05:22:16 GMT</lastBuildDate>
    <language>en-US</language>
    <generator>https://bencrowder.net/</generator>

    <item>
      <title>Scroll bleedthrough</title>
      <link>https://bencrowder.net/blog/2025/scroll-bleedthrough/</link>
      <guid isPermaLink="true">https://bencrowder.net/blog/2025/scroll-bleedthrough/</guid>
      <pubDate>Fri, 15 Aug 2025 12:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Ben Crowder]]></dc:creator>
      <description><![CDATA[<p>I figured out how to add a rudimentary dynamic bleedthrough to Scroll (my homemade ebook reader), to make it feel a bit more like real paper — another step toward implementing what I wrote about in my <a href="https://bencrowder.net/blog/2024/1650/">paper EPUBs post</a> last year.</p>
<p><figure>
        <img src="https://cdn.bencrowder.net/blog/2025/08/scroll-bleedthrough.png" alt="Two ebook reader screenshots side by side. The one on the right has a larger font size." title="Two ebook reader screenshots side by side. The one on the right has a larger font size." />
        <figcaption>Two different paper textures/themes and sizes. The screenshot on the right shows how the bleedthrough matches the font size.</figcaption>
      </figure></p>
<p>Initially I considered baking the bleedthrough images onto the backgrounds in advance, but since the font can change (family, size, leading) and I wanted the bleedthrough to match, and since baking (whether directly onto the background textures or as transparent images to be layered on in the client) would mean dozens of permutations and images, I ended up doing this instead:</p>
<ul>
<li>On load, create a new canvas in memory (leaving it out of the DOM)</li>
<li>Get the font information, padding, etc. from the DOM</li>
<li>Render the lines of bleedthrough sample text onto the canvas, at a light opacity, flipping the canvas horizontally and applying a mild blur filter (noting that mobile Safari doesn’t yet support canvas filters, so the blur doesn’t work there)</li>
<li>Export the canvas to a data URL</li>
<li>Set that data URL as a second background image on the content area (where the first background image is the paper texture), with the blending mode set to multiply</li>
</ul>
<p>It’s working fairly well, I think, and seems performant enough so far.</p>
<p>Potential future work:</p>
<ul>
<li>Get the bleedthrough to line up better with the text. While the leading stays more in sync in Firefox, in mobile Safari it drifts off within a few lines and I don’t know why. That said, for some reason I don’t mind that it doesn’t line up, and I’m not sure getting things aligned would be worth all the effort.</li>
<li>Use the text of the book itself instead of a hardcoded sample text. Also may not be worth it, since the bleedthrough is subtle and isn’t meant to actually be read.</li>
</ul><hr class="feed-extra" style="margin-top: 48pt;" /><p class="feed-extra feed-mail"><a href="mailto:ben.crowder@gmail.com?subject=Re%3A%20Scroll bleedthrough">Reply via email</a></p>]]></description>
    </item>
    <item>
      <title>Scroll</title>
      <link>https://bencrowder.net/blog/2024/scroll/</link>
      <guid isPermaLink="true">https://bencrowder.net/blog/2024/scroll/</guid>
      <pubDate>Tue, 15 Oct 2024 12:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Ben Crowder]]></dc:creator>
      <description><![CDATA[<p>A couple weeks ago I built my own EPUB reader called Scroll, and since then have pretty much <a href="https://bencrowder.net/blog/2024/1665/">moved off Marvin</a>. Here’s what Scroll looks like (light and dark themes):</p>
<p><figure>
        <img src="https://cdn.bencrowder.net/blog/2024/10/scroll.png" alt="scroll.png" title="scroll.png" />
        
      </figure></p>
<p>Thus far I’ve read two books using it, and while there are still a few small issues, overall I’m very happy with it. I don’t plan to release it anytime soon, but as a not-even-close-to-the-same-thing substitute, here are some notes:</p>
<ul>
<li>I’d made decent enough progress with epub2pdf that it was usable, but reflowability and theme-changing are nice, and having quick navigation between books is even nicer, and printing a book to PDF in Firefox is slow, and browsers already natively support the HTML that’s inside EPUBs, so I abandoned the PDF route.</li>
<li>Scroll (after both the noun and the verb) is a PWA without a backend. It’s actually just static HTML files: I wrote a script that concatenates all the HTML in an EPUB into one long HTML file, with some processing to fix links and wrap things and bake the table of contents out. Then there’s a little bit of vanilla JS for the reader functionality (saving the debounced current scroll location to localStorage (I wish Safari supported <code>scrollend</code>), restoring it on the <code>pageshow</code> event, calculating pagination, jumping to pages, switching themes, etc.), and another vanilla JS file listing the current books (so that I don’t have to re-build all the other book files when I start reading a new book).</li>
<li>While I said “pagination” above, I’m not actually chunking the book into pages; I’ve chosen to stick with vertical scrolling for now instead of horizontal paging, primarily because being able to make sub-page progress is nicer than I realized. That said, I still want to know how many “pages” I’ve read, so I use the scroll percentage (<code>scrollTop</code> divided by <code>scrollHeight</code>, super simple) multiplied by a rough heuristic of 1,200 characters per page, ignoring whitespace. It’s not perfect but it’s good enough for my needs.</li>
<li>I added a slight blur to the text so that it feels a little less digital. For now I’ve opted against a background image, but I may change my mind about that.</li>
<li>Whenever I add/remove a book, I copy the baked files to a private directory on my server</li>
<li>I’ve saved the root HTML file (which is just a list of the current books, loaded via JS) to my home screen as a PWA</li>
</ul><hr class="feed-extra" style="margin-top: 48pt;" /><p class="feed-extra feed-mail"><a href="mailto:ben.crowder@gmail.com?subject=Re%3A%20Scroll">Reply via email</a></p>]]></description>
    </item>
    
  </channel>
</rss>
