您现在的位置是:网站首页> 编程资料编程资料
使用SVG实现提示框功能的示例代码HTML5 SVG带弹性动画效果的Tooltip提示框
2023-10-11
365人已围观
简介 这篇文章主要介绍了使用SVG实现提示框功能的示例代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

NO.1
前言
Tooltips常被称为提示框(或信息提示框),提示框能够以较强的交互性、自由度为用户提供相应的提示信息。今天我们要聊的不是如何实现强大的交互行为,而是来看看如何以最好的方式来还原他们的视觉效果,并且能适用于不同的场景。
NO.2
背景

上图是从平时工作场景碰到的UI效果截图过来的。上图中展示的Tooltips框基本上覆盖了常见的UI风格。简单的来归纳一下:
- 带边框的提示框
- 纯色(或带透明度纯色)的提示框
- 带内阴影(或外阴影)的提示框
- 带边框+渐变的提示框
- 带边框+透明度背景的提示框
- 提示框三角带圆角和阴影的提示框
可能还有我未碰到的提示框UI风格。面对这么多的UI风格,对于前端实现上来说是具有一定的挑战性,特别是多种效果组合在一起的。比如说,带有边框+内外阴影+渐变(或透明度)+圆角三角等。基本上组合了上图所提到的各种UI风格。
NO.3
clip-path方案
通常上图的实现是使用CSS画个尖角来拼接上去,比较优秀的方案如下图:

我们简单介绍下clip-path方案:
把提示框分成两个部分,一个是四方形,一个是三角形,然后两个拼接在一起组合成一个提示框。这样整个坐标示意图如下:

假设提示框的尺寸是w x h,边框厚度是h1,那么绘制带有缺口的时需要以下几个坐标点:
d1坐标(0, 0)d2坐标((50% - b), 0)或((w / 2 - b), 0)其中b是三角形对角边长度的一半,后面会介绍到d3坐标((50% - b - h1), h1)或((w / 2 - b - h1), h1)d4坐标((50% + b + h1), h1)或((w / 2 + b + h1), h1)d5坐标((50% + b), 0)或((w / 2 + b), 0)d6坐标(100%, 0)或(w, 0)d7坐标(100%, 100%)或(w, h)d8坐标(0, 100%)或(0, h)
坐标点放置到clip-path的polygon()函数中,最终剪切之后的图形看上去像下图

clip-path: polygon( 0 0, calc(50% - 4px) 0, calc(50% - 7px) 2px, calc(50% + 7px) 2px, calc(50% + 4px) 0, 100% 0, 100% 100%, 0 100%, 0 0);
另外就是三角形的部分,如果我们的三角形是一个10px x 10px旋转45deg得到。根据一些三角函数的公式和已知的正方形边长就可以计算出正方形斜对角的长度:

NO.4
clip-path方案碰到问题
这个效果整体看起来还是不错的,但是细看就会发现在接缝处或许会存在有空隙、有重叠的问题,如下图:



采用vw方案后这类像素对不齐的问题也算是司空见惯了,同时第一个Tooltips由于是背景需要从左到右渐变的,此时尖角的渐变过度要和下方的渐变匹配上就更需要费力气了。
由于先前就遇到过此类ToolTip样式问题,告知视觉同学后,体贴的视觉同学修改了一版不带透明度的纯色提示框,然而视觉效果大打折扣。
其实我们对于原先采用CSSclip-path的方案其实也存在很多的缺陷,它在面对带有阴影、背景透明或者渐变、带边框同时出现时就显出了实现成本高和效果一般的缺点。
NO.5
SVG 方案
在讨论中我们想到 SVG的path和这个提示框的样式天然的匹配(建议先了解下path的相关文档),查阅了相关的文档和资料后我们大致得到了使用SVG来实现的如下几个优点:
- 能轻松满足阴影、背景透明或者渐变、带边框的效果,甚至更为复杂多变的场景
- SVG的
path实现简单,并且代码量极小 - 可扩展性,可维护性
参考相关文章后,我们完善Demo工具如下:


使用Demo工具,我们会得到path的数据大致如下:
M 0,0 L -15,-15 H -79 Q -84,-15 -84,-20 V -85 Q -84,-90-79,-90
H 61 Q 66,-90 66,-85 V -20 Q 66,-15 61,-15 H 15 z
通常使用SVG画path时用到命令如下表:
| 命令 | 名称 | 参数 |
| M | moveto(移动到) | (x y)+ |
| Z | closepath(关闭路径) | (none) |
| L | lineto(画线到) | (x y)+ |
| H | horizontal lineto(水平线到) | x+ |
| V | vertical lineto (垂直线到) | y+ |
| C | curveto(三次贝塞尔曲线到) | (x1 y1 x2 y2 x y)+ |
| S | smooth curveto(光滑三次贝塞尔曲线到) | (x2 y2 x y)+ |
| Q | quadratic Bézier curveto(二次贝塞尔曲线到) | (x1 y1 x y)+ |
| T | smooth quadratic Bézier curveto(光滑二次贝塞尔曲线到) | (x y)+ |
| A | elliptical arc (椭圆弧) | (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+ |
| R | Catmull-Rom curveto* (Catmull-Rom曲线) | x1 y1 (x y)+ |
贝塞尔曲线
在SVGpath命令中我个人认为最精髓的部分是贝塞尔曲线,贝塞尔能画出各种令人愉悦的曲线。
贝塞尔曲线完全由其控制点决定其形状,n个控制点对应着n-1阶的贝塞尔曲线,并且可以通过递归的方式来绘制。我们先看下一次和二次贝塞尔曲线如何来绘制的:
一次曲线:

一条直线上,随着时间t的变化,红色线段的那个点的坐标公式应该如下:
二次贝塞尔曲线:

p0、p1、p2是3个不共线的点,依次用线段连接,此时随意取线段p0p1上的一个点p0', 如上图: 我们的p0'点在p0p1线段的0.26处(t=0.26),此刻p1p2线段相同比列取p1'点,此时p0'和p1'连接后形成线段p0'p1', 在按照如上比列进行取值p0'', 这时候就确定了二次贝塞尔曲线的一个点。
通过一番巴拉巴拉牛逼的推导后,二次贝塞尔曲线公式为:
N次贝塞尔可以认为是如上取值方式的迭代过程,可以通过下图直观的感受到1~4次曲线随着时间t的变化过程,具体N次贝塞尔曲线的公式可以参考下方关于曲线的文章

SVG中的Q命令
回到我们的ToolTips话题, 其中的圆角是可以通过二次贝塞尔曲线来实现,SVG中Q命令就是来实现二次贝塞尔曲线的,SVG中Q命令的示例图如下:

对应的指令,其中x1,y1就是我们上面提到的p1点:
Q x1 y1, x y
二次贝塞尔曲线Q示例如下:
通过设置起始点和调整控制点p1我们能得到我们想要的圆角,如下图所示,小圆点为我们的p1控制点

NO.6
样式设置
实现了上方的SVG后接下来的透明、背景渐变、阴影、边框的设置就都不成问题了。
背景透明
path { fill: rgba(0,0,0, .3); storke: #ffffff; storke-width: 1px }
阴影
svg { filter:drop-shadow(2px 4px 6px black) }
关于为何使用drop-shadow来实现阴影,可以看下图使用了box-shadow和drop-shadow效果区别,
使用box-shadow的时候我们的尖角部分没有阴影,气泡框部分是有阴影的,就会出现下图所示的情况,而使用drop-shadow就能符合我们尖角和气泡框都有阴影的要求。

背景渐变
SVG不仅支持简单的填充,还支持线性渐变和径向渐变以及图形纹理等。为了让渐变能被重复使用,渐变内容需要定义在标签内部。
如下图是径向渐变的演示:

将这个渐变作用到我们提示框后可以看到如下图的效果,终于不用辛辛苦苦的处理尖角的渐变衔接问题了。

更多
SVG同时也支持纹理叠加效果,具体感兴趣的可以自行去研究下。
NO.7
需求还没完
上面方案落地到项目中后,可能是我们不经意感动了设计师,最近的需求视觉稿中我们发现其中涉及到的Tooltips样式已经越发令人惊艳。简单列举如下两个样式:

第一版方案我们基于Demo工具演示我们已经产出了ToolTips的SDK, 我们使用的单个参数arrowHeight传入来生成尖角。在应付上方两个样式是不可能的,尖角样式多变,如何来扩展性和易用性成为了一个问题,不可能多变的尖角样式都开发一个SDK。
NO.8
方案改进
要应付多变的气泡尖角一定要想办法把尖角抽离出原先的气泡外层路径,生成尖角路径后在整合到气泡上形成一个完整的闭合路径。
为了简单处理数值,我将原先的尖角(0,0)坐标定义更换到下方图示点:

所以接下来尖角可以自由设计了,只要保证从(0,0)出发最后回到(-arrowWidth,0)就行了,如下是一个尖角的路径:(M 0 0 C -10 0 -8 5 -12 5 S -14 0 -24 0)

通过设计不同的尖角路径我们就能组合成不同的气泡样式:

提示:
本文由神整理自网络,如有侵权请联系本站删除!
本站声明:
1、本站所有资源均来源于互联网,不保证100%完整、不提供任何技术支持;
2、本站所发布的文章以及附件仅限用于学习和研究目的;不得将用于商业或者非法用途;否则由此产生的法律后果,本站概不负责!
相关内容
- Html5嵌入钉钉的实现示例html5实现点击弹出图片功能html5 录制mp3音频支持采样率和比特率设置html5表单的required属性使用html5调用摄像头实例代码HTML5页面音频自动播放的实现方式Html5大屏数据可视化开发的实现html实现弹窗的实例HTML5来实现本地文件读取和写入的实现方法HTML 罗盘式时钟的实现HTML5简单实现添加背景音乐的几种方法
- 浅析数据存储的三种方式 cookie sessionstorage localstorage 的异同Html5中localStorage存储JSON数据并读取JSON数据的实现方法详解前端HTML5几种存储方式的总结
- h5页面唤起app如果没安装就跳转下载(iOS和Android)HTML5中外部浏览器唤起微信分享Html5如何唤起百度地图App的方法详解如何通过H5(浏览器/WebView/其他)唤起本地apphtml5唤起app的方法
- 天天酷跑新版本安卓葫芦侠修改器无敌跳刷分刷金币技巧攻略_手机游戏_游戏攻略_
- 天天酷跑新版本ios叉叉助手搭配UU助手刷金币辅助教程攻略_手机游戏_游戏攻略_
- 天天酷跑极速世界怎么快速获得钻石 免费获得钻石任务方法大全_手机游戏_游戏攻略_
- 天天酷跑UU助手刷百万分图文攻略 无限刷分每局百万教程_手机游戏_游戏攻略_
- 天天酷跑1.0.7版本新模式试玩心得经验分享 惊现点石成金_手机游戏_游戏攻略_
- 天天酷跑新版本安卓1.0.7葫芦侠刷分刷金币详细图文教程_手机游戏_游戏攻略_
- 天天酷跑新版本UU助手刷金币图文攻略 无敌刷金币每局1W教程_手机游戏_游戏攻略_
