KA Hearth

A small blog where Matthias posted thoughts on things happening around Khan Academy. (Archived) About Me

View the Project on GitHub

How to get better webpage thumbnails

KA webpage thumbnails are generated by HTML2Canvas. This program parses your HTML and draws a picture of it on a canvas. Unfortunely, this is a hard problem, and there are lot of things that can go wrong. This posts has recommendations on how to fix some of the worst issues.

Save your program with a square canvas

KA forces your program’s screenshot into a square, and if it’s not already, then it gets white letterboxing at the bottom. A 600x400 canvas doesn’t fit well into a 200x200 box. Resize the width of the canvas to 400px before hitting save, so the aspect ratio is at least correct.

Have your program send a high-res screenshot

This is arguably the coolest one (if not the most important). Bluebird realized you can make your program send a request to the top page to save itself (if you’ve hit the save button yourself and you’re logged in, of course). He used that, with HTML2Canvas to make a program auto-saver. I adapted that to do something in my opinion much more interesting, save the program at 400x400 instead of 200x200. Now, KA still displays this image at 200x200 in a browse projects setting, but just having this original image higher res helps cut down on text blur and similar artifacts. The following snippet can be added to the end of your HTML project to automatically save a high quality screenshot after you save the program.

<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.js"></script>
<script>
    /* High resolution HTML screenshot snippet (https://matthiassaihttam.github.io/posts/better-html-screenshots) from Matthias and Bluebird. */
    var save = function() {
        html2canvas(document.body, {
            onrendered: function(canvas) {
                window.top.postMessage(canvas.toDataURL();, "https://www.khanacademy.org/");
            },
            allowTaint: false,
            useCORS: true,
            width: 400,
            height: 400
        });
    };
    window.parent.needsThumbnail = true;
    window.parent.addEventListener('message',function(e){
        if (JSON.parse(e.data).screenshot) {
            setTimeout(function () {
                if (window.parent.needsThumbnail) {
                    window.parent.needsThumbnail = true;
                    save();
                }
            }, 1000);
        }
    });
</script>

Without getting into details, the top window requests a screenshot. A second afterwards (to give the normal screenshot request time to process), we generate a high-res screenshot and send that to the top page. window.parent.needsThumbnail is used to ensure we don’t send multiple (since restarting the program would give us multiple message listeners).

Don’t use images

No images can be rendered by HTML2Canvas, for security reasons (implimented by the browser, no bypasses). Work around this by not using images. In my KA Hearth Subscribe page, I used a canvas and drew the logo using the Canvas API. A canvas with p5.js is another good workaround.

Play with CSS rules

HTML2Canvas is just buggy sometimes when applying CSS rules. I know this isn’t super helpful, but take it as a piece of encuragment. It’s possible to “fix” your CSS so that HTML2Canvas renders it better. For example, it ignore backgrounds set on the html element. I find it reliable to set the background on body, and specify a width and height for the body element.

Example

This is better than what the KA Hearth’s screenshot looked like before these tricks (I didn’t undo all the CSS changes I made)

This is the KA Hearth’s screenshot after applying these tricks.

Do the screenshot hack

If you don’t feel like doing these tricks, you can always do the screenshot hack (Lyon’s tutorial program), with a non-animated screenshot of your program to have a perfect image of your program. Of course, you have to repeat this process every time you re-save the program, so I don’t prefer it.