VUE项目中实现DOM模糊化效果

这是一段将DOM元素模糊成图片的代码

<template>
    <div class="gauss-blur-wrap">
        <Spin v-if="showBlur" fix></Spin>
        <div :ref="`sourceBox${rand}`">
            <slot></slot>
        </div>
        <img v-show="true" :id="`tempImg${rand}`" :src="`${tempImg}`"></img>
        <canvas :id="`gauss-blur-canvas${rand}`" :width="canvasWidth" :height="canvasHeight"></canvas>
    </div>
</template>

<script>
    import html2canvas from "html2canvas";
    import * as StackBlur from "stackblur-canvas";

    /**
     * 对 GaussBlur 标签包围内的部分进行模糊化处理,且会删除原DOM元素
     * 强依赖组件 html2canvas stackblur-canvas
     * html2canvas 将 DOM 转为图片
     * stackblur-canvas 对图片进行模糊化处理
     * 当有异步请求时,用加载变量控制展示 <GaussBlur v-if="!loading">,
     * loading 初始值需为true,为false的话会多渲染一遍组件,且没有DOM,导致报错
     * 无异步请求时,可不用任何参数
     *
     * <img 只为临时保存转换好的图版
     * <canvas 用于模糊化后展示
     */
    export default {
        name: "gauss-blur",
        data() {
            return {
                showBlur: true,
                tempImg: '',
                canvasWidth: '',
                canvasHeight: '',

                rand: Math.random(),
                processFlag: true
            }
        },
        created() {
            this.setTimeProcess();
        },
        methods: {
            setTimeProcess() {
                let _this = this;
                // 由于有异步请求只用 $nextTick 还不能在完全在执行后调用
                setTimeout(() => {
                    // 请求成功,更新完 DOM 后再转成base64的图
                    _this.$nextTick(() => {
                        _this.toImage();
                    })
                }, 0);
            },
            toImage() {
                let _this = this;
                let _source = this.$refs[`sourceBox${this.rand}`];

                if (_source) {
                    html2canvas(_source, {backgroundColor: null})
                      .then((canvas) => {
                          let _dataURL = canvas.toDataURL("image/png");

                          // 给临时图片、canvas 加宽高
                          _this.canvasWidth = this.$el.getBoundingClientRect().width;
                          _this.canvasHeight = this.$el.getBoundingClientRect().height;
                          _this.tempImg = _dataURL;

                          // 在图片加载完成后再删除DOM
                          let _tempImg = document.getElementById(`tempImg${_this.rand}`);

                          _tempImg.onload = function () {
                              //调用模糊处理
                              StackBlur.image(`tempImg${_this.rand}`, `gauss-blur-canvas${_this.rand}`, 5, true);
                              // 删掉原有DOM内容
                              _source.remove();
                              _tempImg.remove();


                              // 把loading 效果去掉
                              _this.showBlur = false;
                          }
                      });
                }

            }
        }
    }
</script>

<style scoped>
    .gauss-blur-wrap {
        position: relative;

        .ivu-spin-fix {
            background-color: hsla(0, 0%, 100%, 1);
            z-index: 99999;
        }
    }
</style>

.vue 文件中的用法

<GaussBlur>
  <div>要模糊的代码</div>
</GaussBlur>
阅读 223

推荐阅读

前端基础知识,信息比较杂

1 人关注
13 篇文章
专栏主页