当前位置: 首页 > article >正文

canvas 实现全屏倾斜重复水印

参考:

  1. html、js、canvas实现水印_html页面使用canvas绘制重复水印-CSDN博客

效果

​​​​在这里插入图片描述

不求水印显示完全。

实现代码


<template><div class="watermark" ref="waterMark"></div></template><script lang="ts">import { Component, Vue, Prop, Watch, Ref } from 'vue-property-decorator'@Component({name: 'WaterMark',components: {},})export default class WaterMark extends Vue {@Prop({ default: '' })private text!: string // 水印文本内容// 水印配置参数private config: any = {angle: -30, // 统一倾斜角度 [-90, 90]fontSize: 20, // 字体大小fontFamily: 'Arial, sans-serif', // 字体color: 'rgba(0, 0, 0, 0.5)', // '#cccccc', // 文字颜色opacity: 0.5, // 透明度zIndex: 999, // 层叠顺序gap: [200, 200], // 水印之间的间距[行,纵]}@Ref()private waterMark!: HTMLDivElement@Watch('text', { immediate: true })private onTextChange() {this.createWatermarks()}// 批量创建水印private createWatermarks() {this.addWatermark(this.text)}mounted() {// 确保页面加载完成后再创建水印this.$nextTick(() => {this.createWatermarks()})// 窗口变化时重新生成window.addEventListener('resize', this.createWatermarks)}private addWatermark(text: any) {if (!this.waterMark && !text) {return}const { fontSize, opacity, color, fontFamily, angle, gap } = this.configconst canvas: any = document.createElement('canvas')const ctx: any = canvas.getContext('2d')const width: any = window.innerWidthconst height: any = window.innerHeightlet nWidth = widthlet nHeight = heightif (angle) {// 根据角度计算宽高和原点移动const radian = (angle * Math.PI) / 180const sin = Math.sin(Math.abs(radian))const cos = Math.cos(Math.abs(radian))nWidth = width + height * sinnHeight = width * sin + height * coscanvas.width = nWidthcanvas.height = nHeightctx.translate(-height * sin * cos, height * sin * sin)ctx.rotate(radian)}ctx.globalAlpha = opacityctx.font = `${fontSize}px ${fontFamily}`ctx.fillStyle = color // 文字颜色和透明度ctx.textAlign = 'center'ctx.textBaseline = 'middle'// 在页面上重复绘制水印for (let x = 0, i = 0; x < nWidth; x += text.length * fontSize + gap[0]) {for (let y = 0; y < nHeight; y += gap[1]) {ctx.fillText(text, x + (i % 2) * (gap[0] / 2), y)i++}}const watermark = new Image()watermark.src = canvas.toDataURL('image/png')if (this.waterMark.style) {this.waterMark.style.backgroundImage = `url(${watermark.src})`this.waterMark.style.backgroundRepeat = 'repeat'}this.waterMark.dataset.watermark = 'true' // 标记水印元素}}</script><style lang="scss" scoped>.watermark {position: fixed;top: 0;left: 0;width: 100%;height: 100%;pointer-events: none;z-index: 9999;}</style>
计算旋转后的宽高和移动原点位置

蓝色长方形为原画布长宽,已知为 h,w(此处即为屏幕长宽)。

浅蓝色长方形为以A点为旋转中心,旋转x度之后的画布,

需要得到旋转之后能覆盖原画布大小的长宽-深蓝色长方形,即可求得:hsinX+w(长度没有很严格), hcosX+wsinX

旋转点也从 A点跑到了 B点:(- hsinXsinX, hsinXcosX)

在这里插入图片描述

公式补充

在这里插入图片描述
在这里插入图片描述

提示

如果要考虑文字都在可视区域,还需要考虑 textLefttextRight


const measureText = ctx.measureText(text)const textLeft = measureText.actualBoundingBoxLeftconst textRight = measureText.actualBoundingBoxRight

另外只要判断 xy 值在合理区间之内即可。

http://www.lryc.cn/news/2394957.html

相关文章:

  • vue3项目 前端文件下载的两种工具函数
  • SpringAI系列 - 升级1.0.0
  • 5.31 day33
  • Vue3 + VTable 高性能表格组件完全指南,一个基于 Canvas 的高性能表格组件
  • 【七. Java字符串操作与StringBuilder高效拼接技巧】
  • 题解:洛谷 P12672 「LAOI-8」近期我们注意到有网站混淆视听
  • HTML 计算网页的PPI
  • WIN11+eclipse搭建java开发环境
  • Linux 环境下C、C++、Go语言编译环境搭建秘籍
  • MMR-Mamba:基于 Mamba 和空间频率信息融合的多模态 MRI 重建|文献速递-深度学习医疗AI最新文献
  • 2.5/Q2,Charls最新文章解读
  • Unity QFramework 简介
  • C++ 日志系统实战第五步:日志器的设计
  • @Docker Compose部署Alertmanager
  • 前端面试准备-3
  • 性能测试-jmeter实战1
  • 汽车高速通信的EMC挑战
  • [SC]SystemC在CPU/GPU验证中的应用(五)
  • [蓝桥杯C++ 2024 国 B ] 立定跳远(二分)
  • 现代网络安全攻防技术与发展现状
  • 杏仁海棠花饼的学习日记第十四天CSS
  • ESP8266远程控制:实现网络通信与设备控制
  • RabbitMQ监控:关键技术、技巧与最佳实践
  • 【机器学习基础】机器学习入门核心算法:隐马尔可夫模型 (HMM)
  • zookeeper 操作总结
  • golang 实现基于redis的并行流量控制(计数锁)
  • Leetcode 2819. 购买巧克力后的最小相对损失
  • AI炼丹日志-25 - OpenAI 开源的编码助手 Codex 上手指南
  • AnyConv OGG 转换器:轻松转换音频格式
  • C# 类和继承(使用基类的引用)