8pt

OCR Scan Card

OCR Scan Card•Motion
Overview

On the left a receipt photo is swept by a blue scanning light again and again, with recognized text appearing line by line in highlight boxes; on the right a search box types keywords in turn and the results list highlights matches. It shows that text inside images is searchable too.

Taken from the page template Suitie Mac Clipboard History Website. Use it on its own, or combine it with the other components from the same template to rebuild the full page.

Plain HTML, CSS and a little vanilla JS, with no framework dependency. Copy the prompt into Claude Code, Cursor, Trae or Codex and the model adds OCR Scan Card to your project in your colors.

Where to use it

Scroll, hover and entrance motion that gives a page rhythm; animation uses only transform and opacity.

Install

With Builder, install it with the 8pt CLI or call it directly from an editor connected to 8pt MCP.

$ npm i -g @8pt-dev/cli && 8pt add ocr-scan-card
mcp › Use 8pt MCP to call get_component("ocr-scan-card")

Code

Source for OCR Scan Card. Motion uses only transform and opacity and respects the Reduce motion setting.

<div class="x-ocr"><div class="x-ocr__shot"><img src="https://8pt.dev/api/media/a889a9ff944e5c79e2b1c3af.webp" alt="一张小票照片" draggable="false"><span class="x-ocr__beam" aria-hidden="true"></span><span class="x-ocr__box" style="--x:24%;--y:14%;--w:40%;--h:5%;--d:.2s"></span><span class="x-ocr__box" style="--x:20%;--y:32%;--w:52%;--h:5%;--d:.5s"></span><span class="x-ocr__box x-ocr__box--hit" style="--x:20%;--y:45%;--w:56%;--h:5%;--d:.8s"></span><span class="x-ocr__box" style="--x:20%;--y:58%;--w:48%;--h:5%;--d:1.1s"></span><span class="x-ocr__box" style="--x:20%;--y:80%;--w:58%;--h:5%;--d:1.4s"></span></div><div class="x-ocr__side"><label class="x-ocr__search"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="6.5"/><path d="M16 16l4 4"/></svg><span class="x-ocr__q"></span><i class="x-ocr__caret"></i></label><ul class="x-ocr__res"><li class="x-ocr__item is-hit"><span class="x-ocr__th x-ocr__th--a"></span><span><b>咖啡小票</b><small>识别到 <mark>燕麦拿铁</mark> · 刚刚</small></span></li><li class="x-ocr__item"><span class="x-ocr__th x-ocr__th--b"></span><span><b>白板照片</b><small>周会待办与排期</small></span></li><li class="x-ocr__item"><span class="x-ocr__th x-ocr__th--c"></span><span><b>报错截图</b><small>构建失败的提示信息</small></span></li></ul><span class="x-ocr__tag"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 8V6a2 2 0 0 1 2-2h2"/><path d="M16 4h2a2 2 0 0 1 2 2v2"/><path d="M20 16v2a2 2 0 0 1-2 2h-2"/><path d="M8 20H6a2 2 0 0 1-2-2v-2"/><path d="M8 9.5h8"/><path d="M8 12.5h8"/><path d="M8 15.5h5"/></svg>截图与图片里的字,也能搜到</span></div></div>
.x-ocr{box-sizing:border-box;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:28px;align-items:center;width:100%;max-width:980px;margin:0 auto;padding:32px;border-radius:30px;background:#f3f3f5;color:#0b0b0f;font-family:"PingFang SC","Noto Sans SC","Noto Sans CJK SC","Microsoft YaHei",system-ui,sans-serif;-webkit-font-smoothing:antialiased}.x-ocr *,.x-ocr *::before,.x-ocr *::after{box-sizing:border-box}.x-ocr svg{width:1em;height:1em;flex:none}.x-ocr__shot{position:relative;aspect-ratio:510/600;max-height:560px;margin:0 auto;width:100%;border-radius:22px;overflow:hidden;box-shadow:0 30px 60px -30px rgba(0,0,0,.35)}.x-ocr__shot img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}.x-ocr__beam{position:absolute;left:0;right:0;top:0;height:22%;background:linear-gradient(180deg,transparent,rgba(61,123,255,.28) 80%,rgba(61,123,255,.9) 100%);animation:x-ocr-scan 3.6s cubic-bezier(.45,0,.55,1) infinite}@keyframes x-ocr-scan{0%{transform:translateY(-100%)}70%,100%{transform:translateY(460%)}}.x-ocr__box{position:absolute;left:var(--x);top:var(--y);width:var(--w);height:var(--h);border-radius:6px;background:rgba(61,123,255,.14);box-shadow:inset 0 0 0 1.5px rgba(61,123,255,.7);opacity:0;animation:x-ocr-box 3.6s var(--d) ease-out infinite}.x-ocr__box--hit{background:rgba(255,200,40,.35);box-shadow:inset 0 0 0 2px #f5a623}@keyframes x-ocr-box{0%{opacity:0;transform:scale(.96)}10%,80%{opacity:1;transform:none}100%{opacity:0}}.x-ocr__side{display:flex;flex-direction:column;gap:14px}.x-ocr__search{display:flex;align-items:center;gap:10px;height:52px;padding:0 18px;border-radius:16px;background:#fff;color:#8a8a93;font-size:18px;box-shadow:0 1px 0 rgba(0,0,0,.04),0 10px 30px -18px rgba(0,0,0,.3)}.x-ocr__q{color:#0b0b0f;font-size:16px;font-weight:600}.x-ocr__caret{width:2px;height:20px;margin-left:-6px;background:#3d7bff;animation:x-ocr-blink 1s steps(1) infinite}@keyframes x-ocr-blink{50%{opacity:0}}.x-ocr__res{display:grid;gap:8px;margin:0;padding:0;list-style:none}.x-ocr__item{display:flex;align-items:center;gap:12px;padding:12px;border-radius:16px;background:#fff;opacity:.6;transition:opacity .3s,box-shadow .3s,transform .3s}.x-ocr__item b{display:block;font-size:14px;font-weight:600}.x-ocr__item small{display:block;margin-top:2px;font-size:12px;color:#7a7a84}.x-ocr__item mark{padding:0 3px;border-radius:4px;background:#ffe08a;color:inherit}.x-ocr__item.is-hit{opacity:1;box-shadow:0 0 0 2px #3d7bff;transform:translateX(4px)}.x-ocr__th{width:44px;height:44px;flex:none;border-radius:11px;background:url(https://8pt.dev/api/media/a889a9ff944e5c79e2b1c3af.webp) center/cover}.x-ocr__th--b{background:linear-gradient(135deg,#f1f5ff,#cfdcf5)}.x-ocr__th--c{background:linear-gradient(135deg,#2b2b31,#5a1f24)}.x-ocr__tag{display:inline-flex;align-items:center;gap:8px;align-self:flex-start;height:34px;padding:0 14px;border-radius:99px;background:#e6e6ea;font-size:13px;color:#3a3a42}@media (max-width:720px){.x-ocr{grid-template-columns:1fr;padding:18px}.x-ocr__shot{max-height:300px;aspect-ratio:auto;height:300px}}@media (prefers-reduced-motion:reduce){.x-ocr__beam,.x-ocr__box,.x-ocr__caret{animation:none}.x-ocr__box{opacity:1}.x-ocr__item{transition:none}}
(root) => {
  const q = root.querySelector('.x-ocr__q');
  const items = [...root.querySelectorAll('.x-ocr__item')];
  const words = ['拿铁', '周会', '构建失败'];
  let w = 0, i = 0, dir = 1, t = 0;
  const step = () => {
    const word = words[w];
    i += dir;
    q.textContent = word.slice(0, i);
    if (dir > 0 && i === word.length) { items.forEach((x, k) => x.classList.toggle('is-hit', k === w)); dir = -1; t = setTimeout(step, 1800); return; }
    if (dir < 0 && i === 0) { dir = 1; w = (w + 1) % words.length; t = setTimeout(step, 400); return; }
    t = setTimeout(step, dir > 0 ? 220 : 90);
…
Subscribe to Builder to see the full source.See pricing

Other components from this template

View all

Sky Hero Headline

Device Price Card

Two Column FAQ

Notch Pill Nav

Clip Library Window

Inline Shortcut Typer

More motion components

View all

Chaos Versus Ship Split

Integration Tile Grid

Infra Tab Showcase

Ticker CTA Band

Chrome Outline Wordmark

Prompt Hub Diagram

Dual Row Quote Marquee

Ask AI Composer

More components

View all

Tabbed Logo Testimonial

Dot Matrix Glow Hero

Dotted Globe Features

Segmented Pricing Tiers

Live Deploy Bento

Floating Tile CTA Banner

Aurora Prompt Hero

Trio Capability Cards

Keep exploring