About this teleprompter
A small, dependency-free tool for one job: scrolling your script at a speed you control, so you can read to camera instead of memorising lines. No account, no upload, and the optional recording never leaves your device either.
Why it exists
Most free teleprompter pages are either a thin wrapper around a paid app, or a genuinely simple scroller buried under sign-up walls and ads that load before the tool does. This is the second thing without the first two problems: paste a script, drag two sliders, press Play. The one feature that adds real complexity — optional local recording — is opt-in and clearly separated from the scrolling itself, so declining it (or having your browser deny camera access) never breaks the actual teleprompter.
How the scroll engine is built
- Time-based, not frame-based. Every call to
requestAnimationFramecomputesoffset = speed × elapsedSecondsfrom a real clock (performance.now()), then sets a singletransform: translateY()on the text. It is never driven by counting frames or by a CSS@keyframesanimation, so a slow device that drops frames still lands at the correct position on the next frame it does render, instead of drifting behind. - Pause and resume preserve elapsed time exactly. Pausing adds the time since the last resume into an accumulator and cancels the animation frame; resuming restarts the clock from that accumulator. There is no separate "position" variable to fall out of sync with the timer — position is always re-derived from elapsed time.
- The scroll ceiling is measured, not assumed. The maximum offset is recalculated every frame from the text block's actual
scrollHeightagainst the viewport'sclientHeight, so changing the font size or resizing the window mid-read is reflected immediately rather than requiring a restart. - Mirroring is one CSS transform. The mirror toggle sets
scaleX(-1)on the same element the scroll transform is written to; because a horizontal flip and a vertical translation don't interact, combining them is safe and needs no separate wrapper element. - The script itself is built with
createElement,createTextNodeand real<br>elements — neverinnerHTML— so pasting arbitrary text, including text that looks like HTML, can never be interpreted as markup.
How the optional recording is built
Turning on Record yourself while reading calls navigator.mediaDevices.getUserMedia({ video: true, audio: true }) — the same browser API every video-call app uses — which is why your browser shows its own permission prompt the first time, and why this page cannot see or influence that prompt in any way. Once you allow it, the stream feeds a small local preview and, if you press Start recording, a MediaRecorder instance writes encoded video chunks into memory as they arrive. Stopping the recorder assembles those chunks into a single Blob, which becomes a downloadable object URL — a file that exists only in your browser's memory and on your device once you save it. There is no upload step anywhere in that chain, because there is no server endpoint on this page for a video to go to.
Camera and microphone tracks are stopped explicitly — when you turn the toggle off, when you leave the teleprompter stage, and on pagehide — so the camera's hardware indicator light does not stay lit after you are done, and no stream keeps running in a background tab.
Scope and honesty about limits
This is a scrolling text tool with an optional camera recorder attached, not a production teleprompter suite. It has no script library, no cloud sync, no multi-camera switching, and no editing timeline — closing the tab loses whatever you pasted unless you keep your own copy. The recording format comes from your browser's own MediaRecorder implementation (typically WebM in Chromium and Firefox, MP4 in Safari); this page does not transcode, trim or otherwise touch the file beyond assembling the recorded chunks. Fullscreen and recording support both vary across mobile browsers more than desktop ones — where a control reports it isn't supported, the scrolling itself is unaffected.
If you find a case where the scroll drifts, jumps, or the mirror looks wrong through an actual beam-splitter rig, that's worth reporting — see contact.