当前位置: 首页 > Web前端 > HTML

CSS&SVGforeignObject实现文字镂空波浪动画

时间:2023-04-02 11:53:25 HTML

之前看过一篇文章:CSS奇葩技巧|使用混合模式来实现文字镂空波浪效果是非常巧妙的。它将CSS动画集成到文本中,主要使用混合模式。效果是这样的。为什么要使用混合模式?因为这是文本,不可能把HTML节点放在文本里面,所以下面介绍另一种方式。在HTML完全受限的情况下,借助SVGforeignObject可以轻松实现这种效果,而且会更好1.什么是SVGforeignObject首先,foreignObject是SVG中的一个元素,允许来自不同XML命名空间的元素被包括在内。在浏览器上下文中,通常是XHTML/HTML。这意味着什么?例如,通常我们在各种设计软件中导出的SVG可能是这样的如果直接保存为map.svg,然后放到浏览器中,你会注意到SVG有一个属性xmlns,也就是命名空间,指定了这个内容在浏览器中是如何呈现的,这里是http://万维网。w3.org/2000/svg是SVG的名称空间。如果没有这个属性,浏览器会直接渲染成一个普通的xml文档,如下,但是有一种情况是不需要指定这个命名空间的:如果我们的SVG文件直接内联在XHTML页面或者直接使用.html作为后缀名,可以不指定命名空间,浏览器会自动识别。那么,回到这里,foreignObject可以做什么?您可能已经猜到了,可以在SVG中呈现HTML标签!具体方法是在foreignObject内部添加xml命名空间,例如

xboxyan

注意body标签有一个属性xmlns="http://www.w3.org/1999/xhtml",这是html的命名空间。渲染结果如下,和普通的HTML差不多。下面的重点这里我们可以添加一些CSS动画<样式>p{颜色:红色;动画:hue5sinfinite}@keyframeshue{to{filter:hue-rotate(1turn)}}

xboxyan

这样就得到了一个动画SVG。一般来说,我们可以把SVG当成一张图片,这种图片可以方便的用在网页的各个地方,比如img的src属性,或者直接当成CSS背景图片。总之,在foreignObject的帮助下,可以很方便的把一段HTML转成一张图片,包括CSS动画。这很有趣。很多受HTML结构限制的场景都可以通过这种方式解决,比如文章开头提到的文字镂空波浪动画。2.在文本中嵌入背景图像有固定的套路借助-webkit-background-clip裁剪和透明文本,您可以轻松地将任何背景放入文本中,例如

CSSTEXT

p{-webkit-background-clip:text;颜色:透明;background:linear-gradient(#f44336,#ffc107);}效果如下试想一下,如果把上面的波浪动画做成图片,是不是可以直接用在这里呢?p{-webkit-background-clip:文本;颜色:透明;background:url(wave.svg);}3.CSS动画转SVG图片假设我们已经实现了这样一个wave动画(本文重点不在这里),详细原理可以参考coco的文章PureCSSto实现波浪效果,这里稍微修改一下body::before,body::after{content:"";位置:绝对;底部:50%;左:50%;宽度:400vw;高度:400vw;边界半径:45%48%43%47%;转换:翻译(-50%,0);盒子阴影:00050vw#54caff9e;动画:旋转10s无限线性;}body::after{border-radius:43%47%44%48%;动画:旋转10s无限-1s线性;}@keyframes旋转{0%{变换:平移(-50%,0)旋转(0);}100%{变换:平移(-50%,0)旋转(360度);你可以得到这个效果,把它放到一个SVGforeignObject中,它变成这样将这个SVG保存为wave.svg,就可以直接在浏览器中打开预览!这样就得到了“运动画面”。4.SVG图片的使用回到上文直接给这张图片改渐变。p{-webkit-text-stroke:1px#333;-webkit-背景-剪辑:文本;颜色:透明;background:url(wave.svg);}效果如下当然你也可以直接把这个SVG转成base64格式(推荐大家使用张新旭老师的SVG转换工具,很不错)是这样的转换后完全没有依赖(还是能隐约看到)p{-webkit-text-stroke:1px#333;-webkit-背景剪辑:文本;颜色:透明;背景:url("data:image/svg+xml,%3Csvgxmlns='http://www.w3.org/2000/svg'%3E%3CforeignObjectwidth='100%25'height='100%25'%3E%3Cstyle%3E@keyframesrotate%7B0%25%7Btransform:translate(-50%25,0)rotate(0)%7Dto%7Btransform:translate(-50%25,0)rotate(360deg)%7D%7Dbody%7Bwidth:100%25;height:100%25;margin:0;background:00;transition:.3s%7Dbody::after,body::before%7Bcontent:'';position:absolute;bottom:50%25;left:50%25;width:400vw;height:400vw;border-radius:45%2548%2543%2547%25;transform:translate(-50%25,0);box-shadow:00050vw%2354caff9e;animation:rotate10sinfinitelinear;z-index:1%7Dbody::after%7Bborder-radius:43%2547%2544%2548%25;animation:rotate10sinfinite-1slinear%7D%3C/style%3E%3Cbodyxmlns='http://www.w3.org/1999/xhtml'/%3E%3C/foreignObject%3E%3C/svg%3E");}这个完全没问题(如果预览不对可能是单引号和双引号的问题)CSS,如content:'')完整代码可以访问CSSwavetext(codepen.io)5.优点和局限优点其实很明显。因为是图片,属于真正的文字镂空效果,所以不像混合模式那样容易受到背景层的影响(原实现只能是白色背景),比如这里限制改变颜色是因为变成了图片,还有一些属性样式是固定的,不能动态修改。悬停相关的交互也是无效的。无法控制动画的速度等(在页面上直接使用SVG是可以的)。第六,当许多HTML受到严格限制时,其他应用程序可以使用此方法。可以使用SVG生成,因此您可以使用无限数量的伪元素另外,还有一个很重要的应用场景,纯前端截图功能,著名的前端截图库rasterizeHTML就是这个原理七、总结与解释以上就是本文的全部内容,一个相当实用的tip,withalittlehelpfromSVG一点点特性,主要是解决HTML结构限制的问题,剩下的和传统CSS有关,这里总结一下SVGforeignObject可以嵌入HTML标签注意SVG的命名空间和HTML一样,HTML会自动识别文字背景图片使用-webkit-background-clip结合透明文字实现SVG本质是可以将一张图片SVG转义成inlinebase64而不影响原动画。SVG作为图片时,不支持动态修改styleSVGforeignObject可以实现截图功能。如果你有图像相关的需求,可以往SVG方向思考。毕竟,SVG是一种图像语言。SVG还有很多有用的特性,后面会慢慢介绍。最后,如果觉得对你有帮助,请点赞、收藏、转发???