【译】using-svg

译文出自:闪电矿工翻译组

原文地址:using-svg

原文作者:Chris Coyier

仓库原文链接:using-svg

译者:chenmf

SVG是一种向量图的图片格式,即可伸缩向量图(Scalable Vector Graphics),可以在Adobe Illustrator里面生成。在Web中使用SVG很简单,但是也有一些需要知道的事情。

为什么用SVG

  • 压缩后文件体积小
  • 可以无损伸缩到任意尺寸(除非尺寸特别小)
  • 在retina屏幕上可以完美显示
  • 设计可控,比如交互和滤镜

怎么生成SVG

可以在Adobe Illustrator里设计并且得到SVG。下面是一个站在椭圆上的奇异鸟:

留意到画板刚好贴着设计主体的边缘,画布的大小在SVG里面的重要性和在PNG和JPG里面是一样的。 然后可以直接在Adobe Illustrator里面保存成SVG文件。

保存的时候,可以在duihua对话框里面选择SVG选项。完整的参考可以看SVG 介绍。这里选SVG 1.1就可以了。

当点击'OK'或者'SVG Code...'的时候,就会打开文本编辑器,显示SVG的编码。

<img>标签里面使用SVG

如果把SVG保存成文件之后,可以直接在<img>标签里面使用。

HTML
<img src="kiwi.svg" alt="Kiwi standing on oval">
复制代码

在Illustrator里面,画板的大小是612px ✕ 502px:

这正是图片在页面中的大小。可以选择 <img>标签并且改变 widthheight来改变它的尺寸,就像PNG和JPG一样,比如:

前往codepen查看

浏览器支持

<img>标签里面使用需要有浏览器支持。基本上在IE8以上和Android 2.3以上都可以用。 如果你想要在不支持的浏览器里面使用,可以这样:

  1. 使用Modernizr来替换<img>src属性:
jQuery

if (!Modernizr.svg) {
  $(".logo img").attr("src", "images/logo.png");
}
复制代码
  1. David Bushell提供了一个更简单的操作:
HTML

<img src="image.svg" onerror="this.onerror=null; this.src='image.png'">
复制代码
  1. 使用SVGeezy

background-image里面使用SVG

可以在CSS的background-image里面使用SVG。

HTML

<a href="/" class="logo">
  Kiwi Corp
</a>
复制代码
CSS

.logo {
  display: block;
  text-indent: -9999px;
  width: 100px;
  height: 82px;
  background: url(kiwi.svg);
  background-size: 100px 82px;
}
复制代码

注意把background-size设置成我们想要的尺寸,否则只能看到很大的原始SVG图片的左上角。这个尺寸设置成了跟原始尺寸保持宽高比,如果在不知道原始尺寸的情况下想要保持宽高比,可以把background-size设置成contain

浏览器支持

background-image里面使用SVG也需要看浏览器支持,基本上跟在<img>中使用是一样的。

如果要在不支持的浏览器里面使用:

  1. 用Modernizr把background-image替换成一个支持的格式。它会在不支持SVG的情况下加上一个no-svg的class,注意它也是只会发送一个图片的HTTP请求,不会发两个。
CSS

.main-header {
  background: url(logo.svg) no-repeat top left;
  background-size: contain;
}

.no-svg .main-header {
  background-image: url(logo.png);
}
复制代码
  1. 另一个更方便的方法,就是利用多个背景(background),SVG的浏览器支持和多背景的很接近。
CSS

body {
  background: url(fallback.png);
  background-image: url(image.svg), none;
}
复制代码

使用<img>background-image的问题

<img>background-image里面使用SVG,没法利用CSS对SVG内部进行控制,所以接着看下面的两种其他方式。

使用内联(inline)SVG

在保存SVG的时候可以获取SVG的代码(也可以直接在文本编辑器里面打开SVG文件),直接把SVG的代码复制到HTML里面:

HTML

<body>

   <!-- 把SVG的代码复制到这里就可以显示图片了  -->

</body>
复制代码

这样做的好处是把图片的内容直接写在文档里面,不需要额外发送HTTP请求获取,它和使用Data URI的好处是一样的,坏处也一样:导致文档变得臃肿,难以抓取和缓存。

如果使用后端语言的话,可以获取文件并且插入到文档:

PHP

<?php echo file_get_contents("kiwi.svg"); ?>
复制代码

说到PHP,这里用file_get_contents()方法比较合适,而不是include()include_once(),因为SVG有时候会以<?xml version="1.0" encoding="UTF-8"?>开头,导致PHP编译有问题。

先优化SVG

Adobe Illustrator里面导出的SVG可能不是最优的,会包含一些冗余信息,比如DOCTYPE和生成信息。我们可以进一步优化,减少体积。Peter Collingridge给出了在线的SVG 优化,把需要优化的SVG上传,然后下载新的就可以了。 如果你是硬核玩家,可以直接用这个NodeJS工具自己优化。

用CSS来控制SVG

SVG的代码看起来是不是很像HTML?因为它们都是基于XML的。我们的SVG里面包含了两个元素:<ellipse><path>,可以直接在代码里面给它们加上class,就像HTML元素一样:

SVG

<svg ...>
  <ellipse class="ground" .../>
  <path class="kiwi" .../>
</svg>
复制代码

然后就可以用特殊的SVG CSS来控制这些元素了。SVG元素由着特殊的CSS属性,比如它没有background-color,而是用fill,但是也可以使用一些其他的普通属性,比如:hover

CSS

.kiwi {
  fill: #94d31b; 
}
.kiwi:hover {
  fill: #ace63c; 
}
复制代码

更厉害的是,SVG可以使用滤镜(filter),比如模糊滤镜。比如在SVG代码里面可以加上一个滤镜:

SVG

<svg ...>
  ...
  <filter id="pictureFilter" >
    <feGaussianBlur stdDeviation="5" />
  </filter> 
</svg>
复制代码

然后可以在CSS里面使用这个滤镜

CSS

<svg ...>
  ...
  <filter id="pictureFilter" >
    <feGaussianBlur stdDeviation="5" />
  </filter> 
</svg>
复制代码

下面是一个完整的例子:

前往codepen查看

更多阅读:

浏览器支持

内联SVG的浏览器支持看这里,基本和前面的一样。兼容的方法:

HTML

<svg> ... </svg>
<div class="fallback"></div>
复制代码
CSS

.fallback { 
  display: none;
  /* Make sure it's the same size as the SVG takes up */
}
.no-svg .fallback { 
  background-image: url(logo.png); 
}
复制代码

<object>里面使用SVG

如果想要通过CSS控制SVG,但是又想避免内联SVG的弊端,可以在<object>里面使用SVG。

HTML

<object type="image/svg+xml" data="kiwi.svg" class="logo">
  Kiwi Logo <!-- fallback image in CSS -->
</object>
复制代码

同样可以使用Modernizr来兼容:

CSS

.no-svg .logo {
  width: 200px;
  height: 164px;
  background-image: url(kiwi.png);
}
复制代码

这种情况下,如果想要用CSS控制SVG,就不能用外部的样式或者文档里面的<style>了,要用SVG文件内部的<style>:

SVG

<svg ...>
  <style>
    /* SVG specific fancy CSS styling here */
  </style>
  ...
</svg>
复制代码
<object> SVG里使用外部样式

可以在SVG文件开头的<svg>标签前面引入:

HTML

<?xml-stylesheet type="text/css" href="svg.css" ?>
复制代码

如果把这个放在HTML里面,页面会崩溃没法渲染,如果把这个放在<img>或者background-image的SVG里面,页面不会崩溃,但是也不起作用。

在Data URL里面使用SVG

还可以把SVG转换成Data URL,转换之后可能不止原来的文件大小,但是它很方便,因为不需要额外产生网络请求。 Mobilefish.com上面有一个base64在线转换器,可以转成base64编码,但是这种方式不太推荐。记得去掉换行:

它可以在上述的所有场景里面使用,除了内联SVG。

个人比较推荐这个在线转换器,因为转换之后可读性比较强。

  • 用在<img>里面
HTML

<img src="data:image/svg+xml;base64,[data]">
复制代码
  • CSS里面
CSS

.logo {
  background: url("data:image/svg+xml;base64,[data]");
}
复制代码
  • <object>里面
HTML

<object type="image/svg+xml" data="data:image/svg+xml;base64,[data]">
  fallback
</object>
复制代码

如果,SVG在base64编码之前有嵌套的<style>,那么它依然可以在<object>里面起作用。

Data URI格式

上面的例子都是base64编码的,但是也不一定要转换成base64编码,实际上对于SVG最好不要转成base64编码。因为SVG的原始格式文本重复性比较高,gzip压缩效果更好。

HTML

<!-- base64 -->
data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL...

<!-- UTF-8, not encoded -->
data:image/svg+xml;charset=UTF-8,<svg ...> ... </svg>

<!-- UTF-8, optimized encoding for compatibility -->
data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://...'

<!-- Fully URL encoded ASCII -->
data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A//...
复制代码
自动化工具

从CSS的角度来看比较易用,为每个icon生成一个class,不用CSS sprites。grunticon输入一个SVG/PNG文件的目录,然后输出对应的3种格式的CSS:SVG data url,png data url和一个引用普通的png图片的兼容性CSS文件。

一个PHP命令行工具,把SVG图片转换成CSS icon,支持图片优化和SASS输出。

相关参考

转载于:https://juejin.im/post/5d06e14fe51d4510617210c5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用 `react-native-svg` 和 `react-native-svg-transformer` 加载本地 SVG 图像,你可以按照以下步骤进行操作: 1. 首先,确保你已经在项目中安装了 `react-native-svg` 和 `react-native-svg-transformer` 依赖。你可以通过运行以下命令来安装它们: ``` npm install react-native-svg react-native-svg-transformer ``` 2. 在项目的根目录下创建一个名为 `metro.config.js` 的文件(如果已存在,请跳过此步骤)。 3. 在 `metro.config.js` 文件中添加以下内容: ```javascript module.exports = { transformer: { assetPlugins: ['react-native-svg-transformer'], }, }; ``` 4. 接下来,在你的组件中,使用 `react-native-svg` 中的 `<SvgUri>` 组件来加载本地 SVG 图像。首先,确保你的 SVG 图像位于项目的 `assets` 文件夹中。 ```javascript import React from 'react'; import { View } from 'react-native'; import SvgUri from 'react-native-svg-uri'; const MyComponent = () => { return ( <View> <SvgUri width={200} height={200} source={require('./assets/myImage.svg')} /> </View> ); }; export default MyComponent; ``` 在上面的示例中,我们使用 `require` 方法加载位于 `assets` 文件夹中的 `myImage.svg` 图像,并将其作为 `source` 属性传递给 `<SvgUri>` 组件。你可以根据自己的需要调整宽度和高度。 5. 确保你在重新启动 Metro Bundler 之前完成了以上步骤。你可以通过运行以下命令重新启动 Metro Bundler: ``` npx react-native start --reset-cache ``` 这样,你就可以使用 `react-native-svg` 和 `react-native-svg-transformer` 成功加载和显示本地 SVG 图像了。 希望对你有所帮助!如有任何疑问,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值