vue项目中使用水印

vue项目中通过自定义指令

在vue项目中通过自定义指令,使用canvas特性生成base64格式的图片文件,并将其设置为背景图片,从而实现页面或组件局部水印效果

1.新建directives.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import Vue from "vue";
Vue.directive('watermark', (el, binding) => {
function addWaterMarker(str, parentNode, font, textColor) {
var can = document.createElement('canvas'); //创建canvas元素
parentNode.appendChild(can); // 将canvas挂在到父节点
can.width = 400;
can.height = 200;
can.style.display = 'none';
var cans = can.getContext('2d');
cans.rotate(-20 * Math.PI / 180)
cans.font = font || "14px Helvetica";
cans.fillStyle = textColor || "rgba(180, 180, 180, 0.3)";
cans.textAlign = 'left';
cans.textBaseline = 'Middle';
cans.fillText(str, can.width / 20, can.height / 2);
parentNode.style.backgroundImage = "url(" + can.toDataURL("image/png") + ")"; //将canvas转为转为图片展示的dataURL
}
addWaterMarker(binding.value.text, el, binding.value.font, binding.value.textColor)
})

2.在入口文件 main.js引入 directives.js

1
import "@/assets/utils/directives";

注意:directives.js存放的路径 src//assets/utils/directives.js

3.调用指令

  如果希望在整个项目中都添加水印,可以在app.vue中使用指令

1
2
3
4
5
<template>
<div id="app">
<router-view v-watermark="{text:'水印名称',textColor:'rgba(180, 180, 180, 0.3)'}" />
</div>
</template>

我的项目时将{text:’水印名称’,textColor:’rgba(180, 180, 180, 0.3)’}存储在状态机中,以便可以几张管理配置,一旦text内容需要改变,就没必要取所有的组件去修改指令里面的内容了,附上状态机存储

1
2
3
4
5
6
7
 //  state.js
export default {
waterMarkObj: {
text: '水印名称',
textColor: 'rgba(180,180,180,0.3)'
}
};

在组件中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<template>
<div id="app">
<router-view v-watermark="waterMarkObj" />
</div>
</template>
<script>
export default {
computed:{
waterMarkObj() {
return this.$store.state.waterMarkObj;
}
}
};
</script>

补充知识

1.canvas.toDataURL(type, encoderOptions) 方法返回一个包含图片展示的 data URI 。可以使用 type 参数其类型,默认为 PNG 格式。图片的分辨率为96dpi。

参数
  • type 可选
    图片格式,默认为 image/png
  • encoderOptions 可选
    在指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。
  • 如果画布的高度或宽度是0,那么会返回字符串“data:,”。
  • 如果传入的类型非“image/png”,但是返回的值以“data:image/png”开头,那么该传入的类型是不支持的。
  • Chrome支持“image/webp”类型。
    返回值
    包含 data URI 的DOMString。
1
2
<!-- html -->
<canvas id="canvas" width="5" height="5"></canvas>
1
2
3
4
5
// js
var canvas = document.getElementById("canvas");
var dataURL = canvas.toDataURL();
console.log(dataURL);
// data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAD0lEQVQYV2NkwAIYaSAIAAGkAAa+Ds1zAAAAAElFTkSuQmCC

2.Data URLs 即前缀为 data: 协议的URL,其允许内容创建者向文档中嵌入小文件。

data:[mediatype][;base64],[data]
由四个部分组成:

  • 1.前缀(data:)
  • 2.指示数据类型的MIME类型,如果被省略,则默认值为 text/plain;charset=US-ASCII
    • 如果数据是文本类型,你可以直接将文本嵌入 (根据文档类型,使用合适的实体字符或转义字符)。
    • 如果是二进制数据,你可以将数据进行base64编码之后再进行嵌入。
  • 3.如果非文本则为可选的base64标记
  • 4.数据本身
    1
    2
     data:,Hello%2C%20World!
    /* 简单的 text/plain 类型数据 */
    1
    2
      data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D
    /* 上一条示例的 base64 编码版本 */
    1
    2
      data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E
    /* 一个HTML文档源代码 <h1>Hello, World</h1> */
    1
    2
     data:text/html,<script>alert('hi');</script>
    /* 一个会执行 JavaScript alert 的 HTML 文档。注意 script 标签必须封闭。 */

3.canvas.fillText(text, x, y [, maxWidth]) 在指定的(x,y)位置填充指定的文本,绘制的最大宽度是可选的.

  • text 文本内容
  • (x,y)文本的起点
  • maxWidth 绘制的最大宽度

4.canvas.font = value

当前我们用来绘制文本的样式. 这个字符串使用和 CSS font 属性相同的语法. 默认的字体是 10px sans-serif。

5.canvas.textAlign = value

文本对齐选项. 可选的值包括:start, end, left, right or center. 默认值是 start。

6.canvas.textBaseline = value

基线对齐选项. 可选的值包括:top, hanging, middle, alphabetic, ideographic, bottom。默认值是 alphabetic。

7.canvas.direction = value

文本方向。可能的值包括:ltr, rtl, inherit。默认值是 inherit。