mirror of
https://github.com/shadoll/sLogos.git
synced 2026-02-04 11:03:24 +00:00
Refactor SVG handling for responsive scaling and improve styling attributes
This commit is contained in:
@@ -284,12 +284,12 @@ div.logo-image img {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.logo-image svg {
|
.logo-image svg {
|
||||||
width: 100%;
|
/* width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
display: block;
|
display: block;
|
||||||
object-fit: contain;
|
object-fit: contain; */
|
||||||
color: var(--color-default-fill);
|
color: var(--color-default-fill);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
import { getDefaultLogoColor, getThemeColor } from "../utils/colorTheme.js";
|
import { getDefaultLogoColor, getThemeColor } from "../utils/colorTheme.js";
|
||||||
import { fetchSvgSource } from "../utils/svgSource.js";
|
import { fetchSvgSource } from "../utils/svgSource.js";
|
||||||
import { collections } from '../collections.js';
|
import { collections } from '../collections.js';
|
||||||
|
import { get } from "svelte/store";
|
||||||
|
|
||||||
export let show = false;
|
export let show = false;
|
||||||
export let logo = null;
|
export let logo = null;
|
||||||
@@ -101,28 +102,6 @@
|
|||||||
window.scrollTo(0, 0);
|
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
|
// Capitalize first letter of a string
|
||||||
function capitalizeFirst(str) {
|
function capitalizeFirst(str) {
|
||||||
if (!str) return "";
|
if (!str) return "";
|
||||||
@@ -158,7 +137,7 @@
|
|||||||
<div class="header-spacer"></div>
|
<div class="header-spacer"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="preview-body">
|
<div class="preview-body">
|
||||||
<div class="preview-container" use:removeSvgSize>
|
<div class="preview-container" >
|
||||||
{#if isSvgLogo(logo)}
|
{#if isSvgLogo(logo)}
|
||||||
<InlineSvg
|
<InlineSvg
|
||||||
bind:this={inlineSvgRef}
|
bind:this={inlineSvgRef}
|
||||||
@@ -317,14 +296,16 @@
|
|||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
contain: layout style paint; /* CSS containment */
|
||||||
}
|
}
|
||||||
|
|
||||||
.preview-container img {
|
.preview-container img {
|
||||||
max-width: 100%;
|
max-width: 90%;
|
||||||
max-height: 100%;
|
max-height: 90%;
|
||||||
object-fit: contain;
|
|
||||||
width: auto;
|
width: auto;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
object-fit: contain;
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo-details.fullscreen-details {
|
.logo-details.fullscreen-details {
|
||||||
|
|||||||
@@ -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>
|
|
||||||
@@ -26,17 +26,73 @@
|
|||||||
const doc = parser.parseFromString(text, "image/svg+xml");
|
const doc = parser.parseFromString(text, "image/svg+xml");
|
||||||
const svg = doc.documentElement;
|
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
|
// Set currentColor on SVG element if no fill is specified
|
||||||
if (!svg.hasAttribute("fill")) {
|
if (!svg.hasAttribute("fill")) {
|
||||||
svg.setAttribute("fill", "currentColor");
|
svg.setAttribute("fill", "currentColor");
|
||||||
}
|
}
|
||||||
|
|
||||||
svgHtml = doc.documentElement.outerHTML;
|
svgHtml = doc.documentElement.outerHTML;
|
||||||
|
svgSource = svgHtml;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Parse and update color only if user selected
|
// Parse and update color only if user selected
|
||||||
const parser = new DOMParser();
|
const parser = new DOMParser();
|
||||||
const doc = parser.parseFromString(text, "image/svg+xml");
|
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>
|
// 1. Parse <style> rules and apply as inline attributes before removing <style>
|
||||||
const styleEls = Array.from(doc.querySelectorAll("style"));
|
const styleEls = Array.from(doc.querySelectorAll("style"));
|
||||||
styleEls.forEach((styleEl) => {
|
styleEls.forEach((styleEl) => {
|
||||||
@@ -149,12 +205,17 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
overflow: hidden;
|
||||||
|
isolation: isolate;
|
||||||
|
contain: layout style paint;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.svg-wrapper :global(svg) {
|
.svg-wrapper :global(svg) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
|
display: block;
|
||||||
|
transform-origin: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user