乐趣区

关于vue.js: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>
退出移动版