vue canvas 页面添加水印

522 阅读1分钟

再摸了很久很久的鱼后。终于今天来了个比较有趣的需求,那就是给页面添加水印!!

第一反应,搞一个遮罩层,在套一个一个canvas貌似就ok了啊。

说干就干。,先搞定遮罩层

写个div。搞个css,搞定

 .demo{
    width: 100%;
    height: 102%;
    background-color: #000;
    position: fixed;
    top: 0;
    z-index: 99999;
    opacity: 0.5;
    pointer-events: none
  }

pointer-events:none属性 的作用:添加上该属性的元素,在页面上不会有任何的鼠标事件,只能看得见,不能进行任何的操作。

这样就可以防止遮罩层阻碍页面上的各种操作事件了

下一步canvas写水印

原本想直接网上cv一个直接了事,结果感觉不是很理想, 大部分的水印制作方式都是直接旋转画布,导致边角存在空白,而且看着比较别扭(我自己觉得) 最后还是选择改一改让每一段文字旋转

最后的封装的组件代码如下:(可直接复制拿走😊,粘贴即用)

<template>
  <canvas class="watermarkStyle" id="canvas"></canvas>
</template>

<script>
export default {
  name: "watermark",
  props: {
    text: {
      type: String,
      default: () => "这个是水印文案",
    },
  },
  created() {
    setTimeout(() => {
      this.setWatermark(this.text);
    }, 10);
  },
  methods: {
    setWatermark(text) {
      // 创建一个画布
      var canvas = document.getElementById("canvas");
      const canvasParent = document.body;
      const maxSizeContainer = Math.max(
        canvasParent.offsetWidth,
        canvasParent.offsetHeight
      );
      const minSizeCanvas = Math.ceil(Math.SQRT2 * maxSizeContainer);
      // 设置画面的最小尺寸
      canvas.setAttribute("width", String(minSizeCanvas));
      canvas.setAttribute("height", String(minSizeCanvas));
      var ctx = canvas.getContext("2d");
      ctx.font = "20px arial";
      ctx.fillStyle = "#eee";
      ctx.textBaseline = "Middle";
      ctx.shadowOffsetX = 1;
      ctx.shadowOffsetY = 1;
      ctx.shadowBlur = 3;
      const strWidth = ctx.measureText(text).width
      const offsetX = Math.ceil(strWidth) + 180;  // 调节间距
      const offsetY = 120;                        // 调节间距
      const rowCount = Math.ceil(minSizeCanvas / offsetY);
      const colCount = Math.ceil(minSizeCanvas / offsetX);
      // 行
      for (let i = 0; i < rowCount; i++) {
        // 列
        for (let j = 0; j < colCount; j++) {
          ctx.save()
          ctx.translate(offsetX  * j + strWidth/2, offsetY * i - strWidth/2);
          ctx.rotate(40 * Math.PI / 180)
          ctx.fillText(text,0,0 )
          ctx.restore()
        }
      }
    },
  },
};
</script>
<style lang="less" scoped>
.watermarkStyle {
  position: fixed;
  top: 0;
  z-index: 99999;
  pointer-events: none;
}
</style>

使用

<template>
    <watermark text="测试字段"/>
  </div>
</template>
<script>
import watermark from './components/watermark/index.vue'
export default {
  components: {
    watermark
  },
}
</script>

当然字体颜色之类的这种你可以自己改一下从外部获取~ 最后上个效果图

image.png

再上一个旋转画布的效果图

image.png

边角非常明显的留白😑

如果截全屏的话会更明显些。

当然喜欢哪种,就仁者见仁,智者见智了~

最后最后,欢迎有大佬来指点指点👏👏👏

也欢迎大家一起探讨问题。

==========分割线================

后续使用中发现样式有些拉伸,所以修改了部分代码,最后效果可能与图片略有区别,不过不影响使用的哈~👀