文章目录

  • dom结构形成水印(文字+图片)
  • 图片加单个水印
  • 图片加重复水印

dom结构形成水印(文字+图片)

思路:

  • 设置水印的默认样式
  • 判断是否传入配置项,并且将配置项替换默认值
  • 获取页面最大宽度和长度,计算水印列数和行数,遍历创建每一个水印元素
  • 设置每一个水印的样式并添加到页面上

html部分

<template><div id="app-container"><input type="file" @change="fileChange" /></div>
</template>

css部分

* {margin: 0;padding: 0;
}
#app-container {width: 100vw;height: 100vh;
}

js部分

export default {name: 'App',methods: {fileChange (e) {this.watermark({watermarkElement: '#app-container',watermarkImage: URL.createObjectURL(e.target.files[0])})},watermark () {// 默认设置const defaultSettings = {watermarkElement: 'body', // 水印填充节点watermarkTxt: '水印文字', // 水印文字watermarkImage: '', // 水印图片watermarkX: 20, // 水印起始位置x轴坐标watermarkY: 20, // 水印起始位置Y轴坐标watermarkRows: 2000, // 水印行数watermarkCols: 2000, // 水印列数watermarkXSpace: 70, // 水印x轴间隔watermarkYSpace: 30, // 水印y轴间隔watermarkColor: '#aaa', // 水印字体颜色watermarkAlpha: 0.4, // 水印透明度watermarkFontsize: '15px', // 水印字体大小watermarkFont: '微软雅黑', // 水印字体watermarkWidth: 210, // 水印宽度watermarkHeight: 80, // 水印长度watermarkAngle: 15 // 水印倾斜度数}// 传参覆盖默认if (arguments.length === 1 && typeof arguments[0] === 'object') {const argument = arguments[0] || {}const keys = Object.keys(defaultSettings)for (let key of keys) {if (defaultSettings[key] === argument[key]) {continue} else if (argument[key]) {defaultSettings[key] = argument[key]}}}const oTemp = document.createDocumentFragment()const maskElement = document.querySelector(defaultSettings.watermarkElement) || document.body// 获取页面最大宽度const pageWidth = Math.max(maskElement.scrollWidth, maskElement.clientWidth)// 获取页面最大高度const pageHeight = Math.max(maskElement.scrollHeight, maskElement.clientHeight)// 水印数量自适应元素区域尺寸defaultSettings.watermarkCols = Math.floor(pageWidth / (defaultSettings.watermarkXSpace + defaultSettings.watermarkWidth))defaultSettings.watermarkRows = Math.floor(pageHeight / (defaultSettings.watermarkYSpace + defaultSettings.watermarkHeight))let xlet yfor (let i = 0; i < defaultSettings.watermarkRows; i++) {y = defaultSettings.watermarkY + (defaultSettings.watermarkYSpace + defaultSettings.watermarkHeight) * ifor (let j = 0; j < defaultSettings.watermarkCols; j++) {x = defaultSettings.watermarkX + (defaultSettings.watermarkWidth + defaultSettings.watermarkXSpace) * jconst maskDiv = document.createElement('div')maskDiv.id = 'maskDiv' + i + jmaskDiv.className = 'maskDiv'maskDiv.innerHTML = '<span>' + defaultSettings.watermarkTxt + '</span>'maskDiv.style.transform = 'rotate(-' + defaultSettings.watermarkAngle + 'deg)'maskDiv.style.visibility = ''maskDiv.style.position = 'absolute'maskDiv.style.left = x + 'px'maskDiv.style.top = y + 'px'maskDiv.style.overflow = 'hidden'maskDiv.style.zIndex = '9999'maskDiv.style.pointerEvents = 'none' // pointer-events:none  让水印不遮挡页面的点击事件maskDiv.style.opacity = defaultSettings.watermarkAlphamaskDiv.style.fontSize = defaultSettings.watermarkFontsizemaskDiv.style.fontFamily = defaultSettings.watermarkFontmaskDiv.style.color = defaultSettings.watermarkColormaskDiv.style.width = defaultSettings.watermarkWidth + 'px'maskDiv.style.height = defaultSettings.watermarkHeight + 'px'maskDiv.style.display = 'flex'maskDiv.style.justifyContent = 'center'maskDiv.style.alignItems = 'center'if (defaultSettings.watermarkImage) {const img = new Image()img.src = defaultSettings.watermarkImageimg.style.width = 'auto'img.style.height = 'auto'img.style.maxWidth = '80%'img.style.maxHeight = '80%'maskDiv.appendChild(img)}oTemp.appendChild(maskDiv)}}maskElement.appendChild(oTemp)}}
}

结果示例

图片加单个水印

<input type="file" @change="fileChange" />
<img id="img">
<script>
export default {name: 'App',methods: {fileChange (e) {const img = new Image()img.src = URL.createObjectURL(e.target.files[0])img.onload = function () {URL.revokeObjectURL(img.src)const canvas = document.createElement('canvas')canvas.width = this.widthcanvas.height = this.heightconst ctx = canvas.getContext('2d')// 绘制图片到canvasctx.drawImage(img, 0, 0)// 设置填充字号和字体,样式ctx.font = '24px 宋体'ctx.fillStyle = 'silver'// 设置右对齐ctx.textAlign = 'right'// 在指定位置绘制文字,这里指定距离右下角20坐标的地方ctx.fillText('水印文字', canvas.width - 20, canvas.height - 20)document.querySelector('#img').src = canvas.toDataURL()}}}
}
</script>

结果示例:

图片加重复水印

html部分

<template><div id="app-container"><input type="file" @change="fileChange" /><img id="img"></div>
</template>

js部分代码

export default {name: 'App',methods: {createWaterMark () {const canvas = document.createElement('canvas')const ctx = canvas.getContext('2d')canvas.width = 300canvas.height = 200// 绘制之前画布清除ctx.clearRect(0, 0, canvas.width, canvas.height)// 逆时针旋转30度ctx.rotate(-(30 * Math.PI) / 180)// 设置canvas画布样式ctx.font = '24px 黑体'ctx.fillStyle = 'rgba(100, 100, 100, 0.3)'// 设置canvas画布文字ctx.fillText('水印测试', 50, 150)// 坐标系还原ctx.rotate(30 * Math.PI / 180)return canvas},fileChange (e) {const self = thisconst img = new Image()img.src = URL.createObjectURL(e.target.files[0])img.onload = function () {const canvas = document.createElement('canvas')const ctx = canvas.getContext('2d')canvas.width = this.widthcanvas.height = this.heightctx.drawImage(img, 0, 0)const waterMarkCanvas = self.createWaterMark()ctx.fillStyle = ctx.createPattern(waterMarkCanvas, 'repeat')ctx.fillRect(0, 0, canvas.width, canvas.height)document.querySelector('#img').src = canvas.toDataURL()}}}
}

结果示例

探究添加水印的多种方式相关推荐

  1. C++多线程:thread类创建线程的多种方式

    文章目录 描述 函数成员简介 总结 描述 头文件 <thread> 声明方式:std::thread <obj> 简介 线程在构造关联的线程对象时立即开始执行,从提供给作为构造 ...

  2. python单词词频字典_python利用多种方式来统计词频(单词个数)

    python的思维就是让我们用尽可能少的代码来解决问题.对于词频的统计,就代码层面而言,实现的方式也是有很多种的.之所以单独谈到统计词频这个问题,是因为它在统计和数据挖掘方面经常会用到,尤其是处理分类 ...

  3. Java多种方式读文件,追加文件内容,等对文件的各种操作

    一.多种方式读文件内容.1.按字节读取文件内容 2.按字符读取文件内容 3.按行读取文件内容 4.随机读取文件内容 import java.io.BufferedReader;import java. ...

  4. vue引用js文件的多种方式

    本文主要介绍了vue引用js文件的多种方式,本文大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下 1.vue-cli webpack全局引入jquery (1) 首先 npm inst ...

  5. 安装Python库包的多种方式

    安装Python库包的多种方式 文章目录: 一.安装Python库包的方法 1.pip 安装 1) pip 直接下载安装 2) pip 指定镜像源下载 3) pip 通过源码的形式安装 4) pip ...

  6. 《Android深度探索(卷1):HAL与驱动开发》——6.4节使用多种方式测试Linux驱动...

    本节书摘来自异步社区<Android深度探索(卷1):HAL与驱动开发>一书中的第6章,第6.4节使用多种方式测试Linux驱动,作者李宁,更多章节内容可以访问云栖社区"异步社区 ...

  7. 【Python】多种方式实现生成验证码

    多种方式实现生成验证码 1.生成随机n位验证码 import random def make_random_code(n):res = ''for i in range(n):s = chr(rand ...

  8. 多种方式读取文件内容

    2019独角兽企业重金招聘Python工程师标准>>> import java.io.*; /**  *  * @author wxp  * Created by Administr ...

  9. Spring学习总结(一)——Spring实现IoC的多种方式

    一.Spring框架概述 Spring是一个开源免费的框架,为了解决企业应用开发的复杂性而创建.Spring框架是一个轻量级的解决方案,可以一站式地构建企业级应用.Spring是模块化的,所以可以只使 ...

最新文章

  1. 【MATLAB】数据分析之函数数值积分
  2. 5G 与边缘计算的发展现状(2021 年 6 月)
  3. Ribbon负载均衡策略配置
  4. JZOJ 5987. 【WC2019模拟2019.1.4】仙人掌毒题
  5. 一文串起从NLP到CV 预训练技术和范式演进
  6. Effective Java之用接口模拟可伸缩的枚举(三十四)
  7. c++ 已声明变量提示未定义
  8. LeetCode 543二叉树的直径-简单
  9. C++读取文本文件中以TAB作为分隔符,且中间字段有为空的情况的方法?
  10. 前端学习(1833):前端面试题之nodejs的轮询机制
  11. Dynamic CRM 2013学习笔记(四十二)流程5 - 实时/同步工作流(Workflow)用法图解...
  12. 如何在MVC中下载模板和上传word文件
  13. Android的Context 安卓常用系统服务(当前运行包名/当前网络状态和开关网络/音频服务)...
  14. linux服务器上已安装R 用户下载R包,服务器R语言包下载、R包离线安装
  15. IBM Websphere CEI Configuration
  16. 纯js前端导出Excel表格(Excel科学计数法问题)
  17. 君正X1000开发板/方案开发介绍
  18. Tp6 多应用下路由有些没有效果,这是为什么?
  19. openlayers4加载百度地图、百度影像图、谷歌地图、谷歌影像图
  20. krnln.fnr和shell.fne_电脑开机显示failedtoloadkernllibrary什么意思啊

热门文章

  1. 谷歌浏览器账号密码自动填充和明文显示问题
  2. 服务器虚拟化数据怎么转移,从物理服务器迁移到虚拟机的两大方案
  3. BCI Competition 2008 – Graz dataset A个人翻译(附MATLAB安装BioSig)
  4. 计算机应屏后打印不全怎样处理,打印机打印不完整是怎么回事【解决办法】
  5. mysql5.7.17winx64安装_MYSQL数据库mysql 5.7.17 winx64安装配置图文教程
  6. C/C++中的str系列函数大全
  7. 解决Adobe Arcobat Reader DC打开PDF提示:正在准备文档以供阅读,请稍后
  8. 系统加速比(amdahl定律)
  9. 【转】本人常用资源整理(ing...)
  10. R语言ECM误差修正模型、均衡修正模型、受限VECM、协整检验、单位根检验即期利率市场数据