svg坑中指南

因为公众号网页的限制,不能写js,不能写css,只能在html标签里写内联样式,但是常常有需求要在推文上做一些交互和动画,这时候就需要SVG。

但是SVG在公众号上也有很多坑,总结一下遇到的一些坑,也有一些公众号其他的坑。

1,css的position属性全部失效,把代码上传到公众号之后,它会把position属性的代码删掉,所以公众号的布局不能用定位

2,ID全部失效,把代码上传到公众号之后,它会把ID删掉,包括写在HTML标签上的ID,还有SVG标签里面的ID

3,css的transform属性全部失效,把代码上传到公众号之后,它会把transform属性的代码删掉,(经测试现在的transform属性可以正常用了),SVG相关标签的transform属性有效,例如 <g transform="translate(10 10)"></g> 这样写是有效的

4,svg 里面不能嵌套 svg , 不能嵌套 image 标签, 经测试现在可以嵌套image标签了,但是href属性即图片的链接必须是素材库里的图片链接,外链或者base64均无法显示,如果是页面里普通的img标签则没有这个限制,width和height必须要写,不然在IOS上显示不了图片。

5,svg 尽量不要用渐变的颜色,因为代码会很多,体积太大,这个要跟设计师沟通

6,svg 相当于一张图了,全部放进去会文件体积很大,可以先压缩一下,在线SVG压缩:SVG在线压缩合并工具 » 张鑫旭-鑫空间-鑫生活

7,设计图 在使用AI设计时候,并不能使用复合路径、第二不能有任何超出画板外的元素在,第三文字使用扩展变为路径使用,并不能使用栅格化

8,IOS 上svg 动画的restart="never"没效,就是在苹果手机上再次点击的话,动画还是会执行,安卓没事,只做一次性的动画效果的话要留意下,目前无解,有解决方法欢迎留言。

(评论里有同学补充了解决方法,可以看看评论)

9,在公众号上是没办法通过媒体查询做屏幕适应的,所以遇到需要适应的元素,可以灵活使用VW或者VH作为单位来做适应

10,有的推文的交互一块内容然后向左滑动,但是之前遇到了要求向右滑动的,因为css横向滚动的容器默认滚动条是最左的,只能向左滑,如果想要右滑,我们需要在滚动的容器上加上dir="rtl"这个属性就行。这个属性原本用来规定文本的排列方向,用了这个属性文本就可以从右往左排,但是用在滚动容器上的时候,它就可以令滚动条一开始默认在最右,这样就可以一进来是往右滑的。(注意这个属性只适用于横向的排列和滚动,垂直方向是没效的)

11,做点击展开长图文,长图文里的元素不能有用float属性的,因为用了这个属性对应的元素会脱离文档流,在height为0的容器中也会显示出来,导致无法隐藏长图文。

12,在<g>标签里用style写内联样式,安卓跟PC端是有效的,在IOS上是失效的。例如我做一个旋转的动画,SVG是默认原点在左上角的,这时我们可以这样写<g style="transform-origin:50% 50%"></g>,这个g标签就会以中心为原点旋转,但是放到公众号推文上的时候,在IOS系统下<g style="transform-origin:50% 50%"></g>是不起作用的,它仍然以左上角为原点。做相关动画的时候要留意。

13,<svg>里可以通过<foreignObject>标签来嵌套其他的HTML元素,包括SVG,例如点击svg播放动效的时候同时播放音乐,先将音乐上传到公众号,再将代码复制过来,放到svg里用<foreignObject>包住,这样点击播放音乐的同时就会触发外层的SVG动画。

14,点击SVG后从头播放动图,需要先将动图放到页面之外,可以通过位移,点击触发之后再将动图移进来显示就可以从头播放动图,如果一进来就将动图显示在页面,他就会一直循环播放。

15,做点击展开长图文,可以将宽度写成固定值,现在大屏手机偏多,我一般写343px,这样在各种手机看起来高度就会一样,宽度的话在更大屏的手机上居中就行。

21/6/24 长图文展开有新的方法了,新的可以实现宽度全屏,之前的只能写死宽度,大宽屏手机下两边留白太多,例子如下:

<section style="overflow: hidden;" label="展开">
    <section style="text-align: center;height: 0;line-height: 0;">
     
      /**这里面放展开后的内容,不能用float*/
    
    </section>
    <section style="transform: rotateZ(0deg);text-align: center;line-height: 0;pointer-events: none;" label="">
      <svg viewBox="0 0 750 1295" style="max-width: none !important;pointer-events: none;">  /**外层SVG做展开,利用width撑开 values 500% 的值可根据展开后的内容调整*/
        <animate attributeName="width" fill="freeze" restart="never" keyTimes="0;.2;1" values="100%;0%;500%" dur="6s" begin="click">
        </animate>
       
        <g>
          <foreignObject x="0" width="100%" height="100%">  /**内层SVG做展开前的内容展示,一般放点击展开前的图*/
 <svg viewBox="0 0 750 1295"  display: block; pointer-events: auto;"> </svg> </foreignObject> </g> </svg> </section> </section>

16,做自动展开长图文,如果在微信编辑器已经展开了图文再生成预览,它会给SVG自动加上高度height,所以我们要给svg一个一进来就执行的高度动画,例如

  <animate attributeName="height" fill="freeze" restart="never" values="3730;340" dur="0.01s" >
            </animate>

这样就可以把微信强加的高度覆盖回去。

17,直接用img放单次循环的图片是没有效果的,推文那里会强制无限次循环动图,但是把图片放在SVG里面,用SVG做背景图或者套个image标签就可以实现单次循环

18,SVG双次点击,一般SVG只会触发一次动画,多次的话要用g标签包裹,在g标签里写动画,但是如果动画要作用于svg标签上的话,就只能触发一次了,这时可以通过设置不用的动画触发方式来两次触发动画,写一个touchstart动画触发的动画,然后再写一个click触发的动画,这样第一次点击svg的时候就会执行touchstart的动画,click的要在第二次点击的时候才会触发

19,svg随机结果,就是在公众号的SVG里长按,然后不停切换图片,松手就会停止。应用场景例如抽签和扭蛋之类的,但是公众号推文里有一个BUG就是在安卓上没有办法停在松手时的位置,无论你长按多久,它只会在第一张图停下,ios系统则可以做到什么时候松手就停在什么地方。

解决方法就是增加一个有循环动画的元素来当触发媒介,之前长按是直接按在SVG本身或者里面的g标签、图片标签,现在需要增加一个有循环动画的元素覆盖长按触发的互动区域,这样长按就会按在这个元素上,再通过这个元素触发父级切换图片的动画,这样安卓就可以随松随停,原理我也不清楚,公众号SVG的坑太多了。。。

示例:

<section label="第一部分" style="user-select: none;margin-top: -1px;display: inline-block;width: 100%;vertical-align: top;-webkit-tap-highlight-color: transparent;background-attachment: scroll;"><svg style="margin-top: 0px;display: block;width: 100%;" version="1.1" viewBox="0 0 750 932" xlink="http://www.w3.org/1999/xlink" xml="" xmlns="http://www.w3.org/2000/svg"><g><animateTransform attributeName="transform" type="translate" values="0 0;-1000 0;-2000 0;-3000 0;" repeatCount="indefinite" fill="freeze" begin="touchstart" end="touchend" dur="2s" calcMode="discrete"></animateTransform><g label="静态图片1"><image y="0" width="750" height="700" href="https://mmbiz.qpic.cn/mmbiz_jpg/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzgaziakP3meT6dWtvs8fFHf2bv97EppxAKm3fQKgpp6YX2XdgB4Wbv2DTQ/0?wx_fmt=jpeg" x="0"></image><g label="下方的动态"><image width="750" height="232" href="https://mmbiz.qpic.cn/mmbiz_gif/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzgazzuIQI4NXFXnKpsEu4iapeGKQOqjqtLkOkKhzXNaHn8QCcN52KAh2eQ/0?wx_fmt=gif" x="0" y="700"></image></g><g label="点击区域" opacity="0"><rect width="300" height="80" x="350" y="600" opacity="0" fill="red"><animate attributeName="opacity" values="1;0;1" fill="freeze" dur=".8s" repeatCount="indefinite"></animate></rect></g></g><g label="静态图片2" transform="translate(1000 0)"><image y="0" width="750" height="700" href="https://mmbiz.qpic.cn/mmbiz_jpg/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzga1DiciaDVH2GBTy8cMSLg1UekMZXYvvocUrH5xnpSGr6hnA68zJtaT8Vw/0?wx_fmt=jpeg" x="0"></image><g label="下方的动态"><image width="750" height="232" href="https://mmbiz.qpic.cn/mmbiz_gif/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzgazzuIQI4NXFXnKpsEu4iapeGKQOqjqtLkOkKhzXNaHn8QCcN52KAh2eQ/0?wx_fmt=gif" x="0" y="700"></image></g><g label="点击区域" opacity="0"><rect width="300" height="80" x="350" y="600" opacity="0" fill="red"><animate attributeName="opacity" values="1;0;1" fill="freeze" dur=".8s" repeatCount="indefinite"></animate></rect></g></g><g label="静态图片3" transform="translate(2000 0)"><image y="0" width="750" height="700" href="https://mmbiz.qpic.cn/mmbiz_jpg/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzgaLoyzFoUbbIw0ic79UWGGO8TCia8X8WpP59hiaDdBxnWr8IgsN7EEGJgMg/0?wx_fmt=jpeg" x="0"></image><g label="下方的动态"><image width="750" height="232" href="https://mmbiz.qpic.cn/mmbiz_gif/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzgazzuIQI4NXFXnKpsEu4iapeGKQOqjqtLkOkKhzXNaHn8QCcN52KAh2eQ/0?wx_fmt=gif" x="0" y="700"></image></g><g label="点击区域" opacity="0"><rect width="300" height="80" x="350" y="600" opacity="0" fill="red"><animate attributeName="opacity" values="1;0;1" fill="freeze" dur=".8s" repeatCount="indefinite"></animate></rect></g></g><g label="静态图片4" transform="translate(3000 0)"><image y="0" width="750" height="700" href="https://mmbiz.qpic.cn/mmbiz_jpg/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzga84bBybu5YtzjiaeXP36j4XKicUD9qhrdaxib8BbiaCFrYDpaS66wTmUd4g/0?wx_fmt=jpeg" x="0"></image><g label="下方的动态"><image width="750" height="232" href="https://mmbiz.qpic.cn/mmbiz_gif/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzgazzuIQI4NXFXnKpsEu4iapeGKQOqjqtLkOkKhzXNaHn8QCcN52KAh2eQ/0?wx_fmt=gif" x="0" y="700"></image></g><g label="点击区域" opacity="0"><rect width="300" height="80" x="350" y="600" opacity="0" fill="red"><animate attributeName="opacity" values="1;0;1" fill="freeze" dur=".8s" repeatCount="indefinite"></animate></rect></g></g><g><set attributeName="visibility" from="visible" to="hidden" begin="touchstart"></set><image width="750" height="700" href="https://mmbiz.qpic.cn/mmbiz_gif/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzga8dGUjDnohVicT4Du4vMPb5ia3XyZ0obUIEpdKkAStibjJ3pwl9ghN0icog/0?wx_fmt=gif" x="0"></image><g xmlns="http://www.w3.org/2000/svg"><g><image width="750" height="232" href="https://mmbiz.qpic.cn/mmbiz_gif/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzgazzuIQI4NXFXnKpsEu4iapeGKQOqjqtLkOkKhzXNaHn8QCcN52KAh2eQ/0?wx_fmt=gif" x="0" y="701"></image></g></g></g></g><g transform="translate(-80 -1100) scale(1.5)"><path d="M1,0L0,1395.766h800L801,0H1z M400.945,1229.013c-36.02,0-64.955-28.935-64.955-64.955c0-36.02,28.935-64.955,64.955-64.955  s64.955,28.935,64.955,64.955C465.903,1200.078,436.965,1229.013,400.945,1229.013z" style="opacity: 0;fill: red;"></path></g></svg></section>

20,GIF 图片不能超过300帧,大小不能超过10M,普通图片总像素不能超过600万(就是尺寸不能太高,一般的750设计稿的图就够用了,宽度最好也不要超过1080,不然太大传上去也会被压缩的)

21,有时候图片与图片之间会有白缝,可以将img转为 display:block; 解决 , 可以用 float:left; ,如果想清楚浮动可以给父级元素设置overflow:hidden;

如果上面的设置了还有白缝可以用margin-top:-1px;来微调。

22,在可滚动的容器上加上dir属性可以定义滚动内容的方向,比如设置了overflow-x横向滚动,默认是从左往右开始滚动的,但是加上dir=“rtl”后,就是设置成默认从右向左滚动,注意:如果overflow-y垂直滚动,那么dir属行改变的是里面内容的排列方向,不是改变滚动方向,比如有一句123的话在左边,设置了之后123就变到右边了;

关于滚动还有一些有趣的属性,比如 scroll-snap-type , 至于怎么用上就看项目需求,靠大家发挥下想像力了。

23,翻页的效果可以参考css3的transform:scale(-1)来实现 ,在svg里的animationTransform的scale设置为-1即可

参考案例:https://mp.weixin.qq.com/s/n4fBuV850mwjG6FT-thLiw

 P.S.:

· 单位不能用百分比。例如transform:translateY(-100%) ; margin-top:-100%; 在公众号上会失效,建议用px或者vw/vh

· pointer-events:none; 这个属性可以让所有交互事件失效,在一些场景会需要,可自行探索

· 给SVG设置背景图,图片路径尽量不用单引号包括

例如:url(img) ---- 复制到公众号可以显示,url('img') ---- 复制到公众号有时不可以显示

24,图片向下伸展的过程之中会用到贝塞曲线,在设定贝塞曲线相关的值的时候搭配的values最好选用百分比的形式,适配于各种机型不同的屏幕宽度。点击伸展长图之后,如果设置的伸展动画属性是height,在伸展长图的整个section部分不能使用svg进行图片叠加,会有各个不同的机型长度不同的问题。如果设置的伸展属性是width,则可以使用svg作为图片叠加,vlues可以用百分比来进行控制。

25.section和section之间的嵌套能够实现容器的层叠,section要居中使用text-align:center,section和svg的嵌套逻辑,举个栗子,一个svg包裹一个section,形成一个容器,我需要这个容器行高为0或者是overflow:hidden,就需要在包裹一个section,形成的固定的section容器我需要它高度为0,是不展开的,因此我需要在嵌套一个大的section标签设置height为0,做到一整个容器是被svg撑开的同时与其他svg并列在一个高度。

如果说建立了一个section之后下面仅仅需要插一个图,可以直接在下面写svg,但是需要一个父容器给他们包裹起来,形成一个完成的标签容器部分

26、密码解锁svg注意要更改按键的遮盖方块,viewbox是视觉窗口的意思,可以设置为图片本身的像素比例(1080*12600),具体控制图片的宽高可以使用绝对宽高,在style里面设置固定的宽高

27、像素比换算,可以1080/12600,比如说自己设定的section宽度是345,在乘以345可以得出高

28、探照灯的原理是使用svg的剪裁效果来做的,详情看CSS和SVG剪裁效果 | clip-path属性和clipPath元素_jQuery之家-自由分享jQuery、html5、css3的插件库CSS和SVG有许多共同点。我们如今使用的很多CSS特性都被引入到SVG中。其中的一项特性是剪裁操作。CSS和SVG都允许我们将元素剪裁为不规则的形状。在这篇文章中,我们将讲解CSS和SVG的剪http://www.htmleaf.com/ziliaoku/qianduanjiaocheng/201502081349.html

29、section标签是定义文档中的节(section、区段),包含h1,h2,...等,居中section text-aglin

flex:0 0 100%; 速记属性,设置flex-grow,flex-shrink和flex-basis。0 0 33%基本上只是意味着“占三分之一”,而不再与其他元素成比例地“增长”或“缩小”。

flex-grow:指定项目应在flex容器内占用多少空间。弹性项目的弹性增长因子是相对于弹性容器中其他子项的大小的。

flex-shrink:指定弹性项目的弹性收缩系数。当弹性项目的默认宽度大于弹性容器时,弹性项目将根据弹性收缩编号收缩以填充容器。

flex-basis:指定弹性项目的初始主要尺寸。除非另外使用box-sizing来指定,否则此属性确定内容框的大小。

vertical-align 属性设置元素的垂直对齐方式。top    把元素的顶端与行中最高元素的顶端对齐

overflow-x: auto; -webkit-overflow-scrolling: touch;  滚动回弹

display属性:block、inline和inline-block的区别 
    display:block的特点:
    1、block元素会独占一行,多个block元素会各自新起一行。默认情况下,block元素宽度自动填满其父元素宽度。
    2、block元素可以设置width,height属性。块级元素即使设置了宽度,仍然是独占一行。
    3、block元素可以设置margin和padding属性。
    display:inline的特点:
    1、inline元素不会独占一行,多个相邻的行内元素会排列在同一行里,直到一行排列不下,才会新换一行,其宽度随元素的内容而变化。
    2、inline元素设置width,height属性无效。
    3、inline元素的margin和padding属性,水平方向的padding-left, padding-right, margin-left, margin-right都产生边距效果;但竖直方向的padding-top, padding-bottom, margin-top, margin-bottom不会产生边距效果。
    
-webkit-tap-highlight-color: transparent; 这个属性只用于iOS (iPhone和iPad)。当你点击一个链接或者通过Javascript定义的可点击元素的时候,它就会出现一个半透明的灰色背景。要重设这个表现,你可以设置-webkit-tap-highlight-color为任何颜色。想要禁用这个高亮,设置颜色的alpha值为0即可。

section多层嵌套,有一个svg就要包裹一个section section和svg同时都是子元素的时候在外面要在嵌套一个section,并设定section的样式,如果要section高度为0,就需要为这整个section再次嵌套

使用 sroll-snap-type 优化滚动 scroll-snap-type: x mandatory 中,x 表示捕捉 x 轴方向上的滚动,mandatory 表示强制将滚动结束后元素的停留位置设置到我们规定的地方.scroll-snap-align:center 滚动元素居中

overscroll-behavior 可以控制浏览器过度滚动时的表现——也就是滚动到边界。

-webkit-touch-callout  禁用了默认的callout展示, callout是指当触摸并按住一个元素的时候出现的提示。当在iOS上一直按住一个目标元素时,Safari会展示一个关于这个链接的callout信息。webkit-touch-callout属性允许禁用掉这一行为。

-webkit-user-select:none; 控制页面文字无法选中 (不同浏览器的设置:-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;)

mix-blend-mode: difference; 颜色混合模式

<label> 标签为 input 元素定义标注(标记)。label 元素不会向用户呈现任何特殊效果。不过,它为鼠标用户改进了可用性。如果您在 label 元素内点击文本,就会触发此控件。就是说,当用户选择该标签时,浏览器就会自动将焦点转到和标签相关的表单控件上。label="{lable}"

perspective: 1px; 定义 3D 元素距视图的距离,以像素计。该属性允许您改变 3D 元素查看 3D 元素的视图。当为元素定义 perspective 属性时,其子元素会获得透视效果,而不是元素本身。
perspective-origin:50% 50%; 定义 3D 元素所基于的 X 轴和 Y 轴。该属性允许您改变 3D 元素的底部位置。
当为元素定义 perspective-origin 属性时,其子元素会获得透视效果,而不是元素本身。
transform-style: preserve-3d; 让转换的子元素保留3D转换

 align-items:flex-start;元素位于容器的开头。
弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴起始边界。

transform:scale(1):在子元素或者svg上写了transform:scale(1)图片放大之后,需要在父元素身上也写一个transform:scale(1),在svg的视觉窗口(viewbox)之中,如果元素放大之后会造成中心对齐点(x=0,y=0)发生位置的变化,因此需要等比放大,或者使用transform:rotateZ(1deg)css3系列之transform 详解rotate - 杨耿 - 博客园

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值