✨
blog
  • Blog
  • Element-UI
    • 2019-09-04
  • JS
    • ES6 之 Set 和 Map
    • let 和 const 声明常见概念
    • 元编程
    • ES6之字符串的扩展
    • ES6 之异步流程的前世今生(上)
    • ES6之异步流程的前世今生(下)
    • ES6 之模块你知吗
    • ES6 之解构赋值与箭头函数的妙用
    • 迭代器
    • ES5 之原型(一)
    • ES6之类(二)
    • es7之装饰器
    • es6之数组详解
    • js之this指向
    • 对象
    • vue项目配合使用canvas联动
    • 本文解决痛点:对象里面是否有值
  • MAC
    • vue源码之method
    • Mac的使用技巧
    • 前文
    • Mac常用软件(二)
    • 如何查看 Mac 端口号以及占用情况
  • Node
    • Node之Buffer详解
    • 浏览器与 node 的事件循环(event loop)有何区别
    • Node之多线程
    • node之模块解析(一)
    • 错误捕获与内存告警
  • TS
    • Record
    • 使用方法
    • 工具泛型
    • 类型体操
    • 泛型
  • chrome
    • v8 引擎
    • v8 垃圾回收机制
    • 浏览器的知识
  • flutter
    • 路由
    • 页面布局
  • go
    • index
  • html&css
    • 两栏布局
    • ES5和ES6的区别
    • ES5 和 ES6 的区别
    • HTTP详解
    • TCP 与 UDP 的区别
    • MDN
    • css modules 使用教程
    • css 居中
    • 拖拽
    • flex布局
    • h5 新增特性 html5
    • history 与 hash 路由策略
    • position 定位方式
    • rem布局
    • svg
    • web性能优化
    • 事件循环
    • 从输入网址后发生了什么
    • 前端状态管理
    • 圣杯布局与双飞翼
    • 性能优化 页面的性能统计指标
    • 本地存储的几种对比
    • 浏览器的渲染进程
    • 浏览器缓存策略详解
    • 盒模型
    • 为什么要移动端适配
    • 跨域的 N 种实现方式
  • web3
    • 常见概念
    • vue项目配合使用canvas联动
  • webgl
    • Mac使用技巧(二)
    • Node之模块解析path
  • 代码库
    • documeng的一些常见操作
    • eventBus事件
    • jquery提交
    • jquery的一些常见操作
    • 常见操作
    • 数组polyfill
    • TS代码片段
      • 面试官眼中的test unit
  • 全年安排
    • AfterShip
    • 大企业
  • 函数编程题
    • Promise问题
    • 继承
  • 前端早早聊
    • vue生态
    • 开发一款VScode语言插件
    • 简历回顾和进行复盘
    • 重新认知性能优化及其度量方法
    • 2022-09-17-音视频专场.md
      • 2022-09-17-音视频专场
    • 前端晋升专场
      • 成长的诀窍是靠自己
      • 销销帮
    • 前端监控专场
      • 字节前端监控实践
      • 李港:大前端-从无到有搭建自研前端监控系统
    • 前端跳槽
      • 50个面试官在线招聘
      • 如何识别优秀的前端猎头来跳槽大厂
      • 面试套路
    • 支付宝
      • 面试
    • 管理专场
      • 芋头:管理者眼中的web技术发展前沿
    • 组件专场
      • 基于webCompents的跨技术组件库实践
    • 面试
      • 面试辅导问题
      • 早早聊面试
      • 前端沙箱是什么? 怎么实现沙箱环境?
  • 常见总结
    • 2018年终总结-年底了,你总结了吗?我先来
    • 在逆境中成长
    • 2021年终总结
    • 2024年全年总结
    • 项目
    • Tell2.0 前端复盘
    • 复盘
    • 前端工程师素养
    • 学习方法论
    • 希望与破晓| 2022 年终总结
    • 新起点, 新征途 | 掘金年度征文
    • 稳定| 2023 年终总结
    • 趁着有风快飞翔 | 2019 年终总结
    • AfterShip
      • Emotion:用 JavaScript 编写 CSS 的强大工具
      • 个人中长期目标
      • 事故复盘
      • 时间解析
      • 国内外区别
      • 独立站建设
    • MEIZU
      • NativeApp与H5通信原理
      • SSR 原理
      • SSR的常见问题
      • CLI
      • electron 应用发布流程
      • electron
      • electron 面试
      • 数据结构与算法之美
      • mgc 一期复盘
      • 架构原理
      • 喵币管理
      • 三期复盘总结
      • 异常监控之 sentry 实践
      • 微前端
      • qiankun 原理解析
      • 快游戏一期
      • 游戏中心复盘
    • 个人准则
      • index
    • 编程猫
      • pc 接入 micro bit 方案
      • prompt engineer
      • web work 跨域解析与解决方式
      • web 中的 ai
      • 低版本 node 环境下 ffmpeg 的使用
      • 关于 taobao 源 https 过期
      • 加密 json
      • 安卓 5 和 6 的白屏解决
      • 性能排查与优化实践
      • 探月接入
      • 接入硬件
      • 新生态下的state
      • monorepo 包管理方式
      • 自修复 npm 库
      • 音频的绘制
    • 谨启
      • 音视频
      • 小程序
        • taro 规范
        • 结合 mobx 在跳转前预请求
        • Taro 浅析用法与原理
        • 前文
        • 小程序优化指南
        • 小程序内部实现原理
        • 支付相关
    • tencent
      • TAPD
        • MathJax的食用
        • canvas渲染优化策略
        • 为什么 JavaScript 是单线程的呢?
        • svg 总是不对
        • 前端库
        • 原生端和js端如何通信
        • 在旧项目中复用vue代码
        • 提升自我
        • 批量编辑优化
        • 插入业务对象
        • 编辑器
        • 挂载点
        • 性能优化对比
        • 遇到的问题
        • 项目迁移公告
        • 领导力
      • 行家
        • 实战篇
        • 职业发展、领导力、个人成长
        • 高质量沟通
  • 慕课网
    • react-native原理
    • react-native学习
  • 杂文
    • Dom 节点变动检测并录制的简单实现
    • 错误监控&错误捕获
    • NextJS与NuxtJS
    • 负载均衡的几种常用方式
    • PM2
    • service worker 控制网络请求?
    • SSL 和 TLS 的区别
    • Babel 你太美
    • echart踩坑经验
    • keyup、keydown你都知道有什么区别吗
    • 常见概念
    • 首屏加载优化与性能指标分析
    • preload 和 prefetch 的详解
    • 在项目中配置这几个关系
    • roullp 解析
    • tinymce原理浅析
    • wasm 在前端的应用
    • websocket
    • webworker
    • 项目
    • 从 ajax 到 axios
    • 从postcss 到自己开发一款插件
    • 从输入浏览器到页面展示涉及的缓存机制
    • 代码整洁之道
    • 你知道什么是aop吗
    • 函数式编程
    • 函数式编程指南
    • 前端input框文字最大值
    • 攻坚战
    • 前端书写 sdk
    • 前端文字转语音播放
    • 前端领域的 Docker 和 Kubernetes
    • 前端安全
    • 前端进阶之内存空间
    • 前端音频浅析
    • 十分钟搞定多人协作开发
    • 字符串的比较
    • 尾递归
    • 前文
    • 常见的算法可以分为以下三类
    • 手机调试--mac篇
    • 数组的原生系列
    • COOP 和 COEP - 新的跨域策略
    • 浅谈react组件书写
    • 浏览器与 Node.js 事件循环的区别
    • 由三道题引伸出来的思考
    • 移动端300ms点击延迟
    • 移动端和pc端事件
    • Git 常见疑惑
    • 我们离发 npm 包还有多远
    • 重绘和重排
    • AI 时代下的前端编程范式
    • 音频可视化实战
  • 极客时间
    • Serverless入门课
    • 二分查找
    • 二叉树
    • 全栈工程师
    • 动态规划面试宝典
    • 前端与rust
    • 散列表
    • 前端方面的Docker和Kubernetes
    • 栈
    • 深入浅出区块链
    • 玩转 vue 全家桶
    • 玩转 webpack
    • 程序员的个人财富课
    • 算法
    • 说透元宇宙
    • 跳表
    • 链表
    • 10x 程序员工作法
      • index
    • Node开发实战
      • HTTP服务的性能测试
      • JavaScript语言精髓与编程实战
      • 什么是node。js
      • svg精髓
    • ReactHooks核心原理与实战
      • ReactHooks核心原理与实战
    • Rust
      • Rust编程第一课
      • 前置篇
      • 深度思维
      • 重构
      • 类型体操
      • 基础知识
    • WebAssembly入门课.md
      • 基础篇
      • SSR的注水和脱水
      • jsBriage通信原理
      • 基础知识篇
    • 互联网的英语私教课
      • 互联网人的英语私教课
    • 代码之丑
      • 代码之丑
    • 前端全链路优化实战课
      • 网页指标
    • 图解 Google V8
      • 图解 Google V8
    • 浏览器工作原理与实践
      • 浏览器工作原理与实践
    • 算法面试通关 40 讲
      • 算法面试通关40讲
    • 跟月影学可视化
      • index
    • 软件设计之美
      • 软件设计之美
    • 重学前端
      • js
  • 后续的文件增加都会增加到上面并以编号对应
    • 1029. 两地调度
    • 151.翻转字符串里的单词
    • 2022.3.15
    • 前端数据结构
    • 前端常见算法
    • 前端常见排序
    • 恢复一棵树
  • 设计模式
    • 前端常见设计模式之MVC与MVVM
    • 前端之代理模式
    • 前端常见设计模式之单例模式
    • 前端常见设计模式之发布订阅模式
    • 前端之工厂模式
    • 观察者模式
    • 前端常见设计模式之适配器模式
  • 译文
    • [译] 如何使用CircleCI for GitHub Pages持续部署
    • 您是否优化了 API 的性能
    • [译][官方] Google 正式发布 Flutter 1.2 版本
    • 什么是 Deno ,它将取代 NodeJS ?
  • 读后感
    • JavaScript二十年
    • 1368个单词就够了
    • js编程精解
    • labuladong 的算法小抄
    • lodash常用方法
    • vue的设计与实现
    • 所有的静态资源都是get请求
    • 人生
    • 人生护城河
    • 你不知道的JavaScript
    • 前端核心知识进阶
    • 华为工作法
    • 反脆弱
    • 好好学习
    • 左耳听风
    • 摩托车维修之道
    • 数学之美
    • 深入理解svg
    • 浏览器的ESM到底是啥
    • 经济学原理
    • 编程珠玑
    • 防御式 css 精讲
    • 韭菜的自我修养
  • 雪狼
    • 2022-07-17
    • 基础知识
    • 阶一课程
      • 实战辅导一
      • 实战辅导二
  • 嵌入式
    • 树莓派
      • 排序
  • 源码
    • React
      • 核心知识点
      • errorBoundaries
      • immutable.js 的实现原理
      • React.Suspense
      • react源码分析之Fiber
      • batchedUpdate
      • Component
      • Context
      • react 源码分析之 diff 算法
      • React 中的 key 属性:原理、使用场景与注意事项
      • 使用方式
      • react源码分析之memo
      • react 源码分析之mixin
      • 实战篇
      • react源码分析之react-dom
      • 使用方式
      • scheduleWork
      • useImperativeHandle的使用与原理
      • React 书写小技巧
      • 入口和优化
      • 合成事件和原生事件的区别
      • react 性能优化
      • 构建一个 hooks
      • 浅析 styled-components
      • 生命周期
      • 组合 vs 继承
      • 通信机制
      • 高阶组件
      • 慕课网
        • 应用篇
        • 课程导学
    • ReactHook
      • useCallback
      • useContext
      • useEffect 与 useLayoutEffect
      • useHook
      • useMemo
      • useReducer
      • 原理
      • useState
      • 总结
    • Redux
      • mobx 原理解析
      • redux-saga
      • redux-thunk
      • Mobx 和 Redux 对比
      • 使用方法
      • redux 原理
    • Vite
      • Vite原理
      • Vite配置
      • 热更新原理
      • vite 为什么生产环境用 Rollup
    • Webpack
      • PostCSS
      • Webpack5 核心原理与应用实践-loader
      • Webpack5 核心原理与应用实践-plugin
      • Webpack5 核心原理与应用实践
      • 区分
      • 升级详情
      • treeShaking(树摇Tree Shaking)
      • 编写一个自己的webpack插件plugin
      • 代码分离(code-splitting)
      • webpack 打包优化
      • 基础配置
      • webpack 打包优化
      • webpack 工作原理
      • webpack 按需加载原理
      • webpack 热更新 HMR(Hot Module Replacement)
      • 缓存
      • webpack 自定义 plugin
    • next
      • tailwind
      • 什么是水合
    • sveltejs
      • index
    • tinymce
      • 并发篇
    • 源码手写系列
      • create
      • call
      • bind
      • call
      • es6 单例
      • forEach vs Map
      • instanceOf
      • new
      • reduce
      • 取两个重复数组的交集
      • 函数柯理化
      • 动态规划
      • 基于Generator函数实现async
      • 新建 js 文件
      • 手写一个 slice 方法
      • 手写一个 webpack loader
      • Plugin
      • 手写一个寄生组合式继承
      • 二叉树
      • 链表相关的操作
      • 手动实现发布订阅
      • 数组去重
      • 数组扁平化
      • 数组
      • 构造大顶堆和小顶堆
      • 深浅拷贝 深拷贝
      • 两者对比
    • vue
      • vue2
        • vm.attrs与$listeners
        • vue 和 react 的 diff 算法比较
        • vue 源码分析
        • vue 优化的 diff 策略
        • extends
        • 核心原理篇
        • keep-alive
        • vue 源码分析之 mixins
        • vue 源码分析之 nextTick
        • vue之slot
        • vnode
        • vue 源码分析之 watch
        • 原理
        • vue 源码分析之transition
        • vue 源码分析之异步组件
        • 调用的是 watch
        • 安装
        • react源码分析之portals
        • event 的实现原理(事件的实现原理)
        • 什么是h
        • 分析provide 和 inject
        • vue 源码分析之 use
        • v-model
        • vue源码分析之vuex
        • 响应式原理
        • 初始化的流程
        • 组件更新
        • 编译
        • 父子组件生命周期
        • 原理
        • 多实例
        • Vue 面试
        • 源码研读一
        • 响应式原理
        • 常见问题
        • 数组的劫持
        • vue之自定义指令
        • 运行机制全局概览
      • vue3相比vue2的提升点
        • vue composition api
        • vue3的虚拟dom优化
        • vue3层面的双向数据绑定
        • 预处理优化
  • 重构
    • notification
      • 讲解
  • 面试
    • AfterShip经历
      • JS对URL进行编码和解码
      • ShippingLabelTemplate
      • 接入keycloak详解
      • reCAPTCHA接入
      • yalc与动态解决升级的依赖包
      • RBAC 简介
      • 多语言计划
      • 接入Google登录及其主动弹出快捷登录方式
      • 读书计划
        • 传染
        • 这就是OKR
    • 编程猫经历
      • 2024.1.16
      • 2025.2.20
      • 2025.2.21
      • 2025.2.26
      • 2025.3.28
      • 2025.3.3
      • 2025.3.7
      • 行动轨迹
      • 面试主观题
    • 腾讯经历
      • 2022.02.21
      • 2022.03.30
      • 2022.04.24
      • 2022.04.25
      • 2022.04.27
      • 2022.04.28
      • 2022.04.29
      • 2022.05.05
      • 不同公司的面试关注点不同
      • 2022.05.07
      • 2022.05.09
      • 2022.05.10
      • 2022.05.11
      • 2022.05.12
      • 2022.05.13
      • 2022.05.16
      • 2022.05.17
      • 2022.05.19
      • 2022.05.27
      • 面试
      • 行动轨迹
      • 面试主观题
    • 针对字节
      • 2022.05.14
      • 2022.05.17
      • HR面试准备
      • Promise的相关题目
      • React 进阶实践指南(二)
      • React 面试准备
      • vue 与 react 有什么不同 (react 和 vue 有什么区别)
      • TypeScript 全面进阶指南
      • cookie和session区别
      • express 面试准备 koa 中间件原理
      • next面试准备
      • requestCallBack
      • interface 与 type 异同点
      • 取消 promise
      • 如何设计一个前端项目
      • 进阶篇
      • 早早聊面试准备
      • 自动化部署
      • 挖掘项目的深度
      • 面试
      • 出题指数
    • 魅族经历
      • 2020.09.11
      • 一灯
      • 一灯
      • 一灯
      • 2020.09.20
      • 2020.09.21
      • 网易二面
      • 2020.09.23
      • 头条
      • 360 金融面试题
      • 富途一面
      • 算法
      • 字节
      • 2020.11.04
      • baidu 一面
      • meta 标签的作用
      • 字节
      • 2020.11.22
      • 2020.11.25
      • 微前端接入笔记
      • 面试的基本原则
由 GitBook 提供支持
在本页
  • SVG 是 XML(有时也是 HTML)
  • SVG 是可压缩的
  • SVG 是有结构的
  • SVG 是有样式的
  • 2.1 使用 fill 属性进行填充
  • 创建颜色
  • 3.3 自定义颜色
  • 3.4 混合和搭配
  • 4.1 穿透样式
  • 4.2 其他效果
  • 5 渲染和壁纸
  • 5.2 标识资源
  • 7.2 对象边界盒
  • CSS 与 SVG 使用关键词来设置 CSS 渐变的位置

这有帮助吗?

  1. 读后感

深入理解svg

SVG 是 XML(有时也是 HTML)

意味着如果你忘记引入 XML 的命名空间或者 混淆了 XML 语法的重要细节,你的网页将什么都不显示。

然而,当你直接在 HTML5 标记中插入 SVG 时,它将由 HTML 解析器处 理。HTML 解析器会忽略一些错误(比如缺少结束标签或使用不带引号的 属性),而在 XML 解析器(或大多数仅支持 SVG 的图形编辑器)中这将导 致解析失败。它也会忽略自定义的命名空间,将不能识别的属性或标签名 变成小写,甚至引起其他不能预期的变化。

SVG 是可压缩的

在普通的文件服务器上存储压缩过的 SVG 时, 通常使用 .svgz 作为扩展名。

SVG 是有结构的

SVG 是有样式的

还可以使用媒体属性或瞬时状态等有条件的 CSS 样 式,比如 :hover 和 :focus。

浏览器会把 SVG 标记和样式转换成一个文档对象模型(document object model,DOM)。DOM 可以通过 JavaScript 进行操作

SVG 的渲染模型被称为画家模型。就像在墙上涂层,上层的内容会遮盖下 层的内容。

z-index 和 paint-order 这两个允许你改变渲染规则的属性。

2.1 使用 fill 属性进行填充

SVG 代码中的基本元素和属性可以精确地定义几何形状。

它的左上角就是坐标系的原点,代码如下所示: 创建一个直径为 10 厘米的圆,并把它放置在坐标系的中心,代码如下:

SVG 通常会被缩放,所以英尺、厘米等 长度单位不一定符合真实世界的距离。它会受到显示器的 分辨率、浏览器的缩放程度,当然还有 SVG 元素上添加的 viewBox 或 transform 等属性的影响。

SVG 无单位坐标通 常可以和 px 等价使用。

如果在你的 SVG 中仅仅包含一个圆或一个长方形的标记(或其他任何形状 或文本)而没有其他的样式信息,它将在你定义的尺寸内显示一个纯黑色 的区域。这是因为 fill 属性的默认值是纯黑色。

如果你不想让软件填充形状,可以把 fill 属性值设置为 none。

fill 属性(以及 stroke 属性)的最后一个可以设置的值是 currentColor 关键词。这一关键词通常被估算为给定元素的 CSS color 属性的当前值。 color 属性本身对 SVG 没有直接的影响,但是结合 currentColor,它将有 两个主要用途。

• 使内联的 SVG 图标与它周围的 HTML 文本颜色协调。color 属性的主要 用途是设置 CSS 样式文本的颜色。因此,使用 currentColor 值的内联 SVG 图形会继承周围 HTML 标记的文本颜色。 • 为重复使用的内容提供一个间接继承的样式值。使用 元素复制的 SVG 图形可以从使用它的上下文中继承 fill 和 stroke 等样式。给重复 使用的图形中的重要属性使用 currentColor,这样可以通过改变 元素上的 color 值来分开操作复用图形的 fill 和 stroke 的值。

默认情况下,fill 属性被渲染为纯色且不透明(除非在渲染服务中有不同 的指令)。可以通过给 fill-opacity 属性设定值来调整不透明度,它接受一 个小数作为值:0 到 1 之间的值会导致填充值和背景色混合起来渲染图形, 值为 1(默认值)时表示不透明,值为 0 时的效果相当于设置 fill 属性的 值为 none

当你不能确定图形的某一部分是在图形之内还是之外时,fill-rule 属性可 以给计算机发送精确的指令。它会影响内部有洞的 元素以及路径、 多边形和纵横交错的折线。

fill-rule 属性有两个可选值。

• evenodd 值的每一条边缘线都分隔开了图形的内部和外部。 • nonzero 值(默认值)是当你从头到尾沿着一个方向画交叉的边线时企 图得到“更多的内部空间”,并且只有你在图形内部沿着相反方向绘画来 撤销它们时才会返回图形外部。

SVG 中的每个图形和文本都可以被填充,且默认是填充的。这包括不闭合 的 元素和 元素,它们可以定义一个结束点不与起始点 相连的图形

中没有闭合的片段是通过连接到子路径的初始点来闭 合的: 最后的点是通过一个 move-to 命令创建的。

即使是一个 元素严格来说也是默认填充的: 因为连接终点与起始点 的返回线与原线完全重合,所以最后的形状不包括任何区域。形状内是没 有点的,所以没有点被填充值影响。如果你想看到它,就得给它加 stroke。

2.2 使用 stroke 属性描边

描边形状的每个部分都只会绘制一次,无论形状中是否存在 不同边重叠或交叉的部分。

stroke 的默认值是 none,即不渲染描边区域。就像 fill 属性一样,它的值 还可以是色值或渲染服务元素的引用。

stroke-width 描边宽度,即描边的粗细。其值可以是长度值、用户单位数或者坐标系 宽和高的加权百分比。在 SVG 1.1 中,描边区域通常以形状的边为中心, 所以描边的一半宽度在形状之内,一半在形状之外。 stroke-linecap 该属性用来给未闭合的路径或线条设置描边样式。其默认值 butt 会紧密 修剪描边并且与端点垂直。其他选项(round 和 square)会以特定形状 (即分别以半圆形和方形)使用一半的描边宽度来延伸描边。 stroke-linejoin 该属性用于指定在形状中拐角的描边样式。其默认值 miter 在直线上延 伸描边,直到两条边在某一点相汇。其他可选值是 round(使用圆弧来 连接两条描边)和 bevel(使用一根额外的直线连接两条描边)。 stroke-miterlimit 延伸斜接线可以超出形状边线的最大距离,是描边宽度的倍数(默认 是宽度的四倍)。如果描边在这个距离之内没有汇合,则使用 stroke- linejoin 值为 bevel 时的效果。 stroke-dasharray 定义给形状间断描边时的距离模式(线和间隔)。其默认值 none 会给 整个形状添加连续的描边。每一条线的端点都受 stroke-linecap 值的 影响。 stroke-dashoffset 定义间断描边时起始偏移的距离。默认值是 0。

2.3 层叠描边和填充

当一个图形同时拥有填充属性和描边属性时,描边区域和填充区域会有一 部分重合的地方,因此重合部分会有两种特定的颜色。在所有的 SVG 中, 画家模型都适用: 如果两种颜色都是不透明的,则上层的颜色将会替换下 层的颜色。

默认情况下,描边是渲染在填充层之上的。这意味着你通常可以看到整个 描边宽度,也意味着如果描边是半透明的话,将显示出两种颜色。填充的 颜色将会出现在描边区域内部一半之下而不是外部一半之下。

<g stroke="blue" fill="red">
  <g fill="none">
    <path id="shape" d="..." />
  </g>
  <use xlink:href="#shape" stroke="none" />
</g>

前面的代码片段使用了大量继承的样式。

  1. 本身没有设置任何的 fill 和 stroke 属性,而是从它的外层继承的。

  2. 总的 stroke 和 fill 属性设置在 外层的 元素上,之后在嵌套的组和 元素上分别抵消了 fill 属性 和 stroke 属性。

在 svg2 中引入了 paint-order 属性。它使用空 格分隔的关键词(stroke、fill 以及 markers)列表来指示图形的各部分被 渲染的顺序。所以可以用单个元素实现相同的效果: 你在 paint-order 属性中没有定义的渲染层将会在之后渲染(本例中的 画家模型 | 15

markers),并按照它们本来的顺序渲染。这意味着如果你想调换 fill 和 stroke 的顺序,仅需要定义 stroke 就可以了。 stroke 将会最先被渲染,然后是 fill,最后是 markers。整个填充区域将 始终可见,即使是与描边重叠的地方。

paint-order 的默认值(等于 fill stroke markers)可以用 normal 关键词 显式地设置。

一种解决方式是使用 CSS 的 @supports 条件规则来控制只有在支持 paint- order 属性时才添加轮廓效果。

样式从表现属性上移到了 style 代码块 中,这样就可以使用 CSS 的条件规则了。基本的样式是在不能控制渲染顺 序的时候提供更细的描边,在 @supports 块中使用粗的描边和 paint-order 属性来覆盖基本样式。

图 2-3 和图 2-5 之间 stroke-width 的值被裁掉一半还多。但 是图 2-5 中描边仅仅略微窄一点,这是因为描边内部的一半 在填充之上是可见的。

如果你不能接受使用 @supports 来改变展现规则,唯一的替代方案就是复 制两个相同的元素,一个用来描边,一个用来填充。

SVG 文档中的层级是按照代码中元素定义的顺序排列的: 形状、文本和图 片都会按照标记定义的确切顺序来分层。在 SVG 1.1 中,改变元素渲染顺 序的唯一方式是改变元素在 DOM 中的顺序。

• 它会迫使你打破内容在逻辑上的分组。例如,如果不使用 元素来把 文本和它描述的图形分组,你通常需要把文本标记移到文件的最后,这 样才不会被其他形状遮挡。 • 你不能通过使用 SMIL 或 CSS 动画来改变看到的层级。你必须通过 JavaScript 来操作 DOM,这可能会带来性能问题或中断用户输入的焦点。

SVG 2 中采用 z-index 来重排 SVG 的层级。它的默认值是 0,我们可以给 画家模型 | 21

它设置一个正值来把该元素放到其他图形前面,或者设置负值来把该元素 放到后面。

2.4 使用渲染提示属性

这些最后的属性被认为是你(SVG 的作者)给浏览器或其他把代码转换成 有色像素的软件的提示。当浏览器必须以某种方式牺牲性能或展现时,它们将告诉浏览器或软件哪个属性是你认为最重要的。这样属性或多或少会 有一致的影响。

shape-rendering 浏览器在屏幕分辨率的限制范围内应该如何调整形状的边缘。它有四个 可选的值。 • auto。默认值。这告诉浏览器选择最佳的优化方式。 • optimizeSpeed。这告诉浏览器快速渲染是最重要的特性(可能因为图 形正在执行动画),图形的边缘可能不会被精确地绘制。不过,细微 的变化可能因浏览器而不同,但大部分情况下它和 auto 的效果是相 同的。 • crispEdges。这告诉浏览器应该把填充和描边区域边缘的对比度最大 化,这通常意味着边缘会在最近的像素的边界形成锯齿,而不是对边 缘像素部分着色(反锯齿)。对于垂直线或水平线,这将创建一个锐 利清晰的图像,但是对于曲线或斜线,结果往往不太令人满意。 • geometricPrecision。这告诉浏览器应该尽可能精确地绘制形状,如 果需要可能会使用反锯齿模式。

text-rendering 浏览器应该如何调整文本中字母的形状以及位置。它也有四个可选值。 • auto(默认值)。 • optimizeSpeed,在大多数浏览器中效果和 auto 相同。对于较大的文本, 可能会关闭文本布局调整(对于大于 20 像素的文本,Firefox 默认使 用易读性调整)。 • optimizeLegibility,这告诉浏览器应该尽可能地调整单个字母的渲 染以及文本字符串的布局来使其更易于阅读。实践中,一些浏览器把 它当作扩大字母间距以及字体文件中指定的不必要连字的暗示。 • geometricPrecision,这告诉浏览器应该把字母当作几何形状来精确 地绘制,而不会根据基于分辨率的字体提示来调整。

color-rendering 浏览器在计算颜色时应该精确到什么程度,尤其在使用混合元素和产生 渐变时。标准的提示关键词有如下几个选项: • auto • optimizeSpeed • optimizeQuality

浏览器目前不会响应该属性设置的任何行为。 image-rendering 当图片显示的大小和图片文件本身定义的像素大小不完全相同时,浏 览器应该如何计算来展现光栅图片。在 SVG 1.1 中,可选的标准值有 auto、optimizeSpeed 和 optimizeQuality。然而在实践中,很明显,对 于创建一个“高质量”缩放图片的方法并不总是一致的。在图片包含尖 锐的边缘时,处理相片的最佳算法可以创建毛玻璃效果。 在 CSS Image Values and Replaced Content Module Level 3 中已经接受了 image-rendering 属 性, 但 废 弃 了 optimizeSpeed 和 optimizeQuality 两 个属性值。optimizeSpeed 属性被一个像素化的值(每一个像素都缩放为 一个正方形)替换。此外还增加了 crisp-edges 选项,用于让边缘更加 平滑并维持高对比度。 在编写本书之时,推荐使用 optimizeQuality 选项来平滑插入照片,在 现有的浏览器中它被默认的 auto 值覆盖。目前正在讨论设置一个单独的 smooth 属性,来和 auto 属性加以区分。

创建颜色

关键词颜色是怎么来的

在早期的 HTML 和 CSS 版本 中引入的简单的颜色关键词集,以及从 Unix 电脑 X11 窗口系统中的 SVG (以及后来的 CSS)开始使用的更广泛的关键词集。两种关键词集在所有

所有的 gray 关键词同样也可以拼写为 grey。这是一个特性, 而不是 bug。

关键词的名称和大多数 CSS 关键词一样,是不区分大小写的。如果你觉得 你的颜色非常强,可以把它们全部大写。大部分官方参考文档都使用小写。

例 3-1 创建一个颜色关键词拼图

SVG 标记:
    <
    svg xmlns = "http://www.w3.org/2000/svg"
xmlns: xlink = "http://www.w3.org/1999/xlink"
width = "400px"
height = "650px"
xml: lang = "en"
viewBox = "0 0 7 21"
preserveAspectRatio = "none" >

➊ < title > SVG Color Keywords < /title> <
script > < ![CDATA[
        /* script goes here */

➋
    ]] > < /script> </svg >

➊在 SVG 规范中定义了 147 个关键字(包括不同拼写的 gray), 恰好可以 分布在 7× 21 的网格中。 viewBox 创建了一个 7 列 21 行的网格, 并且使 用 preserveAspectRadio = "none"
来使网格拉伸到填充整个 < svg > 元素。
➋ 整个图形是通过脚本绘制的。 由于这是一个 SVG 文件, 所以需要使用 XML 的 < !CDATA[...]] > 块来包含脚本中的一些特殊字符。

    (function() {
        var svgNS = "http://www.w3.org/2000/svg";
        var xlinkNS = "http://www.w3.org/1999/xlink";
        var svg = document.documentElement;
        var dataFileURL = "color-names.csv"➊
        var request = new XMLHttpRequest();
        request.addEventListener("load", draw);
        request.overrideMimeType("text/csv");
        request.open("GET", dataFileURL);
        request.send();

        function draw() {
            ➋
            var w = 7; //swatches per row
            var colors = request.responseText.split("\n");➌
            for (var i = 0, n = colors.length; i < n; i++) {
                var c = colors[i].trim();➍
                var swatch = document.createElementNS(svgNS, "rect");
                swatch.setAttribute("width", 1);
                swatch.setAttribute("height", 1);
                swatch.setAttribute("x", i % w);
                swatch.setAttribute("y", Math.floor(i / w));➎
                swatch.style.setProperty("fill", c);➏
                var tip = document.createElementNS(svgNS, "title");
                tip.textContent = c;
                swatch.insertBefore(tip, null);➐
                svg.insertBefore(swatch, null);➑
            }
        }
    })();

3.3 自定义颜色

在 CSS 和 SVG 中使用一组 RGB 值来自定义颜色有两种方式: • 函数表示法,格式为 rgb(red,green,blue) • 十六进制表示法,格式为 #RRGGBB 或 #RGB

在函数表示法中使用的值可以是 0 到 255 的整数或者百分比。但不可以混 合使用整数和百分比,所有的值必须使用同一种类型。

六位的十六进制格式的值同样使用 0~255 的数字,但是必须要转换成十六 进制的数值。

三位的十六进制格式是颜色中每个值的两个十六进制数字相同时的简写。

CSS Color Module Level 3 中介绍了另一种描述颜色的方式,它基于更加常见 的颜色理论而不是 RGB 电脑显示器。

色相 - 饱和度 - 亮度(hue-saturation- lightness,HSL)模型把颜色描述为“纯”色和黑色、白色或灰色的混合方 式。它的三个具体值如下。

色相 使用色轮中的角度定义的纯色,角度为 0 度时是纯红色,60 度时是纯黄 色,120 度时是亮绿色,300 度时是品红色,360 度时又回到了纯红色。 饱和度 混合色中纯色的强度(用于调整亮度),0% 的饱和度会有灰色的色度, 100% 的饱和度是鲜亮的颜色。 亮度 混合色中黑色或者白色的程度,0% 的亮度是纯黑色,100% 的亮度是纯 白色,而 50% 的亮度是最鲜艳的颜色。

与 RGB 值不同,HSL 值通常不唯一,不同的 HSL 值可能组合出相同的颜 色。例如饱和度为 0% 时,不论色相值如何,永远显示灰色。亮度为 100% 时,不论色相和饱和度值如何,永远显示白色。

其他两种颜色模型容易与 HSL 混淆:色相 - 饱和度 - 明度 (hue-saturation-value,HSV) 模 型 和 色 相 - 饱 和 度 - 亮 度 (hue-saturation-luminance,不巧,它也缩写为 HSL)模型。 色相和饱和度的定义是相同的,但第三个参数的值是不可互 换的。如果你想匹配其他绘图软件中定义的颜色,要确保你 们使用的是相同的颜色模型。

把 RGB 转换为 HSL 时: • 饱和度的值可以计算为 100% 减去最小 RGB 通道占最大 RGB 通道的百 分比 S = (1 - min/max) × 100% • 亮度的值是最大颜色通道百分比和最小颜色通道百分比的平均值: 36 | 第 3 章

                                         L = (min% + max%)/2

• 色相的值是由中间值与最大颜色通道的值减去最小通道的值的比例决定 的: H = 0 + 60 × ([G−B]/[R−min]),如果最大值是 R H = 120 + 60 × ([B−R]/[G−min]),如果最大值是 G H = 240 + 60 × ([R−G]/[B−min]),如果最大值是 B

3.4 混合和搭配

sRGB 影响灰色或具有不同亮度(lightness)值的颜色的等级,而亮度 (luminance)的权重只会影响色相的不同。而 sRGB 定义了颜色值和感知亮度之间的曲线(伽马调整)关系。

SVG 使用三个不同的属性来控制基础形状和文本的不透明度:opacity、 fill-opacity 以及 stroke-opacity。

4.1 穿透样式

Web 中的不透明度通常使用一个介于 0.0(不可见)和 1.0(纯色,不透明)。之间的小数来表示。当不透明度是颜色或图像的固有组成部分时,这些数 字也被称为 alpha 值。rgba() 和 hsla() 中的 a 指的都是 alpha 通道。这两个 函数都接收四个参数,而不是通常使用的三个,第四个参数是 0 到 1 之间 的 alpha 值。

opacity 属性应用在设置它的元素上——即使是 组、 或者 元素——并且它不会被继承。最终绘制的效果同样会作用在元素所有的子 内容上,这使得整个元素更加均匀透明。

4.2 其他效果

多层重叠显示的最终颜色需要经过以下几个步骤:首先依据 sRGB 模型对 两种颜色进行缩放,然后获取背景和前景(alpha 值是前景的一个权重)的 加权平均值,最后反转 sRGB 缩放。该计算不会在意背景颜色是单一元素 创建的还是与部分透明元素混合创建的。

这种混合颜色的方法被称为简单 alpha 合成。在许多图形程序中,它也被称 为“normal”混合模式。

组元素或 元素上的 isolation 属性用于限制混合作用的范围。隔离元 素在子内容互相混合之后,再使用自己的混合模式来把子内容的混合结果 与背景相融合。

5 渲染和壁纸

当 fill 或 stroke 的值比单一颜色更加复杂时(transparent 或者其他), SVG 使用一种叫作渲染服务的概念来描述图形是如何被渲染的。

渲染服务通过自身特定的 SVG 元素来定义。

这些元素(渐变和图案)不会 直接创建一个可见图形。它们仅仅用于形状或文本的 fill 和 stroke 属性 中。然而,通过使用 XML 标记来定义渲染服务,它可以有无数种变化:任 何 SVG 图形都可以用于生成 SVG 图案,包括其他图案本身。

所有 SVG 渲染服务的一个主要特点是它们生成的图形内容都在长方形区域 内。有时这可能会有些限制,但也会有一些潜在的性能优化机会。

理解渲染服务(尤其是谈论渐变和图案时)的另一种方式是把渲染内容想 象成一大张墙纸。形状是从大块墙纸中裁剪出来的部分,如图 5-1 所示。

理论上说,“渲染”可以是任何事物:一种单独的颜色、一个或多个渐变、 重复的图案、位图、文本,甚至是其他 SVG 文件。实际上,SVG 1.1 有两 种类型的渲染服务:渐变和重复图案

5.2 标识资源

“服务”意味着它是多个资源的外部引用。理论上说,你可以单独创建一个 文件来包含你所有的渲染服务,并且在 fill 和 stroke 属性中引用它,但是 目前浏览器支持比较差。通常情况下,渲染服务指的是每一个渐变或图案 对象可以给多个 SVG 形状提供渲染(渲染指令)。

一个内部引用,就像 url(#myReference) 这样。井号(#)表示接下来是一 个指向特定元素的标记,事实上井号之前没有任何东西表示浏览器应该在 当前文档中查找该元素。具体而言,它寻找的是一个 id 属性与标记片段相 匹配的元素(即 )。 因此,引用一个 ID 为“customBlue”的渲染服务作为填充值如下所示:

因为 fill 是一个表现属性,所以你还可以在文档中任意位置使用一个

rect { fill: url(#customBlue); }

上面的规则将会设置文档中的所有矩形都用那个渲染服务,前提是该样式 不会被更加具体的 CSS 规则覆盖。

外部样式表中的相对 URL 通常指向 CSS 文件的位置,而不是使用这些样式 的文档的位置。

7.2 对象边界盒

通常你要使用渐变填充的形状不会占据整个坐标系统。

渐变矢量属性中的值默认并不是根据绘制 时使用的局部 坐标系来度量的。相反,它们是基于要填充的形状的对象边界盒创建的新 坐标系来定义的。

每个圆都尽可能地填满它的局部坐标系,但四个角无法填充。渐变的定义方 式没有改变,所以渐变矢量依然是从角到角的。对角矢量的最终结果是渐变 中起始和终止的颜色结点被裁剪掉了。

你可以在 元素上使用 gradientUnits 属性来改变它。

设置 gradientUnits 的值为 userSpaceOnUse 使浏览器在用于绘制要填充的形 状的坐标系内解析你的 x1、y1、x2 和 y2 属性。

CSS 与 SVG 使用关键词来设置 CSS 渐变的位置

CSS 线性渐变的默认方向是从上到下。当然你也 可以改变它的默认方向。它的语法与 SVG 完全不同,且与早期试验性的 CSS 渐变也有相当多的不同;为了尽可能地支持早期的浏览器,你可能需 要使用一个 CSS 预处理程序或脚本来把你的渐变重构为旧的语法。 要想改变 CSS 渐变的方向,需要在函数中颜色结点之前添加一个额外的参 数。要创建整整齐齐从一边到另一边、从一个角到另一个角的渐变,你可 以使用关键词:第一个关键词是 to,接着是 left、right、top 或 bottom 之 一来表示边,也可以是这些关键词的组合(例如 top right)表示角。这些 关键词描述的是渐变的终点(也就是渐变要往哪个方向),起点在相反一侧 或相对的角。 当使用角来表示时,渐变过渡的角度会被调整,所以渐变 50% 偏移位置点 连接着另外的角。虽然规范中实现的方式不同,但它的效果和对象边界盒 单位中角到角的 SVG 渐变效果一样。 例 7-4 直接比较了例 7-2 中 SVG 对角渐变(作为图片嵌入)和一个相似的 CSS 渐变(在网页的 body 上)。CSS 渐变中的 to bottom left,意思是它起 始于右上角。图 7-7 显示了最终效果,包括内嵌的 SVG 渐变。

7.4 渐变,变换

gradientTransform 属性的值是可以控制形状位置和方向的相同变换函数的 列表:

• translate(tx,ty) 仅改变位置而不会扭曲 • scale(s) 或 scale(sx,sy) 放大、缩小、拉伸或翻转成镜像 • rotate(a) 或 rotate(a,cx,cy) 围绕原点或指定点进行旋转 • skewX(a) 或 skewY(a) 沿着轴或其他线倾斜

聚焦未来 使用 CSS 规则来变换渐变 CSS Transforms Module 把 gradientTransform 这个表现属性映射到了新的 CSS 样式变换属性。虽然目前还没有浏览器支持,但在未来,你将可以在 渐变元素上设置变换样式,其效果会与 gradientTransform 属性相

倾斜显然是渐变变换来创建对角渐变的一种方式。旋转是另一种方式。

渐变矢量(初始状态下,沿着每个形状的边界盒的顶部从左到右)是围绕 每个盒子的原点(左上角)来旋转的。把渐变矢量旋转 90 度(如底部中间 的椭圆所示)将会使渐变从上到下改变。

CSS 与 SVG 使用角度定位 CSS 渐变 CSS 渐变同样可以使用旋转角度来定位,但是结果与 SVG 中有所不同。 你可以使用带单位的角度作为 linear-gradient 函数的第一个参数,来代替 方向关键词。由于默认方向是从上到下,角度是相对于朝下的垂直矢量来 计算的,为了创建 SVG 默认的指向右侧的渐变,必须把它设置为 -90 度。

上一页数学之美下一页浏览器的ESM到底是啥

最后更新于2个月前

这有帮助吗?