微信公众号图片特效—svg视图交互记录

2,229 阅读3分钟

一、背景

下面是两篇微信公众号的推文的截图,正文都是以图片格式进行内容展示(正文不存在可长按copy的文字),并在此基础上融入了一些交互功能(点击、动画效果)

mp.weixin.qq.com/s/2JOAXKd4r…

mp.weixin.qq.com/s/3IKUHzoIU…

二、特效是如何实现的

  • 1、百度了一圈发现有很多的第三方推文编辑器平台都支持实现图片点击特效

  • 2、打开浏览器控制台查看第一篇推文特效处对应dom:

  • 3、可发现这篇推文里既有svg又有img,这样子做的意义是什么?因为svg在微信内置浏览器是无法通过touch进行预览的,而img可以,这样子可以实现touch对应的部分对特殊定位的隐藏img进行图片预览,即"点击查看他们的简历"的交互效果。

  • 4、查看第二篇推文特效处对应dom:

  • 5、框红部分title:纯dom实现回调地域代码视图。这样做的目的是什么?当此处点击“开始搜索”时会进行几十张图片的短暂切换,就像“中午吃什么”功能一样,用深层嵌套svg这种方式平替复杂的JS事务。

  • 6、现在随便打开一层svg:可发现存在对应的animate标签,其中有一个begin属性,"click + 0.4s",该功能合理就是用来实现帧数跳动效果的闪动效果。

  • 7、上链接: developer.mozilla.org/en-US/docs/… , 详细阐述了svg动画的各种结合使用

三、Try — 实现点击查看隐藏区域大图效果

  • 1、打开公众号,新建文章,选取一张图片

  • 2、可发现编辑器里生成了一个img标签,移动端预览确实是touch时能够进行图片的预览,接下来我把该图片的src提取出来,将img标签转换成svg标签。

<svg style="display: inline-block;width: 100%;
    background-image:url(SRC);
    background-size: 100%,100%;background-repeat: no-repeat;"
    version="1.1" viewBox="0 0 750 1280" xmlns="http://www.w3.org/2000/svg">
</svg>
  • 3、移动端预览touch时并不会进行预览并且此处无法长按选取。接下来我在svg标签内嵌入一个img标签。

  • 4、我对当前srction标签进行行内样式添加position:relative 以及对img标签进行样式position:absolute 添加,保存之后发现定位样式都被过滤掉了,因而得想想其他办法进行img重新定位。

  • 5、尝试了很多办法,最后是这样子实现的:通过transform以及pointer-events进行脱离文档流操作进行布局,这样子即可实现把需要预览的图片隐藏掉点击指定区域可以查看大图的效果,最终代码:

<!-- 实现微信推文点击预览隐藏区域图片效果 -->
<section
    style="text-align: center;height: 0;line-height: 0;width: 100%;
    margin: 0px auto;margin-top: -1px;pointer-events: auto;"
>
    <img src="SRC"
        data-w="1080" style="width: 200px;transform: scale(1, 1);" />
</section>

<section style="transform: scale(1); pointer-events: none;">
    <svg style="display: inline-block;width: 100%;
        background-image:url(SRC);
        background-size: 100%,100%;background-repeat: no-repeat;"
        version="1.1" viewBox="0 0 750 1280" xmlns="http://www.w3.org/2000/svg">
        <g>
            <animate attributeName="opacity" begin="0s" dur="1s" values="1;0;1" repeatCount="indefinite"></animate>
            <text x="200" y="250" fill="#fe8720" style="font-size: 60px;">点击查看大图</text>
        </g>
    </svg>
</section>

四、Try — 实现点击开启幻灯片效果

  • 1、基于"三",我先写出两个svg标签并配上对应的背景图片:

  • 2、结合 foreignObjectanimate 标签,以及animate里的attributeName、begin、 from、to属性,生成如下代码,这样子即实现了点击执行动画:

<svg viewBox="0 0 375 375">
    <foreignObject width="100%" height="100%" x="0%" y="0%">
        <svg style="display: inline-block;width: 100%;
            background-image:url(https://mmbiz.qpic.cn/mmbiz_jpg/0WwxjYnEzRpnnics4JCfmxw2ticx5BaEicRDOMd8oARVFwHJiaib1GbEJ0MbCJowDHDzqOcAmOf4Gld6JYq5Y7wgIwQ/640?wx_fmt=jpeg);
            background-size: 100%,100%;background-repeat: no-repeat;" version="1.1" viewBox="0 0 375 375" xmlns="http://www.w3.org/2000/svg">
        </svg>
    </foreignObject>
    <animate attributeName="width" begin="click + 1.6s" from="1" to="0"></animate>
</svg>
  • 3、进行svg动画嵌套:

<svg viewBox="0 0 375 375">
    <foreignObject width="100%" height="100%" x="0%" y="0%">
        <svg style="display: inline-block;width: 100%;
            background-image:url(https://mmbiz.qpic.cn/mmbiz_jpg/0WwxjYnEzRpnnics4JCfmxw2ticx5BaEicRSibmGgAMxkibrIeXPWyUiaPrRnBwAtGicnm7rrzyiaqHMiafDlQAXib5vt6lQ/640?wx_fmt=jpeg);
            background-size: 100%,100%;background-repeat: no-repeat;" version="1.1" viewBox="0 0 375 375" xmlns="http://www.w3.org/2000/svg">
        </svg>
    </foreignObject>
    <animate attributeName="width" begin="click + 3s" from="1" to="0"></animate>
    <svg viewBox="0 0 375 375">
        <foreignObject width="100%" height="100%" x="0%" y="0%">
            <svg style="display: inline-block;width: 100%;
                background-image:url(https://mmbiz.qpic.cn/mmbiz_jpg/0WwxjYnEzRpnnics4JCfmxw2ticx5BaEicRDOMd8oARVFwHJiaib1GbEJ0MbCJowDHDzqOcAmOf4Gld6JYq5Y7wgIwQ/640?wx_fmt=jpeg);
                background-size: 100%,100%;background-repeat: no-repeat;" version="1.1" viewBox="0 0 375 375" xmlns="http://www.w3.org/2000/svg">
            </svg>
        </foreignObject>
        <animate attributeName="width" begin="click + 1s" from="1" to="0"></animate>
    </svg>
</svg>
  • 4、进行svg多层动画嵌套,最终代码:

<svg viewBox="0 0 375 375">
    <foreignObject width="100%" height="100%" x="0%" y="0%">
        <svg style="display: inline-block;width: 100%;
            background-image:url(https://mmbiz.qpic.cn/mmbiz_jpg/0WwxjYnEzRpnnics4JCfmxw2ticx5BaEicRSibmGgAMxkibrIeXPWyUiaPrRnBwAtGicnm7rrzyiaqHMiafDlQAXib5vt6lQ/640?wx_fmt=jpeg);
            background-size: 100%,100%;background-repeat: no-repeat;" version="1.1" viewBox="0 0 375 375" xmlns="http://www.w3.org/2000/svg">
        </svg>
    </foreignObject>
    <animate attributeName="width" begin="click + 3s" from="1" to="0"></animate>
    <svg viewBox="0 0 375 375">
        <foreignObject width="100%" height="100%" x="0%" y="0%">
            <svg style="display: inline-block;width: 100%;
                background-image:url(https://mmbiz.qpic.cn/mmbiz_jpg/0WwxjYnEzRpnnics4JCfmxw2ticx5BaEicRDOMd8oARVFwHJiaib1GbEJ0MbCJowDHDzqOcAmOf4Gld6JYq5Y7wgIwQ/640?wx_fmt=jpeg);
                background-size: 100%,100%;background-repeat: no-repeat;" version="1.1" viewBox="0 0 375 375" xmlns="http://www.w3.org/2000/svg">
            </svg>
        </foreignObject>
        <animate attributeName="width" begin="click + 1.95s" from="1" to="0"></animate>
        <svg viewBox="0 0 375 375">
            <foreignObject width="100%" height="100%" x="0%" y="0%">
                <svg style="display: inline-block;width: 100%;
                    background-image:url(https://mmbiz.qpic.cn/mmbiz_jpg/0WwxjYnEzRpnnics4JCfmxw2ticx5BaEicRlCU7NTmjsm93IEfNeiaugicIicch5aV1kHbdHyJQqJT2teNv4KeRicUI1Q/640?wx_fmt=jpeg);
                    background-size: 100%,100%;background-repeat: no-repeat;" version="1.1" viewBox="0 0 375 375" xmlns="http://www.w3.org/2000/svg">
                </svg>
            </foreignObject>
            <animate attributeName="width" begin="click + 1.9s" from="1" to="0"></animate>
            <svg viewBox="0 0 375 375">
                <foreignObject width="100%" height="100%" x="0%" y="0%">
                    <svg style="display: inline-block;width: 100%;
                        background-image:url(https://mmbiz.qpic.cn/mmbiz_jpg/0WwxjYnEzRpCr79nxaYVMBPtKicJdeEn3wATFs3JVlQDEt16RP3WI8ankGhQyvWziayicztfvEicwUcWBictibuFgibEg/640?wx_fmt=jpeg);
                        background-size: 100%,100%;background-repeat: no-repeat;" version="1.1" viewBox="0 0 375 375" xmlns="http://www.w3.org/2000/svg">
                    </svg>
                </foreignObject>
                <animate attributeName="width" begin="click + 1.8s" from="1" to="0"></animate>
                <svg viewBox="0 0 375 375">
                    <foreignObject width="100%" height="100%" x="0%" y="0%">
                        <svg style="display: inline-block;width: 100%;
                            background-image:url(https://mmbiz.qpic.cn/mmbiz_jpg/0WwxjYnEzRpnnics4JCfmxw2ticx5BaEicRSibmGgAMxkibrIeXPWyUiaPrRnBwAtGicnm7rrzyiaqHMiafDlQAXib5vt6lQ/640?wx_fmt=jpeg);
                            background-size: 100%,100%;background-repeat: no-repeat;" version="1.1" viewBox="0 0 375 375" xmlns="http://www.w3.org/2000/svg">
                        </svg>
                    </foreignObject>
                    <animate attributeName="width" begin="click + 1.7s" from="1" to="0"></animate>
                    <svg viewBox="0 0 375 375">
                        <foreignObject width="100%" height="100%" x="0%" y="0%">
                            <svg style="display: inline-block;width: 100%;
                                background-image:url(https://mmbiz.qpic.cn/mmbiz_jpg/0WwxjYnEzRpnnics4JCfmxw2ticx5BaEicRDOMd8oARVFwHJiaib1GbEJ0MbCJowDHDzqOcAmOf4Gld6JYq5Y7wgIwQ/640?wx_fmt=jpeg);
                                background-size: 100%,100%;background-repeat: no-repeat;" version="1.1" viewBox="0 0 375 375" xmlns="http://www.w3.org/2000/svg">
                            </svg>
                        </foreignObject>
                        <animate attributeName="width" begin="click + 1.6s" from="1" to="0"></animate>
                        <svg viewBox="0 0 375 375">
                            <foreignObject width="100%" height="100%" x="0%" y="0%">
                                <svg style="display: inline-block;width: 100%;
                                    background-image:url(https://mmbiz.qpic.cn/mmbiz_jpg/0WwxjYnEzRpnnics4JCfmxw2ticx5BaEicRlCU7NTmjsm93IEfNeiaugicIicch5aV1kHbdHyJQqJT2teNv4KeRicUI1Q/640?wx_fmt=jpeg);
                                    background-size: 100%,100%;background-repeat: no-repeat;" version="1.1" viewBox="0 0 375 375" xmlns="http://www.w3.org/2000/svg">
                                </svg>
                            </foreignObject>
                            <animate attributeName="width" begin="click + 1.5s" from="1" to="0"></animate>
                            <svg viewBox="0 0 375 375">
                                <foreignObject width="100%" height="100%" x="0%" y="0%">
                                    <svg style="display: inline-block;width: 100%;
                                        background-image:url(https://mmbiz.qpic.cn/mmbiz_jpg/0WwxjYnEzRpCr79nxaYVMBPtKicJdeEn3wATFs3JVlQDEt16RP3WI8ankGhQyvWziayicztfvEicwUcWBictibuFgibEg/640?wx_fmt=jpeg);
                                        background-size: 100%,100%;background-repeat: no-repeat;" version="1.1" viewBox="0 0 375 375" xmlns="http://www.w3.org/2000/svg">
                                    </svg>
                                </foreignObject>
                                <animate attributeName="width" begin="click + 1.4s" from="1" to="0"></animate>
                            </svg>
                        </svg>
                    </svg>
                </svg>
            </svg>
        </svg>
    </svg>
</svg>

五、总结