mirror of
https://github.com/shadoll/sLogos.git
synced 2025-12-20 20:35:19 +00:00
update InlineSvg component for better color handling; refactor logo components to streamline SVG rendering and remove unused styles.
This commit is contained in:
@@ -9,12 +9,64 @@
|
||||
async function fetchAndColorSvg() {
|
||||
const res = await fetch(path);
|
||||
let text = await res.text();
|
||||
if (!color || !colorConfig) {
|
||||
// No colorization, render as-is
|
||||
svgHtml = text;
|
||||
return;
|
||||
}
|
||||
// Parse and update color
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(text, 'image/svg+xml');
|
||||
const targets = doc.querySelectorAll(colorConfig.selector || colorConfig.target);
|
||||
// 1. Parse <style> rules and apply as inline attributes before removing <style>
|
||||
const styleEls = Array.from(doc.querySelectorAll('style'));
|
||||
styleEls.forEach(styleEl => {
|
||||
const css = styleEl.textContent;
|
||||
// Only handle simple .class { ... } rules
|
||||
const regex = /\.([\w-]+)\s*{([^}]*)}/g;
|
||||
let match;
|
||||
while ((match = regex.exec(css))) {
|
||||
const className = match[1];
|
||||
const rules = match[2];
|
||||
// Find all elements with this class
|
||||
doc.querySelectorAll('.' + className).forEach(el => {
|
||||
rules.split(';').forEach(rule => {
|
||||
const [prop, value] = rule.split(':').map(s => s && s.trim());
|
||||
if (prop && value) {
|
||||
// Apply all style properties, not just fill/stroke
|
||||
el.setAttribute(prop.replace(/-([a-z])/g, g => g[1].toUpperCase()), value);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
// Remove all <style> elements
|
||||
styleEls.forEach(styleEl => styleEl.remove());
|
||||
let targets;
|
||||
if (colorConfig.selector) {
|
||||
targets = doc.querySelectorAll(colorConfig.selector);
|
||||
} else if (colorConfig.target) {
|
||||
targets = doc.querySelectorAll(colorConfig.target);
|
||||
} else {
|
||||
targets = [];
|
||||
}
|
||||
targets.forEach(el => {
|
||||
el.setAttribute(colorConfig.attribute, color);
|
||||
if (colorConfig.attribute) {
|
||||
// Legacy: force a single attribute
|
||||
el.setAttribute(colorConfig.attribute, color);
|
||||
} else {
|
||||
// Only set fill if no stroke attribute exists, and vice versa
|
||||
const hasFill = el.hasAttribute('fill');
|
||||
const hasStroke = el.hasAttribute('stroke');
|
||||
if (hasFill && !hasStroke && el.getAttribute('fill') !== 'none') {
|
||||
el.setAttribute('fill', color);
|
||||
} else if (hasStroke && !hasFill && el.getAttribute('stroke') !== 'none') {
|
||||
el.setAttribute('stroke', color);
|
||||
} else if (!hasFill && !hasStroke) {
|
||||
// If neither, prefer fill
|
||||
el.setAttribute('fill', color);
|
||||
}
|
||||
// If both fill and stroke exist, do not override either
|
||||
}
|
||||
});
|
||||
svgHtml = doc.documentElement.outerHTML;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script>
|
||||
export let logo;
|
||||
// export let onCopy; // No longer needed, handled locally
|
||||
export let onDownload;
|
||||
|
||||
// Download menu state
|
||||
@@ -322,11 +321,6 @@
|
||||
color: #fff;
|
||||
outline: none;
|
||||
}
|
||||
/* Fix: rounded corners for single and grouped buttons
|
||||
- If only one button (no menu), fully rounded
|
||||
- If menu present, main button: left rounded, menu: right rounded
|
||||
- If menu present but only menu button, menu: fully rounded
|
||||
*/
|
||||
.action-group .copy-btn:only-child,
|
||||
.action-group .download-btn:only-child {
|
||||
border-radius: 6px;
|
||||
|
||||
@@ -49,8 +49,13 @@
|
||||
on:keydown={(e) => (e.key === 'Enter' || e.key === ' ') && openPreview(logo)}
|
||||
style="cursor:pointer;"
|
||||
>
|
||||
{#if isSvgLogo(logo) && logo.colors}
|
||||
<InlineSvg path={logo.path} color={logo._activeColor || logo.colors[0].value} colorConfig={logo.colorConfig} alt={logo.name} />
|
||||
{#if isSvgLogo(logo)}
|
||||
<InlineSvg
|
||||
path={logo.path}
|
||||
color={logo.colors ? (logo._activeColor || logo.colors[0].value) : undefined}
|
||||
colorConfig={logo.colors ? logo.colorConfig : undefined}
|
||||
alt={logo.name}
|
||||
/>
|
||||
{:else}
|
||||
<img src={logo.path} alt={logo.name} />
|
||||
{/if}
|
||||
@@ -101,7 +106,6 @@
|
||||
transition: background 0.2s, color 0.2s, transform 0.2s, box-shadow 0.2s;
|
||||
min-width: 320px;
|
||||
}
|
||||
|
||||
.logo-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
||||
@@ -110,38 +114,8 @@
|
||||
.logo-image {
|
||||
height: 260px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 1rem;
|
||||
background: var(--color-card);
|
||||
color: var(--color-text);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s, color 0.2s;
|
||||
}
|
||||
.logo-image img,
|
||||
.logo-image :global(svg) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
object-position: center;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
/* Make inline SVGs scale and fit like <img> */
|
||||
.logo-image svg {
|
||||
max-width: 80%;
|
||||
max-height: 80%;
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
object-fit: contain;
|
||||
object-position: center;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.logo-info {
|
||||
padding: 1rem;
|
||||
@@ -154,71 +128,10 @@
|
||||
margin-bottom: 0.5rem;
|
||||
color: var(--color-accent, #4f8cff);
|
||||
}
|
||||
/* .logo-info p { font-size: 0.9rem; color: var(--color-text); margin-bottom: 1rem; } */
|
||||
.logo-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5em;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
.format-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 1em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
.color-switcher-inline {
|
||||
display: flex;
|
||||
gap: 0.4em;
|
||||
align-items: center;
|
||||
margin-left: auto;
|
||||
}
|
||||
.color-switcher {
|
||||
display: flex;
|
||||
gap: 0.4em;
|
||||
margin: 0.5em 0 0.5em 0;
|
||||
align-items: center;
|
||||
}
|
||||
.color-circle {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #eee;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.08);
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
transition: border 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
.color-circle:hover {
|
||||
border: 2px solid #888;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.12);
|
||||
}
|
||||
.no-results {
|
||||
grid-column: 1 / -1;
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.color-switcher {
|
||||
display: flex;
|
||||
gap: 0.4em;
|
||||
margin: 0.5em 0 0.5em 0;
|
||||
align-items: center;
|
||||
}
|
||||
.color-circle {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #eee;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.08);
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
transition: border 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
.color-circle:hover {
|
||||
border: 2px solid #888;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.12);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -38,9 +38,13 @@
|
||||
on:keydown={(e) => (e.key === 'Enter' || e.key === ' ') && openPreview(logo)}
|
||||
style="cursor:pointer;"
|
||||
>
|
||||
>
|
||||
{#if isSvgLogo(logo) && logo.colors}
|
||||
<InlineSvg path={logo.path} color={logo._activeColor || logo.colors[0].value} colorConfig={logo.colorConfig} alt={logo.name} />
|
||||
{#if isSvgLogo(logo)}
|
||||
<InlineSvg
|
||||
path={logo.path}
|
||||
color={logo.colors ? (logo._activeColor || logo.colors[0].value) : undefined}
|
||||
colorConfig={logo.colors ? logo.colorConfig : undefined}
|
||||
alt={logo.name}
|
||||
/>
|
||||
{:else}
|
||||
<img src={logo.path} alt={logo.name} />
|
||||
{/if}
|
||||
@@ -97,83 +101,22 @@
|
||||
.logo-preview {
|
||||
height: 100px;
|
||||
width: 80px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--color-card);
|
||||
color: var(--color-text);
|
||||
padding: 0;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s, color 0.2s;
|
||||
}
|
||||
.logo-preview img {
|
||||
max-width: 80%;
|
||||
max-height: 80%;
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
object-fit: contain;
|
||||
object-position: center;
|
||||
}
|
||||
.color-switcher {
|
||||
display: flex;
|
||||
gap: 0.4em;
|
||||
margin: 0.5em 0 0.5em 0;
|
||||
align-items: center;
|
||||
}
|
||||
.color-circle {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #eee;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.08);
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
transition: border 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
.color-circle:hover {
|
||||
border: 2px solid #888;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.12);
|
||||
}
|
||||
.logo-info {
|
||||
background: var(--color-card);
|
||||
color: var(--color-text);
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 4px;
|
||||
transition: background 0.2s, color 0.2s;
|
||||
position: relative;
|
||||
}
|
||||
.logo-info h3 {
|
||||
margin-bottom: 0.5rem;
|
||||
color: var(--color-accent, #4f8cff);
|
||||
}
|
||||
/* .logo-info p { font-size: 0.9rem; color: var(--color-text); margin-bottom: 1rem; } */
|
||||
.logo-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5em;
|
||||
}
|
||||
.logo-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.no-results {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.format-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1em;
|
||||
}
|
||||
/* .color-switcher-inline { display: flex; gap: 0.4em; align-items: center; margin-left: auto; } */
|
||||
.color-switcher-under {
|
||||
display: flex;
|
||||
gap: 0.4em;
|
||||
align-items: center;
|
||||
margin: 0.5em 0 0 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -49,8 +49,13 @@
|
||||
on:keydown={(e) => (e.key === 'Enter' || e.key === ' ') && close()}
|
||||
style="cursor:pointer;"
|
||||
>
|
||||
{#if isSvgLogo(logo) && logo.colors}
|
||||
<InlineSvg path={logo.path} color={logo._activeColor || logo.colors[0].value} colorConfig={logo.colorConfig} alt={logo.name} />
|
||||
{#if isSvgLogo(logo)}
|
||||
<InlineSvg
|
||||
path={logo.path}
|
||||
color={logo.colors ? (logo._activeColor || logo.colors[0].value) : undefined}
|
||||
colorConfig={logo.colors ? logo.colorConfig : undefined}
|
||||
alt={logo.name}
|
||||
/>
|
||||
{:else}
|
||||
<img src={logo.path} alt={logo.name} />
|
||||
{/if}
|
||||
@@ -156,33 +161,6 @@
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
/* .color-switcher { display: flex; gap: 0.4em; margin: 0.5em 0 0.5em 0; align-items: center; } */
|
||||
|
||||
.color-switcher-inline {
|
||||
display: flex;
|
||||
gap: 0.4em;
|
||||
align-items: center;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.color-circle {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #eee;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.08);
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
transition: border 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.color-circle:hover {
|
||||
border: 2px solid #888;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.12);
|
||||
}
|
||||
|
||||
/* .format-row { display: flex; align-items: center; justify-content: space-between; gap: 1em; margin-bottom: 0.5em; } */
|
||||
|
||||
.logo-details {
|
||||
padding: 1rem;
|
||||
background-color: var(--color-card);
|
||||
@@ -202,53 +180,4 @@
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.logo-tag {
|
||||
display: inline-block;
|
||||
background: var(--color-accent, #4f8cff);
|
||||
color: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 0.2em 0.8em;
|
||||
font-size: 0.85em;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.02em;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
/* .color-switcher-under { display: flex; gap: 0.4em; align-items: center; margin: 0.5em 0 0 0; } */
|
||||
|
||||
.color-switcher-inline {
|
||||
display: flex;
|
||||
gap: 0.4em;
|
||||
align-items: center;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.color-circle {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #eee;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.08);
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
transition: border 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.color-circle:hover {
|
||||
border: 2px solid #888;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.12);
|
||||
}
|
||||
|
||||
.format-value {
|
||||
font-weight: 400;
|
||||
margin-left: 0.3em;
|
||||
}
|
||||
|
||||
.color-switcher-preview {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 0.4em;
|
||||
align-items: center;
|
||||
margin: 1em 0 0.5em 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user