Icon improvements
|
|
@ -42,7 +42,6 @@ const StyledFileEntry = styled.li<StyledFileEntryProps>`
|
|||
word-break: break-word;
|
||||
}
|
||||
|
||||
img,
|
||||
picture {
|
||||
width: ${({ theme }) => theme.sizes.fileEntry.iconSize};
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ const StyledFileEntry = styled.li`
|
|||
color: #fff;
|
||||
}
|
||||
|
||||
img {
|
||||
picture {
|
||||
margin-left: 3px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ const StyledFileEntry = styled.li`
|
|||
opacity: 0.9;
|
||||
}
|
||||
|
||||
img {
|
||||
picture {
|
||||
margin-left: 7px;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ const StyledFileManager = styled.ol`
|
|||
margin-top: 7px;
|
||||
width: 100%;
|
||||
|
||||
img:not(:first-of-type) {
|
||||
picture:not(:first-of-type) {
|
||||
position: absolute;
|
||||
}
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ const StyledMenu = styled(motion.nav).attrs<StyledMenuProps>(({ $x, $y }) => ({
|
|||
}
|
||||
}
|
||||
|
||||
img {
|
||||
picture {
|
||||
margin: 0 -24px 0 8px;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,12 +69,12 @@ const StyledStartMenu = styled(motion.nav)<StyledStartMenuProps>`
|
|||
padding: 0;
|
||||
|
||||
figure {
|
||||
img {
|
||||
picture {
|
||||
margin-left: 9px;
|
||||
}
|
||||
|
||||
&:active {
|
||||
img {
|
||||
picture {
|
||||
margin-left: 13px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ const StyledTaskbarEntry = styled(motion.li)<StyledTaskbarEntryProps>`
|
|||
white-space: nowrap;
|
||||
}
|
||||
|
||||
img {
|
||||
picture {
|
||||
height: ${({ theme }) => theme.sizes.taskbar.entry.iconSize};
|
||||
position: relative;
|
||||
top: 1px;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ const StyledTitlebar = styled.header<StyledTitlebarProps>`
|
|||
position: relative;
|
||||
top: -1px;
|
||||
|
||||
img {
|
||||
picture {
|
||||
height: ${({ theme }) => theme.sizes.titleBar.iconSize};
|
||||
margin-right: ${({ theme }) => theme.sizes.titleBar.iconMarginRight};
|
||||
width: ${({ theme }) => theme.sizes.titleBar.iconSize};
|
||||
|
|
|
|||
BIN
public/System/Icons/144x144/marked.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
public/System/Icons/144x144/marked.webp
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 168 B After Width: | Height: | Size: 332 B |
|
Before Width: | Height: | Size: 128 B After Width: | Height: | Size: 276 B |
|
Before Width: | Height: | Size: 201 B After Width: | Height: | Size: 816 B |
|
Before Width: | Height: | Size: 156 B After Width: | Height: | Size: 710 B |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
BIN
public/System/Icons/32x32/marked.png
Normal file
|
After Width: | Height: | Size: 677 B |
BIN
public/System/Icons/32x32/marked.webp
Normal file
|
After Width: | Height: | Size: 582 B |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 395 B After Width: | Height: | Size: 395 B |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 973 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 864 B |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 2.2 KiB |
BIN
public/System/Icons/96x96/marked.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
public/System/Icons/96x96/marked.webp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 4.3 KiB |
|
|
@ -13,7 +13,7 @@ FOR %%X in (*.ico) DO (
|
|||
C:\ImageMagick\magick.exe "%%X[4]" -background none -compress lossless -strip -quality 100 "..\32x32\%%~nX.png"
|
||||
C:\ImageMagick\magick.exe "%%X[7]" -background none -compress lossless -strip -quality 100 "..\16x16\%%~nX.png"
|
||||
|
||||
C:\ImageMagick\magick.exe "%%X[0]" -compress lossless -strip -quality 100 "..\max\%%~nX.png"
|
||||
C:\ImageMagick\magick.exe "%%X[0]" -background none -compress lossless -strip -quality 100 "..\max\%%~nX.png"
|
||||
|
||||
cwebp -q 100 -z 9 -m 6 -sharp_yuv -pass 10 -resize 144 144 -mt -lossless -v "..\max\%%~nX.png" -o "..\144x144\%%~nX.webp"
|
||||
cwebp -q 100 -z 9 -m 6 -sharp_yuv -pass 10 -resize 96 96 -mt -lossless -v "..\max\%%~nX.png" -o "..\96x96\%%~nX.webp"
|
||||
|
|
|
|||
|
|
@ -10,25 +10,31 @@ export type IconProps = {
|
|||
$moving?: boolean;
|
||||
};
|
||||
|
||||
type StyledIconProps = Pick<IconProps, "$eager" | "$moving"> & {
|
||||
$height: number;
|
||||
$offset: number | string;
|
||||
$width: number;
|
||||
};
|
||||
|
||||
const StyledIcon = styled.img
|
||||
.withConfig({
|
||||
shouldForwardProp: (prop, defaultValidatorFn) =>
|
||||
["fetchpriority"].includes(prop) || defaultValidatorFn(prop),
|
||||
})
|
||||
.attrs<IconProps>(({ $imgSize = 0, $displaySize = 0, $eager = false }) => ({
|
||||
.attrs<StyledIconProps>(({ $eager = false, $height, $width }) => ({
|
||||
decoding: "async",
|
||||
draggable: false,
|
||||
fetchpriority: $eager ? "high" : undefined,
|
||||
height: $displaySize > $imgSize ? $imgSize : $displaySize || $imgSize,
|
||||
height: $height,
|
||||
loading: $eager ? "eager" : undefined,
|
||||
width: $displaySize > $imgSize ? $imgSize : $displaySize || $imgSize,
|
||||
}))<IconProps>`
|
||||
left: ${({ $displaySize = 0, $imgSize = 0 }) =>
|
||||
$displaySize > $imgSize ? `${$displaySize - $imgSize}px` : undefined};
|
||||
width: $width,
|
||||
}))<StyledIconProps>`
|
||||
left: ${({ $offset }) => $offset};
|
||||
max-height: ${({ $height }) => `${$height}px`};
|
||||
max-width: ${({ $width }) => `${$width}px`};
|
||||
object-fit: contain;
|
||||
opacity: ${({ $moving }) => ($moving ? 0.5 : 1)};
|
||||
top: ${({ $displaySize = 0, $imgSize = 0 }) =>
|
||||
$displaySize > $imgSize ? `${$displaySize - $imgSize}px` : undefined};
|
||||
top: ${({ $offset }) => $offset};
|
||||
`;
|
||||
|
||||
const SUPPORTED_PIXEL_RATIOS = [3, 2, 1];
|
||||
|
|
@ -37,7 +43,13 @@ const Icon: FC<IconProps & React.ImgHTMLAttributes<HTMLImageElement>> = (
|
|||
props
|
||||
) => {
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
const { $imgRef, src = "", ...componentProps } = props;
|
||||
const {
|
||||
$displaySize = 0,
|
||||
$imgRef,
|
||||
$imgSize = 0,
|
||||
src = "",
|
||||
...componentProps
|
||||
} = props;
|
||||
const style = useMemo<React.CSSProperties>(
|
||||
() => ({ visibility: loaded ? "visible" : "hidden" }),
|
||||
[loaded]
|
||||
|
|
@ -49,7 +61,17 @@ const Icon: FC<IconProps & React.ImgHTMLAttributes<HTMLImageElement>> = (
|
|||
src.startsWith("https:") ||
|
||||
src.startsWith("data:") ||
|
||||
src.endsWith(".ico");
|
||||
const { $imgSize } = props;
|
||||
const dimensionProps = useMemo(() => {
|
||||
const size = $displaySize > $imgSize ? $imgSize : $displaySize || $imgSize;
|
||||
const $offset =
|
||||
$displaySize > $imgSize ? `${$displaySize - $imgSize}px` : 0;
|
||||
|
||||
return {
|
||||
$height: size,
|
||||
$offset,
|
||||
$width: size,
|
||||
};
|
||||
}, [$displaySize, $imgSize]);
|
||||
|
||||
useEffect(
|
||||
() => () => {
|
||||
|
|
@ -63,26 +85,26 @@ const Icon: FC<IconProps & React.ImgHTMLAttributes<HTMLImageElement>> = (
|
|||
ref={$imgRef}
|
||||
onLoad={() => setLoaded(true)}
|
||||
src={isStaticIcon ? src : undefined}
|
||||
srcSet={!isStaticIcon ? imageSrcs(src, $imgSize, ".png") : undefined}
|
||||
srcSet={!isStaticIcon ? imageSrcs(src, $imgSize || 1, ".png") : undefined}
|
||||
style={style}
|
||||
{...componentProps}
|
||||
{...dimensionProps}
|
||||
/>
|
||||
);
|
||||
|
||||
if (isStaticIcon) return RenderedIcon;
|
||||
|
||||
return (
|
||||
<picture>
|
||||
{SUPPORTED_PIXEL_RATIOS.map((ratio) => (
|
||||
<source
|
||||
key={ratio}
|
||||
media={
|
||||
ratio > 1 ? `screen and (min-resolution: ${ratio}x)` : undefined
|
||||
}
|
||||
srcSet={imageSrc(src, $imgSize, ratio, ".webp")}
|
||||
type="image/webp"
|
||||
/>
|
||||
))}
|
||||
{!isStaticIcon &&
|
||||
SUPPORTED_PIXEL_RATIOS.map((ratio) => (
|
||||
<source
|
||||
key={ratio}
|
||||
media={
|
||||
ratio > 1 ? `screen and (min-resolution: ${ratio}x)` : undefined
|
||||
}
|
||||
srcSet={imageSrc(src, $imgSize, ratio, ".webp")}
|
||||
type="image/webp"
|
||||
/>
|
||||
))}
|
||||
{RenderedIcon}
|
||||
</picture>
|
||||
);
|
||||
|
|
|
|||