一、使用canvas创建一个与窗口大小一致的画布,然后使用canvas的fillText的方法绘制水印。

此方法有几个注意点:

1. 画布不能覆盖网页上的有效事件,因些需要给canvas设置pointer-events: none;样式

2.创建的画布大小需要是窗口对角线尺寸的正方形,保证在画布在旋转某个角度时4个角不会出现空白区。同时需要将canvas的与当前窗口的尺寸进行计算出向左、向上的偏移量。

3. 计算绘制的文字长度时,一定要设置font属性,否则会使用画布默认的字体大小计算长度,容易出现bug。

4. 计算行数、列数时,需要注意,尤其在fillText时规划好x,y坐标

5. 在旋转画布时,一定要将旋转中心设置到画布的x,y轴的中心位置,旋转完毕后再复原置原来位置。

import React, { useEffect, useRef } from "react"
import PropTypes from 'prop-types'export default function Watermark({ text, rotate }) {const canvasRef = useRef(null)const setCanvasData = () => {const canvas = canvasRef.currentconst 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))// 修改画布在容器中的偏移,使其中心位置与容器的中心位置永远保持一致// 在旋转角度时也要以其中心点为中心进行旋转canvas.style.position = 'fixed'canvas.style.top = - Math.ceil((minSizeCanvas - maxSizeContainer) / 2) + 'px'canvas.style.left = - Math.ceil((minSizeCanvas - maxSizeContainer) / 2) + 'px'// 画笔const ctx = canvas.getContext('2d')// 设置笔触样式,font的样式一定要在measureText方法调用前ctx.font = '16px 微软雅黑'ctx.fillStyle = '#ddd'ctx.textAlign = 'left'ctx.textBaseline = 'middle'// 计算字符串的横向与纵向间距,设置了font的大小与字体const offsetX  = Math.ceil(ctx.measureText(text).width) + 60const offsetY = 110// 列/行数const rowCount = Math.ceil(minSizeCanvas / offsetY)const colCount = Math.ceil(minSizeCanvas / offsetX)// 旋转ctx.translate(minSizeCanvas / 2, minSizeCanvas / 2)ctx.rotate(rotate * Math.PI / 180)ctx.translate(-minSizeCanvas / 2, -minSizeCanvas / 2)// 行for(let i=0; i<rowCount; i++) {// 列for(let j=0; j<colCount; j++) {ctx.fillText(text, offsetX * j, offsetY * i)}}}useEffect(() => {window.addEventListener('resize', setCanvasData)return function cleanup() {window.removeEventListener('resize', setCanvasData)}}, [])useEffect(() => {setCanvasData()}, [text, rotate])return (<canvas ref={canvasRef} />)
}Watermark.propTypes = {text: PropTypes.string.isRequired,rotate: PropTypes.number
}

二、使用canvas的toDataURL方法导出图片的base64的代码,使用css background-repeat属性将图片作为背景进行填充。

import React from "react"
import styles from './scss/wm.module.scss'const createImage = function (text) {const canvas = document.createElement('canvas')// 画笔const ctx = canvas.getContext('2d')// 修改画布在容器中的偏移,使其中心位置与容器的中心位置永远保持一致// 在旋转角度时也要以其中心点为中心进行旋转canvas.style.display = 'none'// 设置笔触样式,font的样式一定要在measureText方法调用前ctx.font = '16px 微软雅黑'ctx.fillStyle = '#ddd'ctx.textAlign = 'left'ctx.textBaseline = 'middle'// 计算字符串的横向与纵向间距,设置了font的大小与字体const offsetX  = Math.ceil(ctx.measureText(text).width) + 60// 设置画面的最小尺寸canvas.setAttribute('width', String(offsetX))// 高度可以增加行间距canvas.setAttribute('height', String(100))ctx.fillText(text, 0, 8)return canvas.toDataURL('image/png')
}function WaterMark({ text, rotate }) {const [count, setCount] = React.useState(0)const onResize = React.useCallback(() => {// 设置画布大小const canvasParent = document.body// 画布大小需要为容器的对角线长度,// 画布在旋转时不会出现对角空白无水印!!!const maxSizeContainer = Math.max(canvasParent.offsetWidth, canvasParent.offsetHeight)const minSizeCanvas = Math.ceil(Math.SQRT2 * maxSizeContainer)setCount(minSizeCanvas)}, [])React.useEffect(() => {onResize()window.addEventListener('resize', onResize)return () => {window.removeEventListener('resize', onResize)}}, [])return (<div className={styles.container} style={{backgroundImage: `url(${createImage(text)})`,height: count,width: count}} />)
}export default WaterMark
.container {transform: rotate(-30deg) translate(-20%, -40%);background-repeat: repeat;width: 200%;min-width: 200%;height: 200%;min-height: 200%;
}

canvas实现水印效果相关推荐

  1. 使用canvas实现水印效果

    通过canvas绘制生成base64背景图,使用repeat重复背景,达到充满整个元素的水印效果 function createWatermark(str, el = document.body) { ...

  2. gdiplus 水印_Delphi程序的应用GDI+制作水印效果图片

    利用GDI+可以很方便的制作带水印效果的图片,网上介绍这方面的文章也很多,但鲜有Delphi的,本文参照网上文章http://www.codeproject.com/KB/GDI-plus/water ...

  3. android视频处理之动态时间水印效果

    最近的项目中遇到一个非常头痛的需求,在android端录制视频的时候动态添加像监控画面一样的精确到秒的时间信息,关键是,并不是说只在播放器的界面显示时间就可以了,而是录制到视频里面去,这个MP4在电脑 ...

  4. Asp.net(C#)给图片加上水印效果(转自园上的Seven Eleven)

    Asp.net(C#)给图片加上水印效果 private void Btn_Upload_Click(object sender, System.EventArgs e)         {      ...

  5. html中放大镜案列,Canvas实现放大镜效果完整案例分析(附代码)

    本文主要记录 canvas 在图像.文字处理.离屏技术和放大镜特效的实现过程中使用到的api.先看下效果吧: 一张模糊的图片: 鼠标点击任意位置,产生放大效果: 哇塞~ 一个帅哥,哈哈哈哈~ 1.放大 ...

  6. 原生js实现canvas气泡冒泡效果

    说明: 本文章主要分为ES5和ES6两个版本 ES5版本是早期版本,后面用ES6重写优化的,建议使用ES6版本. 1, 原生js实现canvas气泡冒泡效果的插件,api丰富,使用简单 2, 只需引入 ...

  7. java做橡皮擦效果_HTML5 canvas橡皮擦擦拭效果

    这是一款HTML5 canvas橡皮擦擦拭效果.该效果通过canvas来制作遮罩层和擦拭用的橡皮擦,用户可以通过移动鼠标来移除遮罩层,效果非常炫酷. 因为发代码有时会排版混乱,所以先发图演示了.源码已 ...

  8. WPF实现TextBox水印效果

    原文:WPF实现TextBox水印效果 在日常项目中,一个TextBox需要输入用户名,我们通常的做法是先用一个TextBlock来说明,例如下面的截图: 今天将使用另外一种方式来展示,使用水印的方式 ...

  9. 鼠标点击特效:canvas点击效果

    JS代码(代码中包含了sketch.min.js的源码,如果你的网站已经引用了,请删掉下面的6到7行.): /** 鼠标点击特效:canvas点击效果*/ /* Copyright (C) 2013 ...

最新文章

  1. Animation动画:
  2. POJ 2151 Check the difficulty of problems (概率dp)
  3. Excel 2016中的新增函数之CONCAT
  4. mysql索引 钱缀_【mysql索引】之前缀索引-Go语言中文社区
  5. ALGO-117_蓝桥杯_算法训练_友好数
  6. 三、如何手动实现一个微前端框架雏形
  7. Robot Framework: 自定义自己的python库
  8. flutter输入框TextField中文本textAlign对齐分析篇
  9. bzoj 2464: 中山市选[2009]小明的游戏(BFS)
  10. ubuntu 安装php gd,如何在ubuntu上安装php5-gd?
  11. 牛逼!B 站 up 主开源视频字幕自动翻译神器!
  12. 【LinuxOS】Ubuntu学习感悟
  13. 2017-07-07 2,3,5,7倍数
  14. 异或、或、与(且)的运算
  15. 游戏项目管理经验方法
  16. shell脚本控制jar包启停
  17. 【从零开始学Skynet】基础篇(二):了解Skynet
  18. 大华web开发工具包使用
  19. 2022SDUT知到/智慧树----C语言第十章测试题解(完结)
  20. html5相册快速制作软件,HTML5 Slideshow Maker(HTML5幻灯片相册制作工具)

热门文章

  1. Android 长度单位(dp、sp、px、in、pt、mm)详解
  2. storm风暴英雄 tempo_暴雪发布2018《风暴英雄》HGC战队实力排行榜
  3. C#windows竞赛管理系统
  4. 安全问题的思考---君子不立于危墙之下
  5. EPPlus批量插入图片到Excel
  6. 在OCI中为计算实例添加第二块网卡
  7. 百度网盘提速加速方法
  8. 用友通新建账套显示不能登入到服务器,用友通打不开,出现登录失败
  9. rust如何在木板上上传图片_腐蚀rust游戏玩法方式详解
  10. excel选择性粘贴为何是html,Excel选择性粘贴预览有什么功能