js-截图某一个div,使它飞向某个区域并消失

前两天遇到个需求:

交互显示XXXX(一个div)动画逐渐缩小,飞入右上角个人中心

当时遇到这个需求的时候我是懵逼的。跟她说实现不了吧?太复杂了。但我刚跟她说完就又很气,就这点东西我都做不出来?主要还是懒呀。开发周期不是很长,以下就跟大家分享一下我的一个实现思路以及实现代码:

实现思路 ___

  1. 找轮子,可能是没有能发现闪光的眼睛,只找到了扳手 —— html2canvas。
  2. 获取到需要添加飞入动画的div,以及个人中心(就一个div)的四维:距离顶部、距离左边、宽度、高度。
  3. 解决css动画问题(这里采用依靠css实现动画的方式,而不是js过多的干涉dom,影响性能)。
  4. 考虑封装整体功能,以便后续使用与升级优化。

实现代码 ___
这里采用了一种链式调用的写法,确保各功能相互独立,便于后期优化升级。

import html2canvas from "html2canvas"	//扳手
class htmlToPic {
    /**
     * @param {dom} html    需要添加动画的dom
     * @param {dom} target  移动至dom
     */
    constructor(html, target) {
        if (!!html == false || !!target == false) {
            throw "创建实例时,请传入需要加入动画的dom与目标dom"
        }
        this.html = html        // 获取到的执行动画dom
        this.target = target    // 获取到的目标dom
        this.getPic = html2canvas(html)
        this.pic = null
        this.domImg = null
        this.body = document.querySelector("body")
        this.img = new Image()

        console.log(html.offsetLeft)

        // html四维
        this.imgTop = html.offsetTop + "px"
        this.imgLeft = html.offsetLeft + "px"
        this.imgWidth = html.offsetWidth + "px"
        this.imgHeight = html.offsetHeight + "px"

        // target四维
        this.targetTop = target.offsetTop + "px"
        this.targetLeft = target.offsetLeft + "px"
        this.targetWidth = target.offsetWidth + "px"
        this.targetHeight = target.offsetHeight + "px"
        console.log(this)
        // 配置项(可选)
        this.options = {
            time: 2000,                      // 动画时间 1000 = 1s
            className: "htmlToPic--dom",     // 动画img的class
            opacity: {                       // 动画开始、结束时透明度
                start: 1,
                end: .4
            }
        }
    }
    /**
     * 初始化
     * 
     * @param {function} f      初始化实例回调
     * @param {object} option   可选配置项
     */
    init(f = false, option = false) {
        if (!!option) {
            this.options = {
                ...this.options,
                ...option
            }
        }
        this.getPic.then(canvas => {
            console.info("====成功初始化html2canvas====")
            this.pic = canvas.toDataURL('image/png')
            f && f(this)
        })
        this.img.className = this.options.className
        this.img.style.top = this.imgTop
        this.img.style.left = this.imgLeft
        this.img.style.width = this.imgWidth
        this.img.style.height = this.imgHeight
        this.img.style.zIndex = 10000
        this.img.style.position = "absolute"
        this.img.style.opacity = this.options.opacity.start
        this.img.style.transition = "all " + this.options.time / 1000 + "s ease-in-out"
        // 阻止多次调用
        this.init=function(){
            console.error("一次初始化只能有一个实例")
        }
        return "方法体第一个参数为回调函数,初始化的试了会通过此函数回调回来"
    }
    /**
     * 展示
     * 
     * @param {function} f      展示实例后回调
     */
    show(f = false) {
        this.img.src = this.pic
        this.body.appendChild(this.img)
        console.info("====成功插入dom====")
        this.domImg = document.querySelector(`.${this.options.className}`)
        f && f()
        return this
    }

    /**
     * 展示
     * 
     * @param {boolean} flag    移动后是否删除  默认不删除
     * @param {function} f      移动后回调
     */
    move(flag = false, f = false) {
        const _this = this;
        setTimeout(() => {
            console.log("====开始移动====",_this)
            _this.domImg.style.opacity = _this.options.opacity.end
            _this.domImg.style.top = _this.targetTop
            _this.domImg.style.left = _this.targetLeft
            _this.domImg.style.width = _this.targetWidth
            _this.domImg.style.height = _this.targetHeight
            setTimeout(() => {
                if (flag) {
                    _this.domImg.remove()
                }
                f && f()
            }, _this.options.time);
        }, 20)
        return this
    }

    /**
     * 删除
     */
    remove() {
        // this.domImg.remove()
        console.info("====删除img成功====")
    }
}
export default htmlToPic

使用的时候就接近于

      let dom = document.querySelector('.box1')
      let tar = document.querySelector('.box2')
      // 自定义选项
      let option = {
        time: 3000, // 动画时间 1000 = 1s
        className: 'htmlToPic--dom', // 动画img的class
        opacity: {
          // 动画开始、结束时透明度
          start: 1,
          end: 0.4,
        },
      }
      let htmlPic = new htmlToPic(dom, tar)
      // init 中返的 e 就是创建的实例
      // 主要是考虑到html2canvas,需要异步获取转换过来的canvas,所以需要改变一下结构
      htmlPic.init((e) => {
        e.show().move(true)
      },option)

如果有更漂亮的写法欢迎来讨论,让我们一起有条不紊的持续进步。
喜欢的话不妨点个小小的赞与关注,您的赞与关注将是我源源不断的前进动力。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值