@ammduncan/easel 0.2.15 → 0.2.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/client/viewer.css +12 -0
- package/dist/client/viewer.js +14 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to easel. This project adheres to [Semantic Versioning](https://semver.org/).
|
|
4
4
|
|
|
5
|
+
## 0.2.17 — 2026-05-23
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **`kind: "mockup"` / `"app"` pushes now break out to near-full viewport width.** Two width bounds applied to every push: (1) the wrapper's presentation frame (`max-width: 1400px` + body padding + 880px prose cap), removed by app-fidelity mode since 0.2.13; (2) the feed reading column (`min(94vw, 1600px)` ≈ ~1540px usable), which still squeezed desktop UI recreations. Now app-fidelity cards get `.push--full-bleed` — `width: min(98vw, 1920px)` centred on the viewport — so desktop screens render at real desktop proportions instead of being pinched into the reading column. Presentation pushes stay in the column as before.
|
|
9
|
+
|
|
10
|
+
## 0.2.16 — 2026-05-23
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- **PDF export quality bumped back up after the 0.2.15 size fix landed.** 0.2.15 traded crispness for size (JPEG 0.92 + DPR 2 → ~800 KB per card) — visible JPEG artefacts on type at zoom. Bumped to JPEG quality 1.0 + DPR 4 for the PDF target. Same compression trick (JPEG-in-PDF vs PNG-in-PDF) keeps the file at ~3–8 MB per card instead of the original 300+ MB; the higher quality settings just bring text back to "razor sharp at any zoom" without giving up the size win.
|
|
14
|
+
- PNG export unchanged (still lossless PNG @ DPR 4).
|
|
15
|
+
|
|
5
16
|
## 0.2.15 — 2026-05-23
|
|
6
17
|
|
|
7
18
|
### Fixed
|
package/dist/client/viewer.css
CHANGED
|
@@ -501,6 +501,18 @@ body {
|
|
|
501
501
|
animation: pop-in 360ms cubic-bezier(0.2, 0.7, 0.2, 1);
|
|
502
502
|
}
|
|
503
503
|
|
|
504
|
+
/* App-fidelity pushes (kind: mockup / app) break out of the feed column to
|
|
505
|
+
near-full viewport width, so desktop UI recreations render at real desktop
|
|
506
|
+
proportions instead of being squeezed to the ~1540px reading column.
|
|
507
|
+
margin-left:50% moves the left edge to the column's centre line (which is
|
|
508
|
+
the viewport centre, since .feed is margin:0 auto), then translateX(-50%)
|
|
509
|
+
pulls back by half the element's own width → viewport-centred full bleed. */
|
|
510
|
+
.push--full-bleed {
|
|
511
|
+
width: min(98vw, 1920px);
|
|
512
|
+
margin-left: 50%;
|
|
513
|
+
transform: translateX(-50%);
|
|
514
|
+
}
|
|
515
|
+
|
|
504
516
|
@keyframes pop-in {
|
|
505
517
|
from { opacity: 0; transform: translateY(10px); }
|
|
506
518
|
to { opacity: 1; transform: none; }
|
package/dist/client/viewer.js
CHANGED
|
@@ -426,6 +426,11 @@
|
|
|
426
426
|
const card = document.createElement("article");
|
|
427
427
|
card.className = "push";
|
|
428
428
|
if (opts && opts.fresh) card.classList.add("fresh");
|
|
429
|
+
// App-fidelity pushes (mockup / app) break out of the feed column to
|
|
430
|
+
// near-full viewport width so desktop screens render at real proportions.
|
|
431
|
+
if (push.kind === "mockup" || push.kind === "app") {
|
|
432
|
+
card.classList.add("push--full-bleed");
|
|
433
|
+
}
|
|
429
434
|
card.id = "push-" + push.id;
|
|
430
435
|
|
|
431
436
|
const meta = document.createElement("div");
|
|
@@ -867,18 +872,21 @@ ${body}
|
|
|
867
872
|
document.body ? document.body.scrollHeight : 0,
|
|
868
873
|
);
|
|
869
874
|
// PNG target → lossless PNG @ pixelRatio 4 for crisp standalone files.
|
|
870
|
-
// PDF target → JPEG @ quality 0
|
|
871
|
-
// DCT compression for embedded
|
|
872
|
-
//
|
|
875
|
+
// PDF target → JPEG @ quality 1.0 + pixelRatio 4. PDFs natively use
|
|
876
|
+
// DCT compression for embedded JPEGs, so even at max quality the PDF
|
|
877
|
+
// stays in the ~3-8 MB range for a typical card (vs ~300 MB if we
|
|
878
|
+
// embedded as PNG — see 0.2.15). 1.0 + DPR 4 keeps text razor-sharp
|
|
879
|
+
// at any zoom level; tuned down to 0.92 + DPR 2 in 0.2.15 dropped to
|
|
880
|
+
// ~800 KB but at the cost of visible JPEG artefacts on type.
|
|
873
881
|
var rasterFn = format === "pdf" ? window.htmlToImage.toJpeg : window.htmlToImage.toPng;
|
|
874
882
|
var rasterOpts = {
|
|
875
883
|
backgroundColor: bgColor,
|
|
876
|
-
pixelRatio:
|
|
884
|
+
pixelRatio: 4,
|
|
877
885
|
cacheBust: true,
|
|
878
886
|
width: width,
|
|
879
887
|
height: height,
|
|
880
888
|
};
|
|
881
|
-
if (format === "pdf") rasterOpts.quality = 0
|
|
889
|
+
if (format === "pdf") rasterOpts.quality = 1.0;
|
|
882
890
|
rasterFn(document.documentElement, rasterOpts).then(function(dataUrl){
|
|
883
891
|
parent.postMessage({ type: "easel:image-ready", pushId: pushId, dataUrl: dataUrl, filename: filename, format: format }, "*");
|
|
884
892
|
}).catch(function(err){
|
|
@@ -903,7 +911,7 @@ ${body}
|
|
|
903
911
|
const configScript =
|
|
904
912
|
"<script src='https://cdn.jsdelivr.net/npm/html-to-image@1.11.13/dist/html-to-image.js'></script><script>(function(){function a(c){if(!c)return;if(c.theme==='light'||c.theme==='dark'){document.documentElement.setAttribute('data-theme',c.theme);window.__claudeDisplayTheme=c.theme}if(c.preset==='paper'||c.preset==='aurora'||c.preset==='slate'){document.documentElement.setAttribute('data-preset',c.preset);window.__claudeDisplayPreset=c.preset}if(c.density==='carded'||c.density==='flat'){document.documentElement.setAttribute('data-density',c.density);window.__claudeDisplayDensity=c.density}}a(" +
|
|
905
913
|
JSON.stringify({ theme, preset, density }) +
|
|
906
|
-
");window.addEventListener('message',function(e){if(!e||!e.data)return;if(e.data.type==='easel:config')a(e.data);if(e.data.type==='easel:theme')a({theme:e.data.theme});if(e.data.type==='easel:print'){try{window.print()}catch(_){}}if(e.data.type==='easel:image'){var pid=e.data.pushId;var fn=e.data.filename||'push.png';var fmt=e.data.format==='pdf'?'pdf':'png';var bg=e.data.bgColor||'#ffffff';if(!window.htmlToImage)return;var rfn=fmt==='pdf'?window.htmlToImage.toJpeg:window.htmlToImage.toPng;var ropts={backgroundColor:bg,pixelRatio:
|
|
914
|
+
");window.addEventListener('message',function(e){if(!e||!e.data)return;if(e.data.type==='easel:config')a(e.data);if(e.data.type==='easel:theme')a({theme:e.data.theme});if(e.data.type==='easel:print'){try{window.print()}catch(_){}}if(e.data.type==='easel:image'){var pid=e.data.pushId;var fn=e.data.filename||'push.png';var fmt=e.data.format==='pdf'?'pdf':'png';var bg=e.data.bgColor||'#ffffff';if(!window.htmlToImage)return;var rfn=fmt==='pdf'?window.htmlToImage.toJpeg:window.htmlToImage.toPng;var ropts={backgroundColor:bg,pixelRatio:4,cacheBust:true};if(fmt==='pdf')ropts.quality=1.0;rfn(document.body,ropts).then(function(u){parent.postMessage({type:'easel:image-ready',pushId:pid,dataUrl:u,filename:fn,format:fmt},'*')}).catch(function(err){console.error(err);parent.postMessage({type:'easel:image-error',pushId:pid,format:fmt,message:(err&&err.message)?err.message:String(err)},'*')})}})})();</script>";
|
|
907
915
|
const measureScript = "<script>" + selfMeasureScript(pushId) + "</script>";
|
|
908
916
|
const combined = configScript + measureScript;
|
|
909
917
|
if (/<\/body>/i.test(html)) return html.replace(/<\/body>/i, combined + "</body>");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ammduncan/easel",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.17",
|
|
4
4
|
"description": "A live browser tab for every Claude Code (and MCP) session. The push MCP tool appends HTML cards to a scrolling feed you keep open in split-screen.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|