mirror of
https://github.com/iconify/iconify.git
synced 2025-01-08 07:48:29 +00:00
Render icons as background in SVG framework
This commit is contained in:
parent
7700ea1808
commit
f5bc7b4ea2
@ -45,12 +45,14 @@
|
|||||||
<body>
|
<body>
|
||||||
<p>This is a simple HTML page with few icons.</p>
|
<p>This is a simple HTML page with few icons.</p>
|
||||||
<p>
|
<p>
|
||||||
Icon that behaves like an image:
|
Icons that behave like images:
|
||||||
<span class="iconify" data-icon="bi:house-door"></span>
|
<span class="iconify" data-icon="bi:house-door"></span>
|
||||||
|
<i class="iconify" data-icon="cif:ee"></i>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Icon that behaves like an glyph (aligned to bottom of this text):
|
Icon that behaves like an glyph (aligned to bottom of this text):
|
||||||
<span class="iconify-inline" data-icon="bi:house-door"></span>
|
<span class="iconify-inline" data-icon="bi:house-door"></span>
|
||||||
|
<i class="iconify-inline" data-icon="cif:ee"></i>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Changing icon color:
|
Changing icon color:
|
||||||
|
119
packages/iconify/src/render/bg.ts
Normal file
119
packages/iconify/src/render/bg.ts
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
import type { FullIconifyIcon } from '@iconify/utils/lib/icon';
|
||||||
|
import { iconToSVG } from '@iconify/utils/lib/svg/build';
|
||||||
|
import {
|
||||||
|
elementDataProperty,
|
||||||
|
IconifyElement,
|
||||||
|
IconifyElementProps,
|
||||||
|
IconifyElementData,
|
||||||
|
} from '../scanner/config';
|
||||||
|
import { applyClasses } from './classes';
|
||||||
|
import { applyStyle } from './style';
|
||||||
|
|
||||||
|
const commonProps: Record<string, string> = {
|
||||||
|
display: 'inline-block',
|
||||||
|
};
|
||||||
|
|
||||||
|
const monotoneProps: Record<string, string> = {
|
||||||
|
'-webkit-mask-image': 'var(--svg)',
|
||||||
|
'-webkit-mask-repeat': 'no-repeat',
|
||||||
|
'-webkit-mask-size': '100% 100%',
|
||||||
|
'mask-image': 'var(--svg)',
|
||||||
|
'mask-repeat': 'no-repeat',
|
||||||
|
'mask-size': '100% 100%',
|
||||||
|
'background-color': 'currentColor',
|
||||||
|
};
|
||||||
|
|
||||||
|
const coloredProps: Record<string, string> = {
|
||||||
|
'background-image': 'var(--svg)',
|
||||||
|
'background-repeat': 'no-repeat',
|
||||||
|
'background-size': '100% 100%',
|
||||||
|
'background-color': 'transparent',
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render icon as inline SVG
|
||||||
|
*/
|
||||||
|
export function renderBackground(
|
||||||
|
element: IconifyElement,
|
||||||
|
props: IconifyElementProps,
|
||||||
|
iconData: FullIconifyIcon
|
||||||
|
): IconifyElement {
|
||||||
|
// Generate data to render
|
||||||
|
const renderData = iconToSVG(iconData, {
|
||||||
|
...props.customisations,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get old data
|
||||||
|
const oldData = element[elementDataProperty];
|
||||||
|
|
||||||
|
// Generate SVG
|
||||||
|
const renderAttribs = renderData.attributes;
|
||||||
|
let renderAttribsHTML = '';
|
||||||
|
for (const attr in renderAttribs) {
|
||||||
|
const value = (
|
||||||
|
iconData[attr] !== void 0 ? iconData[attr] : renderAttribs[attr]
|
||||||
|
) as string;
|
||||||
|
renderAttribsHTML += ' ' + attr + '="' + value + '"';
|
||||||
|
}
|
||||||
|
const html =
|
||||||
|
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"' +
|
||||||
|
renderAttribsHTML +
|
||||||
|
'>' +
|
||||||
|
renderData.body +
|
||||||
|
'</svg>';
|
||||||
|
|
||||||
|
// Add classes
|
||||||
|
const classesToAdd: Set<string> = new Set(['iconify']);
|
||||||
|
const iconName = props.icon;
|
||||||
|
['provider', 'prefix'].forEach((attr: keyof typeof iconName) => {
|
||||||
|
if (iconName[attr]) {
|
||||||
|
classesToAdd.add('iconify--' + iconName[attr]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const addedClasses = applyClasses(
|
||||||
|
element,
|
||||||
|
classesToAdd,
|
||||||
|
new Set(oldData && oldData.addedClasses)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Update style
|
||||||
|
const isMonotone = renderData.body.indexOf('currentColor') !== -1;
|
||||||
|
const url =
|
||||||
|
'url("data:image/svg+xml,' +
|
||||||
|
html
|
||||||
|
.replace(/"/g, "'")
|
||||||
|
.replace(/%/g, '%25')
|
||||||
|
.replace(/#/g, '%23')
|
||||||
|
.replace(/{/g, '%7B')
|
||||||
|
.replace(/}/g, '%7D')
|
||||||
|
.replace(/</g, '%3C')
|
||||||
|
.replace(/>/g, '%3E') +
|
||||||
|
'")';
|
||||||
|
const newStyles: Record<string, string> = {
|
||||||
|
'--svg': url,
|
||||||
|
'width': renderAttribs.width,
|
||||||
|
'height': renderAttribs.height,
|
||||||
|
...commonProps,
|
||||||
|
...(isMonotone ? monotoneProps : coloredProps),
|
||||||
|
};
|
||||||
|
if (renderData.inline) {
|
||||||
|
newStyles['vertical-align'] = '-0.125em';
|
||||||
|
}
|
||||||
|
|
||||||
|
const addedStyles = applyStyle(
|
||||||
|
element,
|
||||||
|
newStyles,
|
||||||
|
oldData && oldData.addedStyles
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add data to element
|
||||||
|
const newData: IconifyElementData = {
|
||||||
|
...props,
|
||||||
|
status: 'loaded',
|
||||||
|
addedClasses,
|
||||||
|
addedStyles,
|
||||||
|
};
|
||||||
|
element[elementDataProperty] = newData;
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
@ -22,6 +22,7 @@ import {
|
|||||||
resumeObservingNode,
|
resumeObservingNode,
|
||||||
stopObserving,
|
stopObserving,
|
||||||
} from '../observer';
|
} from '../observer';
|
||||||
|
import { renderBackground } from '../render/bg';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag to avoid scanning DOM too often
|
* Flag to avoid scanning DOM too often
|
||||||
@ -121,7 +122,8 @@ export function scanDOM(rootNode?: ObservedNode, addTempNode = false): void {
|
|||||||
paused = true;
|
paused = true;
|
||||||
pauseObservingNode(observedNode);
|
pauseObservingNode(observedNode);
|
||||||
}
|
}
|
||||||
renderInlineSVG(element, props, iconData);
|
// renderInlineSVG(element, props, iconData);
|
||||||
|
renderBackground(element, props, iconData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find all elements
|
// Find all elements
|
||||||
|
Loading…
Reference in New Issue
Block a user