Files

457 lines
16 KiB
JavaScript

export const SVG = {
edit: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 3a2.85 2.85 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z"></path></svg>`,
move: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M12 3v6m0 6v6m9-9h-6m-6 0H3"></path></svg>`,
alignLeft: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="4" y1="6" x2="20" y2="6"></line><line x1="4" y1="12" x2="14" y2="12"></line><line x1="4" y1="18" x2="18" y2="18"></line></svg>`,
alignCenter: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="4" y1="6" x2="20" y2="6"></line><line x1="8" y1="12" x2="16" y2="12"></line><line x1="6" y1="18" x2="18" y2="18"></line></svg>`,
alignRight: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="4" y1="6" x2="20" y2="6"></line><line x1="10" y1="12" x2="20" y2="12"></line><line x1="6" y1="18" x2="20" y2="18"></line></svg>`,
bold: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 4h6a4 4 0 0 1 4 4 4 4 0 0 1-4 4H7z"></path><path d="M7 12h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H7z"></path></svg>`,
italic: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="17" y1="4" x2="7" y2="20"></line><line x1="14" y1="4" x2="20" y2="4"></line><line x1="4" y1="20" x2="10" y2="20"></line></svg>`,
font: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 4v16m-4-4h8"></path><line x1="6" y1="4" x2="18" y2="4"></line></svg>`,
fontSize: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8 4v16"></path><path d="M4 4h8"></path><path d="M4 20h8"></path><path d="M16 10v10"></path><path d="M13 10h6"></path><path d="M13 20h6"></path></svg>`,
shadow: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="4" width="12" height="12" rx="2"></rect><rect x="8" y="8" width="12" height="12" rx="2" stroke-dasharray="3"></rect></svg>`,
outline: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="6" y="6" width="12" height="12" rx="2"></rect><rect x="9" y="9" width="6" height="6" rx="1"></rect></svg>`,
rotate: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3A9 9 0 1 0 21 12h-3"></path><path d="M18 4v4h4"></path></svg>`,
reflectX: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v18"></path><path d="M15 7l-3-4-3 4"></path><path d="M15 17l-3 4-3-4"></path></svg>`,
reflectY: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12h18"></path><path d="M7 9l-4 3 4 3"></path><path d="M17 9l4 3-4 3"></path></svg>`,
frame: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"></rect><line x1="3" y1="12" x2="21" y2="12"></line><line x1="12" y1="3" x2="12" y2="21"></line></svg>`,
color: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3h.01"></path><path d="M19 12h.01"></path><path d="M5 12h.01"></path><path d="M12 19h.01"></path><path d="M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5"></path></svg>`
};
export const WIDGET_CONFIG = {
text: ["STRING", { multiline: true, default: "", hidden: true }],
font_size: ["INT", { default: 32, min: 8, max: 128, hidden: true }],
text_color: ["STRING", { default: "#FFFFFF", hidden: true }],
text_gradient_start: ["STRING", { default: "", hidden: true }],
text_gradient_end: ["STRING", { default: "", hidden: true }],
text_gradient_angle: ["INT", { default: 0, min: 0, max: 360, hidden: true }],
background_color: ["STRING", { default: "#000000", hidden: true }],
width: ["INT", { hidden: true }],
height: ["INT", { hidden: true }],
position_x: ["FLOAT", { default: 256, min: 0, max: 512, step: 1, precision: 0, label: "X Position", hidden: true }],
position_y: ["FLOAT", { default: 256, min: 0, max: 512, step: 1, precision: 0, label: "Y Position", hidden: true }],
rotation: ["FLOAT", { default: 0.0, min: -360.0, max: 360.0, hidden: true }],
is_bold: ["BOOLEAN", { default: false, hidden: true }],
is_italic: ["BOOLEAN", { default: false, hidden: true }],
text_align: ["STRING", { default: "center", hidden: true }],
font_family: ["STRING", { default: "Arial", hidden: true }],
text_shadow: ["BOOLEAN", { default: false, hidden: true }],
text_outline: ["BOOLEAN", { default: false, hidden: true }],
outline_color: ["STRING", { default: "#000000", hidden: true }],
outline_width: ["INT", { default: 3, min: 1, max: 20, hidden: true }],
opacity: ["FLOAT", { default: 1.0, min: 0.0, max: 1.0, hidden: true }],
background_visible: ["BOOLEAN", { default: true, hidden: true }],
reflect_x: ["BOOLEAN", { default: false, hidden: true }],
reflect_y: ["BOOLEAN", { default: false, hidden: true }],
canvas_image: ["STRING", { default: "", hidden: true }]
};
export const TOOLBAR_TOOLS = [
{
icon: SVG.edit,
tooltip: "Edit Text",
action: 'editText'
},
{ type: 'divider' },
{
icon: SVG.move,
tooltip: "Set Position",
action: 'openMoveDialog'
},
{ type: 'divider' },
{
icon: SVG.alignLeft,
tooltip: "Align Left",
action: 'alignLeft'
},
{
icon: SVG.alignCenter,
tooltip: "Center",
action: 'alignCenter'
},
{
icon: SVG.alignRight,
tooltip: "Align Right",
action: 'alignRight'
},
{ type: 'divider' },
{
icon: SVG.bold,
tooltip: "Bold",
action: 'toggleBold'
},
{
icon: SVG.italic,
tooltip: "Italic",
action: 'toggleItalic'
},
{ type: 'divider' },
{
icon: SVG.fontSize,
tooltip: "Font Size",
action: 'openFontSizeDialog'
},
{
icon: SVG.font,
tooltip: "Font Type",
action: 'openFontDialog'
},
{ type: 'divider' },
{
icon: SVG.color,
tooltip: "Text Color",
action: 'openColorDialog'
},
{
icon: SVG.shadow,
tooltip: "Shadow",
action: 'openShadowDialog'
},
{
icon: SVG.outline,
tooltip: "Outline",
action: 'openOutlineDialog'
},
{ type: 'divider' },
{
icon: SVG.rotate,
tooltip: "Rotate",
action: 'openRotationDialog'
},
{
icon: SVG.reflectX,
tooltip: "Reflect Horizontally",
action: 'reflectX'
},
{
icon: SVG.reflectY,
tooltip: "Reflect Vertically",
action: 'reflectY'
},
{ type: 'divider' },
{
icon: SVG.frame,
tooltip: "Frame Settings",
action: 'openFrameSizeDialog'
}
];
export const STYLES = `
@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,700;1,400;1,700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,400;0,700;1,400;1,700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,400;0,700;1,400;1,700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,400;0,700;1,400;1,700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Source+Sans+Pro:ital,wght@0,400;0,700;1,400;1,700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,400;0,700;1,400;1,700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;1,400;1,700&display=swap');
.skb-textbox-dialog {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background: #1e1e1e;
border: 1px solid #4a9eff;
padding: 20px;
border-radius: 4px;
z-index: 10000;
min-width: 400px;
}
.skb-textbox-dialog h3 {
color: #fff;
margin: 0 0 15px 0;
font-size: 16px;
}
.skb-textbox-position-canvas {
position: relative;
width: 360px;
height: 360px;
background: #2a2a2a;
border-radius: 4px;
overflow: hidden;
margin-bottom: 15px;
}
.skb-textbox-position-canvas canvas {
position: absolute;
top: 0;
left: 0;
}
.skb-textbox-handle {
position: absolute;
background: rgba(74, 158, 255, 0.2);
border: 2px solid #4a9eff;
border-radius: 4px;
transform: translate(-50%, -50%);
cursor: move;
display: flex;
align-items: center;
justify-content: center;
pointer-events: all;
width: 40px;
height: 40px;
}
.skb-textbox-handle-center {
width: 16px;
height: 16px;
background: #4a9eff;
border: 2px solid #fff;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
}
.skb-textbox-inputs {
display: flex;
gap: 10px;
margin-bottom: 10px;
}
.skb-textbox-inputs > div {
flex: 1;
}
.skb-textbox-inputs label {
color: #ccc;
display: block;
margin-bottom: 5px;
}
.skb-textbox-inputs input {
width: 100%;
background: #2a2a2a;
color: #fff;
border: 1px solid #666;
padding: 4px;
border-radius: 3px;
}
.skb-textbox-buttons {
display: flex;
gap: 10px;
margin-bottom: 10px;
}
.skb-textbox-buttons button {
flex: 1;
padding: 8px;
background: #333;
color: #fff;
border: none;
border-radius: 3px;
cursor: pointer;
transition: background-color 0.2s;
}
.skb-textbox-buttons button:hover {
background: #444;
}
.skb-textbox-button-group {
display: flex;
justify-content: flex-end;
gap: 10px;
margin-top: 15px;
padding-top: 15px;
border-top: 1px solid #333;
}
.skb-textbox-button-group button {
padding: 6px 15px;
border: none;
border-radius: 3px;
cursor: pointer;
transition: opacity 0.2s;
}
.skb-textbox-button-group button:hover {
opacity: 0.8;
}
.skb-textbox-button-group button.secondary {
background: #333;
color: #fff;
}
.skb-textbox-button-group button.primary {
background: #4a9eff;
color: #fff;
}
.skb-textbox-font-preview {
padding: 10px;
margin-bottom: 5px;
border-radius: 4px;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
transition: background-color 0.2s;
}
.skb-textbox-font-preview:hover {
background: #2a2a2a;
}
.skb-textbox-font-preview.selected {
background: #4a9eff;
}
.skb-textbox-font-preview .skb-textbox-font-name {
color: #fff;
}
.skb-textbox-font-preview .skb-textbox-font-sample {
color: #ccc;
}
.skb-textbox-font-preview.selected .skb-textbox-font-name,
.skb-textbox-font-preview.selected .skb-textbox-font-sample {
color: #fff;
}
.skb-textbox-font-list {
max-height: 300px;
overflow-y: auto;
margin: 10px 0;
padding-right: 10px;
}
.skb-textbox-font-list::-webkit-scrollbar {
width: 8px;
}
.skb-textbox-font-list::-webkit-scrollbar-track {
background: #1e1e1e;
border-radius: 4px;
}
.skb-textbox-font-list::-webkit-scrollbar-thumb {
background: #4a9eff;
border-radius: 4px;
}
.skb-textbox-font-family-roboto { font-family: 'Roboto', sans-serif; }
.skb-textbox-font-family-montserrat { font-family: 'Montserrat', sans-serif; }
.skb-textbox-font-family-opensans { font-family: 'Open Sans', sans-serif; }
.skb-textbox-font-family-lato { font-family: 'Lato', sans-serif; }
.skb-textbox-font-family-poppins { font-family: 'Poppins', sans-serif; }
.skb-textbox-font-family-sourcesanspro { font-family: 'Source Sans Pro', sans-serif; }
.skb-textbox-font-family-ubuntu { font-family: 'Ubuntu', sans-serif; }
.skb-textbox-font-family-playfair { font-family: 'Playfair Display', serif; }
/* Styles moved from openMoveDialog */
.skb-textbox-dialog .skb-textbox-position-canvas {
position: relative;
width: 360px;
height: 360px;
margin: 0 auto 15px auto;
background: #181818;
border: 1px solid #333;
}
.skb-textbox-dialog canvas#positionCanvas {
display: block;
}
.skb-textbox-dialog .skb-textbox-handle {
position: absolute;
width: 20px;
height: 20px;
border: 2px solid #4a9eff;
border-radius: 50%;
background: rgba(74, 158, 255, 0.3);
cursor: grab;
transform: translate(-50%, -50%);
box-sizing: border-box;
}
.skb-textbox-dialog .skb-textbox-handle:active {
cursor: grabbing;
}
.skb-textbox-dialog .skb-textbox-handle-center {
position: absolute;
top: 50%;
left: 50%;
width: 4px;
height: 4px;
background: #fff;
border-radius: 50%;
transform: translate(-50%, -50%);
}
.skb-textbox-dialog .skb-textbox-inputs {
display: flex;
justify-content: space-between;
gap: 10px;
margin-bottom: 15px;
}
.skb-textbox-dialog .skb-textbox-inputs div {
flex: 1;
}
.skb-textbox-dialog .skb-textbox-inputs label {
display: block;
color: #ccc;
font-size: 12px;
margin-bottom: 4px;
}
.skb-textbox-dialog .skb-textbox-inputs input {
width: 100%;
box-sizing: border-box;
background: #2a2a2a;
color: #fff;
border: 1px solid #666;
padding: 6px;
border-radius: 3px;
text-align: center;
}
/* Hide number input spinners */
.skb-textbox-dialog .skb-textbox-inputs input::-webkit-outer-spin-button,
.skb-textbox-dialog .skb-textbox-inputs input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
.skb-textbox-dialog .skb-textbox-inputs input[type=number] {
-moz-appearance: textfield;
}
.skb-textbox-dialog .skb-textbox-buttons {
display: flex;
justify-content: space-around;
margin-bottom: 15px;
}
.skb-textbox-dialog .skb-textbox-buttons button {
padding: 6px 15px;
background: #333;
color: #fff;
border: none;
border-radius: 3px;
cursor: pointer;
}
.skb-textbox-dialog .skb-textbox-buttons button:hover {
background: #444;
}
.skb-textbox-dialog .skb-textbox-button-group {
display: flex;
justify-content: flex-end;
gap: 10px;
}
`;