(Next.js) 我该如何在 next/image 中更改 SVG 的颜色?

29
import Image from 'next/image'

...

<Image src="/emotion.svg" alt="emtion" width={50} height={50} />

我想改变next/image中SVG的颜色。

但在CSS中,

img {
  fill="#ffffff"
}

无法工作。

我该怎么解决?

7个回答

23
我建议您不要直接使用SVG文件,而是使用Playground SVG(https://react-svgr.com/playground/)将文件转换为JS,然后可以通过props更改颜色和其他属性。

1
谢谢您的建议!我改用SVG方法了。 - Dann1y
1
我想知道这样做的好处。 - labs
当然,@labs,通过这样做,您可以在SVG内部使用状态,例如,如果您想通过悬停SVG来触发某些操作。 - Andres Campuzano Garzon
1
很酷,但在性能方面呢? - labs
2
这对我来说是迄今为止最好的解决方案。不需要疯狂的配置,只需将SVG制作成优化的React组件即可。它甚至支持TypeScript。 - James Hubert

12

我认为这里最好的解决方案不是使用Image。默认情况下,nextjsImage组件不会对svg进行任何优化。然后您将有多个选项/解决方案可供选择:

  1. 通过@svgr/webpack在您的next.config.js文件上扩展 webpack 配置:
// next.config.js

webpack(config) {
  config.module.rules.push({
    test: /\.svg$/,
    use: ["@svgr/webpack"]
  });

  return config;
}

// The file where u want to import the svg
import YourSvg from './public/yourSvg.svg'

// I recommend using the `currentColor` property on your svg, but you can also pass the color as prop
<YourSvg color="red" />


使用 babel-plugin-inline-react-svghttps://github.com/vercel/next.js/discussions/20993#discussioncomment-760119 enter image description here

我不明白为什么Nextjs在这方面表现得如此糟糕。但还是谢谢你的确认! - NickW

7

2
这个答案指引了我正确的方向。谢谢!对于任何想要了解更多细节的人,请参考此SO线程:https://dev59.com/gmEh5IYBdhLWcg3wk0Sz#53336754 - 99darshan

1

不要直接使用SVG文件,而是将其转换为React组件。这种方法可以消除复杂的配置需求。

转换方法:

  1. 使用transform.tools将SVG转换为React组件。
  2. 在SVG的JSX代码中,将所有的fill属性设置为"currentColor"。这样可以通过React props来改变颜色。

优势:

  • 通过props直接控制SVG的属性,如颜色、高度和宽度。
  • 简化设置,无需额外的Webpack或Babel配置。

使用Tailwind的示例:

<SVGIcon className="w-4 h-4 text-white" />

通过按照以下步骤操作,您将能够更轻松、灵活地管理您的 Next.js 项目中的 SVG 文件。
致谢:本信息基于 Andres Campuzano Garzon 的回答洞察得出。

1
<Link href={"/setting"} className="h-fit w-fit">
    <Image className="dark:invert"
        src={"/setting.svg"} alt={"setting.svg"} width={80} height={80} />
</Link>

只需在tailwind css中使用invert

0
将filter属性应用于组件的style属性。
import Image from 'next/image'
...

<Image src="/emotion.svg" alt="emtion" style={{ filter: 'invert(100%)' }} width={50} height={50} />

如果你想使用反转滤镜给SVG图标添加蓝色,你可以相应地修改滤镜属性。在这种情况下,你想要反转颜色,也就是将黑色区域变为白色,将白色区域变为黑色。为了实现蓝色效果,你需要再次反转这些颜色。
<Image src="/emotion.svg" alt="emtion" style={{ filter: 'invert(100%) sepia(100%) saturate(10000%) hue-rotate(180deg)' }} width={50} height={50} />

你可以调整棕褐色、饱和度和色相旋转的值来微调蓝色,使其符合你的喜好。例如,减小饱和度值会使颜色变得不那么强烈,而改变色相旋转的值则会调整蓝色的色调。

抱歉,但这并不是改变颜色,而是应用了一个滤镜。 - NickW
它通过应用滤镜来改变颜色。看起来有点丑,但它确实有效。这个答案提供了更多细节,包括一个可以将十六进制颜色转换为滤镜的生成器的链接:https://stackoverflow.com/a/53336754/1806628 - undefined

-1

嗯,我找到的解决方案是实用的。我编辑 svg 并更改颜色。当我在 vscode 中选择 svg 时,它会显示所有配置。

这个 svg 将变为粉色:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
 "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
 width="128.000000pt" height="128.000000pt" viewBox="0 0 128.000000 128.000000"
 preserveAspectRatio="xMidYMid meet">

<g transform="translate(0.000000,128.000000) scale(0.100000,-0.100000)"
fill="#D2485A" stroke="none">
<path d="M647 1233 c-13 -15 -17 -38 -17 -102 l0 -83 -84 -97 c-47 -53 -109
-123 -140 -156 l-55 -60 -1 58 0 57 -175 0 -175 0 0 -400 0 -400 175 0 175 0
0 31 c0 23 4 30 14 26 8 -3 57 -20 108 -38 l93 -33 265 -3 c300 -5 316 -2 354
72 17 33 18 43 8 81 -10 39 -9 48 8 76 22 36 26 98 9 129 -8 16 -5 26 15 50
28 33 35 93 16 129 -8 15 -4 27 15 56 30 44 32 88 5 131 -34 56 -61 63 -235
63 -106 0 -155 3 -155 11 0 6 7 36 16 66 25 85 17 198 -18 251 -52 78 -182
128 -221 85z m113 -85 c42 -29 70 -82 70 -133 0 -22 -13 -87 -30 -145 -16 -58
-30 -108 -30 -112 0 -5 87 -8 193 -8 158 0 197 -3 215 -16 40 -28 26 -80 -24
-90 -30 -6 -34 -10 -34 -39 0 -24 6 -34 24 -43 50 -22 41 -85 -14 -97 -25 -6
-30 -11 -30 -37 0 -20 8 -37 25 -50 27 -21 33 -59 12 -76 -6 -6 -24 -13 -40
-17 -23 -6 -27 -13 -27 -40 0 -25 5 -35 20 -40 24 -7 37 -51 23 -74 -9 -14
-44 -16 -279 -16 l-269 0 -107 39 -108 38 0 215 0 216 88 95 c262 286 262 285
262 379 0 82 6 87 60 51z m-480 -698 l0 -320 -100 0 -100 0 0 320 0 320 100 0
100 0 0 -320z"/>
</g>
</svg>

这里填充的地方我改变了颜色:

<g transform="translate(0.000000,128.000000) scale(0.100000,-0.100000)"
fill="#D2485A" stroke="none">

这是一条非常平滑的道路。不适用于90%的任务。我们经常需要从代码中访问svg属性。 - Денис Беспалов
是的,如果你只需要更改一次,这样做非常好;但是大部分情况下,你希望能够在JSX上直接自定义SVG的颜色。 - Iyxan23

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接