mirror of
https://github.com/shadoll/sLogos.git
synced 2025-12-20 06:30:00 +00:00
feat: enhance SVG handling by updating color targets and adding SVG source retrieval; refactor Actions and InlineSvg components for improved functionality
This commit is contained in:
@@ -1544,30 +1544,33 @@
|
||||
"ua_yellow": "#FFDD00"
|
||||
},
|
||||
"targets": {
|
||||
"part_s1": "#s1",
|
||||
"part_s2": "#s2",
|
||||
"part_l": "#l"
|
||||
"part_s": "#s",
|
||||
"part_s_stroke": "#s&stroke",
|
||||
"part_l": "#l",
|
||||
"part_l_stroke": "#l&stroke"
|
||||
},
|
||||
"sets": {
|
||||
"light": {
|
||||
"part_s1": "red",
|
||||
"part_s2": "red",
|
||||
"part_l": "white"
|
||||
"part_s": "red",
|
||||
"part_l": "white",
|
||||
"part_l_stroke": "black",
|
||||
"part_s_stroke": "black"
|
||||
},
|
||||
"dark": {
|
||||
"part_s1": "red",
|
||||
"part_s2": "red",
|
||||
"part_l": "black"
|
||||
"part_s": "red",
|
||||
"part_l": "black",
|
||||
"part_l_stroke": "white",
|
||||
"part_s_stroke": "white"
|
||||
},
|
||||
"uk": {
|
||||
"part_s1": "uk_red",
|
||||
"part_s2": "uk_red",
|
||||
"part_l": "uk_blue"
|
||||
},
|
||||
"ua": {
|
||||
"part_s1": "ua_blue",
|
||||
"part_s2": "ua_blue",
|
||||
"part_l": "ua_yellow"
|
||||
"part_s": "ua_blue",
|
||||
"part_l": "ua_yellow",
|
||||
"part_l_stroke": "none",
|
||||
"part_s_stroke": "none"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1582,7 +1585,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Shkafnik Logo",
|
||||
"name": "Shkafnik",
|
||||
"path": "logos/shkafnik_logo.svg",
|
||||
"format": "SVG",
|
||||
"disable": false,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="510" width="510" viewBox="0 0 510 510">
|
||||
<path id="l" d="m286.7 401.2 61.9 60.2v-389.4l-62.4-60.6z" fill="currentColor" stroke="#eee" stroke-width="0"
|
||||
<path id="l" d="m286.7 401.2 61.9 60.2v-389.4l-62.4-60.6z" fill="currentColor" stroke="none" stroke-width="2"
|
||||
stroke-miterlimit="10" />
|
||||
<g stroke="#eee" stroke-width="0" stroke-miterlimit="10">
|
||||
<path id="s1" fill="#dc2108" d="m161.2 500 106.1-100.8-39-37.2-66.9 63.6z" />
|
||||
<path id="s2" fill="#dc2108" d="m275 174.3-113.8 108.9 113.8 108.9v-73.6l-37-35.3 37-36.3z" />
|
||||
<g id="s" fill="#dc2108" stroke="none" stroke-width="2" stroke-miterlimit="10">
|
||||
<path d="m161.2 500 106.1-100.8-39-37.2-66.9 63.6z" />
|
||||
<path d="m275 174.3-113.8 108.9 113.8 108.9v-73.6l-37-35.3 37-36.3z" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 485 B After Width: | Height: | Size: 461 B |
@@ -393,7 +393,7 @@
|
||||
top: 110%;
|
||||
right: auto;
|
||||
left: 0;
|
||||
min-width: 200px; /* Increased width from 160px */
|
||||
min-width: 200px;
|
||||
background: var(--color-card, #fff);
|
||||
color: var(--color-text, #222);
|
||||
border: 1px solid var(--color-border, #ddd);
|
||||
@@ -407,7 +407,6 @@
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* Dropdown menus are positioned with JavaScript instead of CSS */
|
||||
.dropdown-item {
|
||||
background: none;
|
||||
color: var(--color-text, #222);
|
||||
@@ -439,7 +438,7 @@
|
||||
padding-left: 5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
/* Notification styles moved to Notification.svelte */
|
||||
|
||||
.notification-overlay {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
|
||||
@@ -23,12 +23,41 @@
|
||||
// For SVG source code display
|
||||
let svgSource = "";
|
||||
let isFetchingSvgSource = false;
|
||||
let inlineSvgRef; // Reference to the InlineSvg component
|
||||
|
||||
// Watch for color changes and update SVG source
|
||||
function updateSvgSource() {
|
||||
if (inlineSvgRef && typeof inlineSvgRef.getSvgSource === 'function') {
|
||||
const newSource = inlineSvgRef.getSvgSource();
|
||||
if (newSource) {
|
||||
svgSource = newSource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isSvgLogo(logo) {
|
||||
return logo && logo.format && logo.format.toLowerCase() === "svg";
|
||||
}
|
||||
function copySvgSourceFromTextarea() {
|
||||
if (svgSource) {
|
||||
if (inlineSvgRef && typeof inlineSvgRef.getSvgSource === 'function') {
|
||||
// Get the updated SVG source with all color changes applied
|
||||
const updatedSource = inlineSvgRef.getSvgSource();
|
||||
|
||||
try {
|
||||
const tempEl = document.createElement('textarea');
|
||||
tempEl.value = updatedSource || svgSource;
|
||||
document.body.appendChild(tempEl);
|
||||
tempEl.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(tempEl);
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.error("Error copying SVG source:", err);
|
||||
window.prompt("Copy the SVG source code:", updatedSource || svgSource);
|
||||
return false;
|
||||
}
|
||||
} else if (svgSource) {
|
||||
// Fallback to the original source if component reference is not available
|
||||
try {
|
||||
navigator.clipboard.writeText(svgSource);
|
||||
return true;
|
||||
@@ -41,14 +70,18 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
$: getLogoThemeColor = (logo) => getDefaultLogoColor(logo.colors, theme);
|
||||
// Update SVG source every time the component rerenders with new colors
|
||||
$: if (logo && (logo._activeColor || (logo && logo._activeSet))) {
|
||||
// Use a small delay to ensure the SVG has been rendered with the new colors
|
||||
setTimeout(updateSvgSource, 100);
|
||||
}
|
||||
|
||||
$: validColorConfig =
|
||||
logo && typeof logo.colorConfig === "object" && logo.colorConfig.selector
|
||||
? logo.colorConfig
|
||||
: undefined;
|
||||
|
||||
// Only fetch SVG source when displayed
|
||||
$: getLogoThemeColor = (logo) => getDefaultLogoColor(logo.colors, theme);
|
||||
$: if (show && logo) {
|
||||
if (logo.format === "SVG" && !svgSource) {
|
||||
isFetchingSvgSource = true;
|
||||
@@ -106,6 +139,7 @@
|
||||
<div class="preview-container" use:removeSvgSize>
|
||||
{#if isSvgLogo(logo)}
|
||||
<InlineSvg
|
||||
bind:this={inlineSvgRef}
|
||||
path={logo.path}
|
||||
color={logo.colors
|
||||
? logo._activeColor || getLogoThemeColor(logo)
|
||||
@@ -132,10 +166,18 @@
|
||||
role="button"
|
||||
aria-label="Reset to theme color"
|
||||
style="background: none; width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; padding: 0; margin: 0; border: none;"
|
||||
on:click|stopPropagation={() => (logo._activeColor = undefined)}
|
||||
on:keydown|stopPropagation={(e) =>
|
||||
(e.key === "Enter" || e.key === " ") &&
|
||||
(logo._activeColor = undefined)}
|
||||
on:click|stopPropagation={() => {
|
||||
logo._activeColor = undefined;
|
||||
logo._activeSet = undefined; // Reset activeSet too
|
||||
setTimeout(updateSvgSource, 100); // Update SVG source after color reset
|
||||
}}
|
||||
on:keydown|stopPropagation={(e) => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
logo._activeColor = undefined;
|
||||
logo._activeSet = undefined;
|
||||
setTimeout(updateSvgSource, 100);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
width="100%"
|
||||
@@ -160,6 +202,7 @@
|
||||
i % Object.keys(logo.colors).length
|
||||
];
|
||||
logo._activeSet = setName;
|
||||
setTimeout(updateSvgSource, 100); // Update SVG source after color change
|
||||
}}
|
||||
on:keydown|stopPropagation={(e) => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
@@ -167,6 +210,7 @@
|
||||
i % Object.keys(logo.colors).length
|
||||
];
|
||||
logo._activeSet = setName;
|
||||
setTimeout(updateSvgSource, 100); // Update SVG source after color change
|
||||
}
|
||||
}}
|
||||
style="padding: 0; overflow: hidden;"
|
||||
@@ -182,11 +226,18 @@
|
||||
style={`background:${colorValue}`}
|
||||
tabindex="0"
|
||||
role="button"
|
||||
on:click|stopPropagation={() =>
|
||||
(logo._activeColor = colorValue)}
|
||||
on:keydown|stopPropagation={(e) =>
|
||||
(e.key === "Enter" || e.key === " ") &&
|
||||
(logo._activeColor = colorValue)}
|
||||
on:click|stopPropagation={() => {
|
||||
logo._activeColor = colorValue;
|
||||
logo._activeSet = undefined; // Clear any active set when setting individual color
|
||||
setTimeout(updateSvgSource, 100); // Update SVG source after color change
|
||||
}}
|
||||
on:keydown|stopPropagation={(e) => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
logo._activeColor = colorValue;
|
||||
logo._activeSet = undefined; // Clear any active set
|
||||
setTimeout(updateSvgSource, 100); // Update SVG source after color change
|
||||
}
|
||||
}}
|
||||
></span>
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
export let colors = null;
|
||||
export let alt = "";
|
||||
let svgHtml = "";
|
||||
let svgSource = ""; // Store the updated SVG source code
|
||||
|
||||
async function fetchAndColorSvg() {
|
||||
const res = await fetch(path);
|
||||
@@ -58,37 +59,69 @@
|
||||
// Remove all <style> elements
|
||||
styleEls.forEach((styleEl) => styleEl.remove());
|
||||
// Handle the new format with targets and sets if available
|
||||
if (targets && sets && activeSet && sets[activeSet]) {
|
||||
if (targets && sets && activeSet && typeof activeSet === 'string' && sets[activeSet]) {
|
||||
try {
|
||||
// Get the color assignments from the active set
|
||||
const colorAssignments = sets[activeSet];
|
||||
|
||||
// Apply each target-color pair
|
||||
for (const [targetName, colorName] of Object.entries(colorAssignments)) {
|
||||
if (targets[targetName] && colors && colors[colorName]) {
|
||||
// Get the selector for this target
|
||||
const selector = targets[targetName];
|
||||
// Get the selector and determine if it's for fill or stroke
|
||||
const targetInfo = targets[targetName];
|
||||
|
||||
// Parse the selector to extract the target and attribute (fill/stroke)
|
||||
let selector, attribute;
|
||||
|
||||
if (typeof targetInfo === 'string') {
|
||||
if (targetInfo.includes('&stroke')) {
|
||||
// Format: "#element&stroke" - target stroke attribute
|
||||
selector = targetInfo.split('&stroke')[0];
|
||||
attribute = 'stroke';
|
||||
} else if (targetInfo.includes('&fill')) {
|
||||
// Format: "#element&fill" - target fill attribute
|
||||
selector = targetInfo.split('&fill')[0];
|
||||
attribute = 'fill';
|
||||
} else {
|
||||
// Default is fill if not specified
|
||||
selector = targetInfo;
|
||||
attribute = 'fill';
|
||||
}
|
||||
} else {
|
||||
// Fallback for older format
|
||||
selector = targetInfo;
|
||||
attribute = 'fill';
|
||||
}
|
||||
|
||||
// Proceed with selecting elements and applying colors
|
||||
const targetElements = doc.querySelectorAll(selector);
|
||||
// Get the actual color value for this target
|
||||
const targetColor = colors[colorName];
|
||||
|
||||
// Apply the color to all elements matching this selector
|
||||
targetElements.forEach(el => {
|
||||
// Always override fill and stroke unless they are 'none'
|
||||
if (el.hasAttribute("fill") && el.getAttribute("fill") !== "none") {
|
||||
if (colorName === "none") {
|
||||
// Special case for 'none' value
|
||||
el.setAttribute(attribute, "none");
|
||||
} else if (attribute === 'fill') {
|
||||
el.setAttribute("fill", targetColor);
|
||||
}
|
||||
if (el.hasAttribute("stroke") && el.getAttribute("stroke") !== "none") {
|
||||
} else if (attribute === 'stroke') {
|
||||
el.setAttribute("stroke", targetColor);
|
||||
}
|
||||
if (!el.hasAttribute("fill") && !el.hasAttribute("stroke")) {
|
||||
// If neither, prefer fill
|
||||
el.setAttribute("fill", targetColor);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Error applying color set:", err);
|
||||
}
|
||||
}
|
||||
svgHtml = doc.documentElement.outerHTML;
|
||||
// Update the svgSource property to store the modified SVG code
|
||||
svgSource = doc.documentElement.outerHTML;
|
||||
}
|
||||
|
||||
// Export the svgSource so it can be accessed from outside
|
||||
export function getSvgSource() {
|
||||
return svgSource;
|
||||
}
|
||||
|
||||
$: path, color, colorConfig, targets, sets, activeSet, colors, fetchAndColorSvg();
|
||||
|
||||
Reference in New Issue
Block a user