@framv/image 0.1.0
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/dist/bundle.esm.js +143 -0
- package/dist/bundle.iife.js +18637 -0
- package/dist/cdn.d.ts +3 -0
- package/dist/cdn.d.ts.map +1 -0
- package/dist/cdn.js +3 -0
- package/dist/cdn.js.map +1 -0
- package/dist/element.d.ts +33 -0
- package/dist/element.d.ts.map +1 -0
- package/dist/element.js +160 -0
- package/dist/element.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// src/element.ts
|
|
2
|
+
import { exportElement } from "@framv/core";
|
|
3
|
+
var STYLES = `
|
|
4
|
+
:host {
|
|
5
|
+
display: block;
|
|
6
|
+
position: relative;
|
|
7
|
+
background: #f5f5f5;
|
|
8
|
+
border-radius: 8px;
|
|
9
|
+
overflow: hidden;
|
|
10
|
+
font-family: system-ui, sans-serif;
|
|
11
|
+
}
|
|
12
|
+
.framv-image-stage {
|
|
13
|
+
position: relative;
|
|
14
|
+
width: var(--framv-iw, 800px);
|
|
15
|
+
height: var(--framv-ih, 600px);
|
|
16
|
+
transform-origin: top left;
|
|
17
|
+
overflow: hidden;
|
|
18
|
+
}
|
|
19
|
+
.framv-image-toolbar {
|
|
20
|
+
display: flex; align-items: center; justify-content: center; gap: 8px;
|
|
21
|
+
padding: 8px 12px;
|
|
22
|
+
background: rgba(0,0,0,0.7);
|
|
23
|
+
color: #fff; font: 12px system-ui;
|
|
24
|
+
position: absolute; bottom: 0; left: 0; right: 0;
|
|
25
|
+
opacity: 0; transition: opacity 0.2s;
|
|
26
|
+
z-index: 10;
|
|
27
|
+
}
|
|
28
|
+
:host(:hover) .framv-image-toolbar { opacity: 1; }
|
|
29
|
+
.framv-image-toolbar button {
|
|
30
|
+
background: none; border: 1px solid rgba(255,255,255,0.2);
|
|
31
|
+
color: inherit; cursor: pointer;
|
|
32
|
+
padding: 4px 10px; font: inherit; border-radius: 4px;
|
|
33
|
+
}
|
|
34
|
+
.framv-image-toolbar button:hover { background: rgba(255,255,255,0.15); }
|
|
35
|
+
.framv-image-toolbar .btn-export {
|
|
36
|
+
border-color: #ff79c6; color: #ff79c6;
|
|
37
|
+
}
|
|
38
|
+
.framv-image-badge {
|
|
39
|
+
position: absolute; top: 8px; right: 8px;
|
|
40
|
+
background: rgba(0,0,0,0.6); color: #fff;
|
|
41
|
+
padding: 2px 8px; border-radius: 4px;
|
|
42
|
+
font: 11px system-ui; letter-spacing: 0.5px;
|
|
43
|
+
text-transform: uppercase; z-index: 5;
|
|
44
|
+
}
|
|
45
|
+
`;
|
|
46
|
+
var FramvImageElement = class extends HTMLElement {
|
|
47
|
+
static observedAttributes = ["format"];
|
|
48
|
+
_stage;
|
|
49
|
+
_exportBtn;
|
|
50
|
+
_shadow;
|
|
51
|
+
_exporting = false;
|
|
52
|
+
constructor() {
|
|
53
|
+
super();
|
|
54
|
+
this._shadow = this.attachShadow({ mode: "open" });
|
|
55
|
+
}
|
|
56
|
+
get width() {
|
|
57
|
+
return parseInt(this.getAttribute("width") ?? "800");
|
|
58
|
+
}
|
|
59
|
+
get height() {
|
|
60
|
+
return parseInt(this.getAttribute("height") ?? "600");
|
|
61
|
+
}
|
|
62
|
+
get format() {
|
|
63
|
+
return this.getAttribute("format") ?? "png";
|
|
64
|
+
}
|
|
65
|
+
get quality() {
|
|
66
|
+
return parseFloat(this.getAttribute("quality") ?? "0.95");
|
|
67
|
+
}
|
|
68
|
+
connectedCallback() {
|
|
69
|
+
const w = this.width;
|
|
70
|
+
const h = this.height;
|
|
71
|
+
this._shadow.innerHTML = `
|
|
72
|
+
<style>${STYLES}</style>
|
|
73
|
+
<div class="framv-image-badge">framv image \xB7 ${this.format.toUpperCase()} \xB7 ${w}x${h}</div>
|
|
74
|
+
<div class="framv-image-stage" style="--framv-iw:${w}px;--framv-ih:${h}px">
|
|
75
|
+
<slot></slot>
|
|
76
|
+
</div>
|
|
77
|
+
<div class="framv-image-toolbar">
|
|
78
|
+
<span style="opacity:0.6;font-size:11px">${w}x${h}</span>
|
|
79
|
+
<button class="btn-export">\u2B07 Export ${this.format.toUpperCase()}</button>
|
|
80
|
+
</div>
|
|
81
|
+
`;
|
|
82
|
+
this._stage = this._shadow.querySelector(".framv-image-stage");
|
|
83
|
+
this._exportBtn = this._shadow.querySelector(".btn-export");
|
|
84
|
+
this._adaptSize();
|
|
85
|
+
this._exportBtn.addEventListener("click", () => this._export());
|
|
86
|
+
new ResizeObserver(() => this._adaptSize()).observe(this);
|
|
87
|
+
}
|
|
88
|
+
attributeChangedCallback(name) {
|
|
89
|
+
if (name === "format" && this._stage) {
|
|
90
|
+
const badge = this._shadow.querySelector(".framv-image-badge");
|
|
91
|
+
if (badge) badge.textContent = `framv image \xB7 ${this.format.toUpperCase()} \xB7 ${this.width}x${this.height}`;
|
|
92
|
+
this._exportBtn.textContent = `\u2B07 Export ${this.format.toUpperCase()}`;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
_adaptSize() {
|
|
96
|
+
const w = this.width;
|
|
97
|
+
const h = this.height;
|
|
98
|
+
const containerW = this.clientWidth || w;
|
|
99
|
+
const scale = Math.min(containerW / w, 1);
|
|
100
|
+
this._stage.style.transform = `scale(${scale})`;
|
|
101
|
+
this.style.minHeight = `${h * scale}px`;
|
|
102
|
+
}
|
|
103
|
+
async _export() {
|
|
104
|
+
if (this._exporting) return;
|
|
105
|
+
this._exporting = true;
|
|
106
|
+
const container = document.createElement("div");
|
|
107
|
+
container.style.width = `${this.width}px`;
|
|
108
|
+
container.style.height = `${this.height}px`;
|
|
109
|
+
container.style.position = "relative";
|
|
110
|
+
container.style.overflow = "hidden";
|
|
111
|
+
Array.from(this.children).forEach((child) => container.appendChild(child.cloneNode(true)));
|
|
112
|
+
try {
|
|
113
|
+
const blob = await exportElement({
|
|
114
|
+
element: container,
|
|
115
|
+
settings: {
|
|
116
|
+
format: this.format,
|
|
117
|
+
width: this.width,
|
|
118
|
+
height: this.height,
|
|
119
|
+
quality: this.quality,
|
|
120
|
+
time: 0
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
const url = URL.createObjectURL(blob);
|
|
124
|
+
const a = document.createElement("a");
|
|
125
|
+
a.href = url;
|
|
126
|
+
a.download = `framv-image.${this.format}`;
|
|
127
|
+
this._shadow.appendChild(a);
|
|
128
|
+
a.click();
|
|
129
|
+
a.remove();
|
|
130
|
+
URL.revokeObjectURL(url);
|
|
131
|
+
} catch (err) {
|
|
132
|
+
console.error("Export failed:", err);
|
|
133
|
+
} finally {
|
|
134
|
+
this._exporting = false;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
if (!customElements.get("framv-image")) {
|
|
139
|
+
customElements.define("framv-image", FramvImageElement);
|
|
140
|
+
}
|
|
141
|
+
export {
|
|
142
|
+
FramvImageElement
|
|
143
|
+
};
|