主要记录最近做的项目前端加载svg文件并且更改颜色的需求
使用drop-shadow
drop-shadow是css的filter提供的预定义效果的函数,能够输出图像的投影
- 与text-shadow和box-shadow不同
text-shadow为容器中的文字提供阴影效果,box-shadow为容器边框提供阴影效果,drop-shadow可以为图片中的图像提供投影效果
- 参数
drop-shadow(offset-x offset-y blur color)
为了实现更改颜色的需求,我们可以利用x方向上的偏移使投影图像与原图像不重叠,利用外层容器的overflow属性和图片元素的位置偏移形成更改图片颜色的效果
<div class="father">
<img src="./firefox-logo.svg" class="child">
</div>
.father {
width: 100px;
height: 100px;
overflow: hidden;
}
.child {
transform: translateX(100px);
filter: drop-shadow(-100px 0px 0px #558ABB);
}
通过以上代码我们能够获得一个纯色的与原图形状轮廓相同的图片,如下
通过绑定动态css,我们可以实现动态更改图片颜色
- 遗憾的是,尝试过使用渐变颜色,但是好像并不支持,也可能是没有用对
使用raw-loader
因为drop-shadow并不支持我们使用渐变的颜色,我们尝试通过raw-loader加载svg源码来实现,所以此方法只支持对于svg图片的颜色修改,而drop-shadow是支持除svg格式之外的png,jpg等格式的图片颜色修改的,两者有利有弊
- 思路
这种方法的思路主要是根据svg文件的颜色是通过fill来进行填充的,我们可以通过css对svg中节点的fill属性进行修改,而要实现渐变颜色,则需要定义一个渐变即<linearGradient>
或<radialGradient>
并填充
-
项目配置 在项目中安装raw-loader依赖,并配置对svg文件使用raw-loader加载,在项目中只需要对一部分svg文件加载源文件,可做类似如下配置
config.module .rule('svgicon') .test(/\.(svg)(\?.*)?$/) .include.add(path.resolve(__dirname, 'src/assets/images/svg')) .end() .use('raw-loader') .loader('raw-loader') .end(); config.module .rule('svg') .exclude.add(path.resolve(__dirname, 'src/assets/images/svg')) .end() .use('file-loader') .end();
-
加载图片
<div v-html="url" class="my-svg-icon"></div>
url() { let icon = ''; try { icon = require(`@/assets/svg/${可变名称}.svg`); } catch (e) { // 在加载图片出错时加载一张默认图片 icon = this.defaultImg; } if (icon.default) { icon = icon.default; } if (icon.includes('</svg>') || icon.includes('.svg')) { return icon; } }
至此我们完成了加载svg文件源码到我们的页面上
-
填充颜色 了解过svg的基础知识就知道svg元素具有属性fill,决定元素的颜色,普通纯色可以直接赋值,但是要使用渐变颜色,需先定义渐变再使用
<svg style="width:0;height:0;position:absolute;" aria-hidden="true" focusable="false"> <linearGradient id="linearGradient" x2="0" y2="1"> <stop offset="0%" stop-color="#FFB546" /> <stop offset="100%" stop-color="#FF9901" /> </linearGradient> </svg>
::v-deep.my-svg-icon path { fill: url(#linearGradient); }
在存在很多种渐变方案时我们可以选择把所有渐变写在一个vue文件里,并加载到使用svg的父文件中,避免多次渲染 当然也可以使用js动态生成
linearGradient
2021-03-26