podesigner-sdk
Version:
专业设计器SDK - 完整的图片编辑、文字添加、图层管理解决方案
570 lines (569 loc) • 17.5 kB
JavaScript
var X = Object.defineProperty;
var Y = (c, i, o) => i in c ? X(c, i, { enumerable: !0, configurable: !0, writable: !0, value: o }) : c[i] = o;
var u = (c, i, o) => Y(c, typeof i != "symbol" ? i + "" : i, o);
export * from "podesigner-core";
import { App as q, Frame as H, Image as J, Text as Q } from "leafer-editor";
import { GuideLines as ee } from "leafer-x-guide-line";
import { Ruler as te } from "leafer-x-ruler";
import { ref as v, defineComponent as ne, reactive as le, onMounted as ie, nextTick as oe, onUnmounted as se, watch as re, createElementBlock as d, openBlock as p, createElementVNode as e, Fragment as w, renderList as z, normalizeClass as _, toDisplayString as S, createCommentVNode as x, withModifiers as ae, withDirectives as h, vModelText as y } from "vue";
class ue {
constructor(i, o = {}) {
u(this, "app");
u(this, "elementParent");
u(this, "currentElement", v(null));
u(this, "printImages", v([]));
u(this, "initialized", v(!1));
u(this, "currentFrame");
u(this, "guideLines");
u(this, "ruler");
u(this, "zoom", v(0.25));
// SKU相关
u(this, "skus", /* @__PURE__ */ new Map());
u(this, "currentSkuKey", "");
u(this, "currentSkuFaceKey", "");
u(this, "currentFaceName", "");
u(this, "commonSkuChildren", /* @__PURE__ */ new Map());
u(this, "config");
u(this, "options");
this.config = i, this.options = {
strokeColor: "#F68066",
strokeWidth: 1,
cornerRadius: 0,
...o
};
}
/**
* 初始化编辑器
*/
init() {
this.createApp(), this.setupGuideLines(), this.setupRuler(), this.setupWorkspace(), this.initialized.value = !0;
}
/**
* 创建主应用
*/
createApp() {
this.app = new q({
view: this.config.container,
width: this.config.width || 1200,
height: this.config.height || 1200,
tree: {
type: "editor"
},
editor: {
point: { cornerRadius: this.options.cornerRadius },
middlePoint: {},
rotatePoint: { width: 16, height: 16 },
rect: { dashPattern: [3, 2] },
buttonsDirection: "top",
stroke: this.options.strokeColor,
strokeWidth: this.options.strokeWidth,
buttonsFixed: !0
},
wheel: {
disabled: !0,
preventDefault: !1
}
}), this.app.tree.fill = "transparent";
}
/**
* 设置吸附线
*/
setupGuideLines() {
this.config.enableGuideLines !== !1 && (this.guideLines = new ee(this.app, {
enabled: !0,
alignLineMargin: 10,
alignLineWidth: 1,
signSize: 3,
lineStyle: { type: "dashed" },
alignLineColor: this.options.strokeColor || "#F68066"
}));
}
/**
* 设置标尺
*/
setupRuler() {
this.config.enableRuler !== !1 && (this.ruler = new te(this.app, {
enabled: !0,
theme: "light"
}));
}
/**
* 设置工作区
*/
setupWorkspace() {
const i = new H({
lockRatio: !0,
zIndex: 1,
resizeChildren: !0,
name: "workspace",
fill: {
type: "solid",
color: "#ffffff01"
}
});
this.elementParent = i, this.currentFrame = i, this.app.tree.add(i);
}
/**
* 添加图片元素
*/
addImage(i, o) {
const f = new J({
url: i,
x: o?.x || 0,
y: o?.y || 0,
width: o?.width,
height: o?.height
});
return this.elementParent.add(f), f;
}
/**
* 添加文本元素
*/
addText(i, o) {
const f = new Q({
text: i,
x: o?.x || 0,
y: o?.y || 0,
fontSize: o?.fontSize || 16,
fill: o?.fill || "#000000"
});
return this.elementParent.add(f), f;
}
/**
* 删除元素
*/
removeElement(i) {
this.printImages.value = this.printImages.value.filter((o) => o.id !== i.id), i.remove();
}
/**
* 清空画布
*/
clear() {
this.elementParent && "removeAll" in this.elementParent && this.elementParent.removeAll(), this.printImages.value = [];
}
/**
* 获取所有元素
*/
getAllElements() {
return this.elementParent.children || [];
}
/**
* 设置缩放
*/
setZoom(i) {
this.zoom.value = i, this.app.tree.scale = i;
}
/**
* 获取当前缩放
*/
getZoom() {
return this.zoom.value;
}
/**
* 销毁编辑器
*/
destroy() {
this.app?.destroy(), this.initialized.value = !1;
}
}
const de = { class: "cuzcuz-designer" }, pe = { class: "top-toolbar" }, ce = { class: "toolbar-center" }, ve = ["disabled"], fe = ["disabled"], me = { class: "designer-body" }, he = { class: "left-sidebar" }, ye = { class: "tool-tabs" }, ge = ["onClick"], be = { class: "tool-content" }, ke = {
key: 0,
class: "tool-panel"
}, xe = {
key: 1,
class: "tool-panel"
}, we = { class: "gallery-grid" }, ze = ["onClick"], Ce = ["src", "alt"], _e = {
key: 2,
class: "tool-panel"
}, Se = { class: "text-templates" }, Ie = ["onClick"], Ee = {
key: 3,
class: "tool-panel"
}, Le = { class: "layers-list" }, Te = ["onClick"], Me = ["onClick"], Pe = { class: "canvas-area" }, Re = { class: "canvas-toolbar" }, Ue = { class: "zoom-controls" }, $e = { class: "right-sidebar" }, Ae = {
key: 0,
class: "properties-panel"
}, Fe = { class: "property-group" }, Ve = { class: "property-row" }, De = { class: "property-row" }, Ge = { class: "property-row" }, We = { class: "property-row" }, Oe = {
key: 0,
class: "property-group"
}, Ne = { class: "property-row" }, Ze = { class: "property-row" }, je = { class: "property-row" }, Be = {
key: 1,
class: "no-selection"
}, Ke = /* @__PURE__ */ ne({
__name: "CuzcuzDesigner",
props: {
width: { default: 1200 },
height: { default: 800 },
galleryImages: { default: () => [] },
onSave: {},
onPreview: {}
},
emits: ["save", "preview", "elementSelected"],
setup(c, { emit: i }) {
const o = c, f = i, b = v(), I = v(), g = v("upload"), E = v(""), r = v(null), M = v(!1), P = v(!1);
let a = null;
const R = [
{ key: "upload", label: "上传", icon: "icon-upload" },
{ key: "gallery", label: "图库", icon: "icon-gallery" },
{ key: "text", label: "文字", icon: "icon-text" },
{ key: "layers", label: "图层", icon: "icon-layers" }
], L = v([]), U = [
{ id: "1", text: "标题文字", fontSize: 24, fill: "#000000" },
{ id: "2", text: "正文内容", fontSize: 16, fill: "#333333" },
{ id: "3", text: "装饰文字", fontSize: 18, fill: "#666666" }
], l = le({
x: 0,
y: 0,
width: 0,
height: 0,
text: "",
fontSize: 16,
fill: "#000000"
});
ie(async () => {
await oe(), b.value && (a = new ue({
container: b.value,
width: o.width,
height: o.height,
enableGuideLines: !0,
enableRuler: !0
}), a.init(), $());
}), se(() => {
a?.destroy();
});
function $() {
a && (a.app.editor.on("select", (s) => {
r.value = s.list[0] || null, A(), f("elementSelected", r.value);
}), re(() => a?.getAllElements(), (s) => {
L.value = s?.map((t, n) => ({
id: t.id || `layer-${n}`,
name: t.tag === "Text" ? `文字 ${n + 1}` : `图片 ${n + 1}`,
type: t.tag || "unknown"
})) || [];
}, { deep: !0 }));
}
function A() {
r.value && (l.x = r.value.x || 0, l.y = r.value.y || 0, l.width = r.value.width || 0, l.height = r.value.height || 0, r.value.tag === "Text" && (l.text = r.value.text || "", l.fontSize = r.value.fontSize || 16, l.fill = r.value.fill || "#000000"));
}
function m() {
r.value && (Object.assign(r.value, {
x: l.x,
y: l.y,
width: l.width,
height: l.height
}), r.value.tag === "Text" && Object.assign(r.value, {
text: l.text,
fontSize: l.fontSize,
fill: l.fill
}));
}
function F(s) {
const t = s.target.files;
!t || !a || Array.from(t).forEach((n) => {
const k = URL.createObjectURL(n);
a?.addImage(k, {
x: Math.random() * 300,
y: Math.random() * 300
});
});
}
function V(s) {
a && a.addImage(s.url, {
x: Math.random() * 300,
y: Math.random() * 300
});
}
function D() {
a && a.addText("双击编辑文字", {
x: Math.random() * 300,
y: Math.random() * 300,
fontSize: 16,
fill: "#000000"
});
}
function G(s) {
a && a.addText(s.text, {
x: Math.random() * 300,
y: Math.random() * 300,
fontSize: s.fontSize,
fill: s.fill
});
}
function W(s) {
E.value = s.id;
}
function He(s) {
}
function C(s) {
a?.setZoom(s);
}
function O() {
}
function N() {
}
function Z() {
}
function j() {
const s = {
elements: a?.getAllElements()
// 其他设计数据
};
f("save", s);
}
function B() {
const s = {
elements: a?.getAllElements()
// 其他设计数据
};
f("preview", s);
}
return (s, t) => (p(), d("div", de, [
e("div", pe, [
t[11] || (t[11] = e("div", { class: "logo" }, "CuzcuzDesigner", -1)),
e("div", ce, [
e("button", {
onClick: N,
disabled: !M.value
}, "撤销", 8, ve),
e("button", {
onClick: Z,
disabled: !P.value
}, "重做", 8, fe),
e("button", { onClick: j }, "保存")
]),
e("div", { class: "toolbar-right" }, [
e("button", {
onClick: B,
class: "preview-btn"
}, "预览")
])
]),
e("div", me, [
e("div", he, [
e("div", ye, [
(p(), d(w, null, z(R, (n) => e("div", {
key: n.key,
class: _(["tool-tab", { active: g.value === n.key }]),
onClick: (k) => g.value = n.key
}, [
e("i", {
class: _(n.icon)
}, null, 2),
e("span", null, S(n.label), 1)
], 10, ge)), 64))
]),
e("div", be, [
g.value === "upload" ? (p(), d("div", ke, [
t[12] || (t[12] = e("h3", null, "图片上传", -1)),
e("input", {
type: "file",
onChange: F,
accept: "image/*",
multiple: "",
ref_key: "fileInput",
ref: I,
style: { display: "none" }
}, null, 544),
e("button", {
onClick: t[0] || (t[0] = (n) => I.value?.click()),
class: "upload-btn"
}, " 上传图片 ")
])) : x("", !0),
g.value === "gallery" ? (p(), d("div", xe, [
t[13] || (t[13] = e("h3", null, "图片素材", -1)),
e("div", we, [
(p(!0), d(w, null, z(s.galleryImages, (n) => (p(), d("div", {
key: n.id,
class: "gallery-item",
onClick: (k) => V(n)
}, [
e("img", {
src: n.url,
alt: n.name
}, null, 8, Ce)
], 8, ze))), 128))
])
])) : x("", !0),
g.value === "text" ? (p(), d("div", _e, [
t[14] || (t[14] = e("h3", null, "文字工具", -1)),
e("button", {
onClick: D,
class: "add-text-btn"
}, "添加文字"),
e("div", Se, [
(p(), d(w, null, z(U, (n) => e("div", {
key: n.id,
class: "text-template",
onClick: (k) => G(n)
}, S(n.text), 9, Ie)), 64))
])
])) : x("", !0),
g.value === "layers" ? (p(), d("div", Ee, [
t[15] || (t[15] = e("h3", null, "图层", -1)),
e("div", Le, [
(p(!0), d(w, null, z(L.value, (n, k) => (p(), d("div", {
key: n.id,
class: _(["layer-item", { active: n.id === E.value }]),
onClick: (K) => W(n)
}, [
e("span", null, S(n.name), 1),
e("button", {
onClick: ae((K) => void 0, ["stop"]),
class: "delete-btn"
}, "×", 8, Me)
], 10, Te))), 128))
])
])) : x("", !0)
])
]),
e("div", Pe, [
e("div", Re, [
e("div", Ue, [
e("button", {
onClick: t[1] || (t[1] = (n) => C(0.25))
}, "25%"),
e("button", {
onClick: t[2] || (t[2] = (n) => C(0.5))
}, "50%"),
e("button", {
onClick: t[3] || (t[3] = (n) => C(1))
}, "100%"),
e("button", { onClick: O }, "适应屏幕")
])
]),
e("div", {
ref_key: "canvasContainer",
ref: b,
class: "canvas-container"
}, null, 512)
]),
e("div", $e, [
r.value ? (p(), d("div", Ae, [
t[25] || (t[25] = e("h3", null, "属性设置", -1)),
e("div", Fe, [
t[20] || (t[20] = e("h4", null, "位置和大小", -1)),
e("div", Ve, [
t[16] || (t[16] = e("label", null, "X:", -1)),
h(e("input", {
"onUpdate:modelValue": t[4] || (t[4] = (n) => l.x = n),
onInput: m,
type: "number"
}, null, 544), [
[
y,
l.x,
void 0,
{ number: !0 }
]
])
]),
e("div", De, [
t[17] || (t[17] = e("label", null, "Y:", -1)),
h(e("input", {
"onUpdate:modelValue": t[5] || (t[5] = (n) => l.y = n),
onInput: m,
type: "number"
}, null, 544), [
[
y,
l.y,
void 0,
{ number: !0 }
]
])
]),
e("div", Ge, [
t[18] || (t[18] = e("label", null, "宽度:", -1)),
h(e("input", {
"onUpdate:modelValue": t[6] || (t[6] = (n) => l.width = n),
onInput: m,
type: "number"
}, null, 544), [
[
y,
l.width,
void 0,
{ number: !0 }
]
])
]),
e("div", We, [
t[19] || (t[19] = e("label", null, "高度:", -1)),
h(e("input", {
"onUpdate:modelValue": t[7] || (t[7] = (n) => l.height = n),
onInput: m,
type: "number"
}, null, 544), [
[
y,
l.height,
void 0,
{ number: !0 }
]
])
])
]),
r.value.tag === "Text" ? (p(), d("div", Oe, [
t[24] || (t[24] = e("h4", null, "文字属性", -1)),
e("div", Ne, [
t[21] || (t[21] = e("label", null, "内容:", -1)),
h(e("input", {
"onUpdate:modelValue": t[8] || (t[8] = (n) => l.text = n),
onInput: m,
type: "text"
}, null, 544), [
[y, l.text]
])
]),
e("div", Ze, [
t[22] || (t[22] = e("label", null, "字号:", -1)),
h(e("input", {
"onUpdate:modelValue": t[9] || (t[9] = (n) => l.fontSize = n),
onInput: m,
type: "number"
}, null, 544), [
[
y,
l.fontSize,
void 0,
{ number: !0 }
]
])
]),
e("div", je, [
t[23] || (t[23] = e("label", null, "颜色:", -1)),
h(e("input", {
"onUpdate:modelValue": t[10] || (t[10] = (n) => l.fill = n),
onInput: m,
type: "color"
}, null, 544), [
[y, l.fill]
])
])
])) : x("", !0)
])) : (p(), d("div", Be, t[26] || (t[26] = [
e("p", null, "请选择一个元素来编辑属性", -1)
])))
])
])
]));
}
}), Xe = (c, i) => {
const o = c.__vccOpts || c;
for (const [f, b] of i)
o[f] = b;
return o;
}, T = /* @__PURE__ */ Xe(Ke, [["__scopeId", "data-v-6270eb26"]]), Ye = "1.0.0", qe = (c) => {
c.component("CuzcuzDesigner", T);
}, lt = {
install: qe,
CuzcuzDesigner: T,
VERSION: Ye
};
export {
ue as BaseEditor,
T as CuzcuzDesigner,
ue as CuzcuzEditor,
Ye as VERSION,
lt as default,
qe as install
};
//# sourceMappingURL=index.js.map