Refactor SVG handling for responsive scaling and improve styling attributes

This commit is contained in:
sHa
2025-06-20 00:02:36 +03:00
parent cb373ffef2
commit fff1e0b395
4 changed files with 72 additions and 71 deletions

View File

@@ -284,12 +284,12 @@ div.logo-image img {
}
.logo-image svg {
width: 100%;
/* width: 100%;
height: 100%;
max-width: 100%;
max-height: 100%;
display: block;
object-fit: contain;
object-fit: contain; */
color: var(--color-default-fill);
}

View File

@@ -6,6 +6,7 @@
import { getDefaultLogoColor, getThemeColor } from "../utils/colorTheme.js";
import { fetchSvgSource } from "../utils/svgSource.js";
import { collections } from '../collections.js';
import { get } from "svelte/store";
export let show = false;
export let logo = null;
@@ -101,28 +102,6 @@
window.scrollTo(0, 0);
}
// Svelte action to remove width/height from SVGs for responsive scaling
function removeSvgSize(node) {
function cleanSvg() {
const svgs = node.querySelectorAll("svg");
svgs.forEach((svg) => {
svg.removeAttribute("width");
svg.removeAttribute("height");
svg.style.width = "100%";
svg.style.height = "100%";
});
}
cleanSvg();
// In case SVG is loaded async (e.g. InlineSvg), observe for changes
const observer = new MutationObserver(cleanSvg);
observer.observe(node, { childList: true, subtree: true });
return {
destroy() {
observer.disconnect();
},
};
}
// Capitalize first letter of a string
function capitalizeFirst(str) {
if (!str) return "";
@@ -158,7 +137,7 @@
<div class="header-spacer"></div>
</div>
<div class="preview-body">
<div class="preview-container" use:removeSvgSize>
<div class="preview-container" >
{#if isSvgLogo(logo)}
<InlineSvg
bind:this={inlineSvgRef}
@@ -317,14 +296,16 @@
color: var(--color-text);
overflow: hidden;
position: relative;
contain: layout style paint; /* CSS containment */
}
.preview-container img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
max-width: 90%;
max-height: 90%;
width: auto;
height: auto;
object-fit: contain;
display: block;
}
.logo-details.fullscreen-details {

View File

@@ -1,41 +0,0 @@
<script>
import CardSquare from './CardMiddle.svelte';
export let logos = [];
export let onCopy;
export let onDownload;
export let setSearchQuery;
export let allLogos = [];
export let theme;
</script>
<div class="logo-grid">
{#each logos as logo}
<CardSquare
{logo}
{theme}
{onCopy}
{onDownload}
{setSearchQuery}
{allLogos}
/>
{:else}
<p class="no-results">No logos found matching your search criteria.</p>
{/each}
</div>
<style>
.logo-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 1.5rem;
}
.no-results {
grid-column: 1 / -1;
text-align: center;
padding: 2rem;
color: #666;
}
</style>

View File

@@ -26,17 +26,73 @@
const doc = parser.parseFromString(text, "image/svg+xml");
const svg = doc.documentElement;
// Fix SVG dimensions here too
const viewBox = svg.getAttribute('viewBox');
if (viewBox) {
// Remove any existing style and dimension attributes
svg.removeAttribute('style');
svg.removeAttribute('width');
svg.removeAttribute('height');
// Set percentage dimensions to allow scaling
svg.setAttribute('width', '100%');
svg.setAttribute('height', '100%');
// svg.setAttribute('preserveAspectRatio', 'none');
// Ensure viewBox is preserved for proper clipping
svg.setAttribute('viewBox', viewBox);
} else {
svg.removeAttribute('style');
svg.setAttribute('width', '100%');
svg.setAttribute('height', '100%');
}
// Set currentColor on SVG element if no fill is specified
if (!svg.hasAttribute("fill")) {
svg.setAttribute("fill", "currentColor");
}
svgHtml = doc.documentElement.outerHTML;
svgSource = svgHtml;
return;
}
// Parse and update color only if user selected
const parser = new DOMParser();
const doc = parser.parseFromString(text, "image/svg+xml");
// Add proper SVG clipping first (before color processing)
const svg = doc.documentElement;
// Fix SVG dimensions based on viewBox
const viewBox = svg.getAttribute('viewBox');
if (viewBox) {
// Remove any existing style attribute and fixed dimensions
svg.removeAttribute('style');
svg.removeAttribute('width');
svg.removeAttribute('height');
// Set percentage dimensions to allow scaling
svg.setAttribute('width', '100%');
svg.setAttribute('height', '100%');
// Ensure viewBox is preserved for proper clipping
svg.setAttribute('viewBox', viewBox);
// Add preserveAspectRatio to ensure proper scaling
if (!svg.hasAttribute('preserveAspectRatio')) {
svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
}
} else {
// If no viewBox, remove style and set percentage dimensions
svg.removeAttribute('style');
svg.setAttribute('width', '100%');
svg.setAttribute('height', '100%');
}
// Ensure proper overflow handling
svg.setAttribute('overflow', 'visible'); // Let CSS handle the clipping
// Now process color changes
// 1. Parse <style> rules and apply as inline attributes before removing <style>
const styleEls = Array.from(doc.querySelectorAll("style"));
styleEls.forEach((styleEl) => {
@@ -149,12 +205,17 @@
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
isolation: isolate;
contain: layout style paint;
position: relative;
}
.svg-wrapper :global(svg) {
width: 100%;
height: 100%;
max-width: 100%;
max-height: 100%;
object-fit: contain;
display: block;
transform-origin: center;
}
</style>