当前位置: 首页 > 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 值在合理区间之内即可。

相关文章:

canvas 实现全屏倾斜重复水印

​ 参考&#xff1a; html、js、canvas实现水印_html页面使用canvas绘制重复水印-CSDN博客 效果 ​​​​ 不求水印显示完全。 实现代码 <template><div class"watermark" ref"waterMark"></div></template><script lang&q…...

vue3项目 前端文件下载的两种工具函数

1、Blob 流下载 Blob 表示不可变的原始数据的类文件对象&#xff0c;通常用于处理文件或大块二进制数据。 注意&#xff1a;js中还有一个二进制数据类型ArrayBuffer&#xff0c;它们的区别如下 Blob 可以位于磁盘、高速缓存内存和其他不可用的位置&#xff1b;ArrayBuffer 是存…...

SpringAI系列 - 升级1.0.0

目录 一、调整pom二、MessageChatMemoryAdvisor调整三、ChatMemory get方法删除lastN参数四、QuestionAnswerAdvisor调整Spring AI发布1.0.0正式版了😅 ,搞起… 一、调整pom <properties><java.version>17</java.version><spring-ai.version>...

5.31 day33

知识点回顾&#xff1a; PyTorch和cuda的安装 查看显卡信息的命令行命令&#xff08;cmd中使用&#xff09; cuda的检查 简单神经网络的流程 数据预处理&#xff08;归一化、转换成张量&#xff09; 模型的定义 继承nn.Module类 定义每一个层 定义前向传播流程 定义损失函数和优…...

Vue3 + VTable 高性能表格组件完全指南,一个基于 Canvas 的高性能表格组件

Vue3 + VTable 高性能表格组件完全指南 前言 VTable 是一个高性能的多维表格组件,专为处理大数据量场景而设计。它支持数十万条数据的快速渲染,提供了丰富的表格功能和良好的用户体验。本文将详细介绍如何在 Vue3 项目中使用 VTable,并解决常见的配置问题。 什么是 VTabl…...

【七. Java字符串操作与StringBuilder高效拼接技巧】

7. java字符串 7.1 API 介绍&#xff1a;应用程序编程接口。在 Java 中&#xff0c;API 指的是 JDK 提供的各种功能类&#xff0c;这些类把底层实现封装好了&#xff0c;我们不用关心内部怎么写的&#xff0c;直接用就行 用 API 帮助文档步骤&#xff1a;以查Random类为例 打…...

题解:洛谷 P12672 「LAOI-8」近期我们注意到有网站混淆视听

设 LGR 存在数量为 x x x&#xff0c;CSP 存在数量为 y y y。 很明显&#xff0c;我们只需要将其中数量较小的一方改没就行了&#xff08;一个巴掌拍不响&#xff09;。 每两个字符串可同意进行一次更改&#xff0c;答案为&#xff1a; ⌈ min ⁡ ( x , y ) 2 ⌉ \left\lce…...

HTML 计算网页的PPI

HTML 计算网页的PPI vscode上安装live server插件&#xff0c;可以实时看网页预览 有个疑问&#xff1a; 鸿蒙density是按照类别写死的吗&#xff0c;手机520dpi 折叠屏426dpi 平板360dpi <html lang"en" data - overlayscrollbars - initialize><header&…...

WIN11+eclipse搭建java开发环境

环境搭建&#xff08;WIN11ECLIPSE&#xff09; 安装JAVA JDK https://www.oracle.com/cn/java/technologies/downloads/#jdk24安装eclipse https://www.eclipse.org/downloads/ 注意&#xff1a;eclipse下载时指定aliyun的软件源&#xff0c;后面安装会快一些。默认是jp汉化e…...

Linux 环境下C、C++、Go语言编译环境搭建秘籍

引言 在当今多元化的编程世界里&#xff0c;C、C 和 Go 语言凭借各自独特的优势&#xff0c;在不同的领域发光发热。C 语言作为一门古老而强大的编程语言&#xff0c;以其高效、贴近硬件的特性&#xff0c;在操作系统、嵌入式系统等底层开发中占据着重要地位&#xff1b;C 作为…...

MMR-Mamba:基于 Mamba 和空间频率信息融合的多模态 MRI 重建|文献速递-深度学习医疗AI最新文献

Title 题目 MMR-Mamba: Multi-modal MRI reconstruction with Mamba and spatial-frequency information fusion MMR-Mamba&#xff1a;基于 Mamba 和空间频率信息融合的多模态 MRI 重建 01 文献速递介绍 磁共振成像&#xff08;MRI&#xff09;因其无创、无辐射特性以及…...

2.5/Q2,Charls最新文章解读

文章题目&#xff1a;Trajectories of depressive symptoms and risk of chronic liver disease: evidence from CHARLS DOI&#xff1a;10.1186/s12876-025-03943-7 中文标题&#xff1a;抑郁症状的轨迹和慢性肝病风险&#xff1a;来自 CHARLS 的证据 发表杂志&#xff1a;BM…...

Unity QFramework 简介

目录 什么是MVC模式&#xff1f; QFramework 架构提供了 Model 的概念 QFramework 架构引入 Command 的方式 QFramework 架构引入 Event事件机制 四个层&#xff1a;表现层、系统层、数据层、工具层 委托和回调函数的关系 命令和事件的区别 工具篇 QFramework整体基于M…...

C++ 日志系统实战第五步:日志器的设计

全是通俗易懂的讲解&#xff0c;如果你本节之前的知识都掌握清楚&#xff0c;那就速速来看我的项目笔记吧~ 本文项目代码编写收尾&#xff01; 日志器类 (Logger) 设计&#xff08;建造者模式&#xff09; 日志器主要用于和前端交互。当我们需要使用日志系统打印 log 时&…...

@Docker Compose部署Alertmanager

文章目录 Docker Compose部署Alertmanager1. 准备工作1.1 系统要求1.2 目录结构准备 2. 配置文件准备2.1 创建docker-compose.yml文件2.2 创建Alertmanager配置文件 3. 部署Alertmanager3.1 启动服务3.2 验证服务状态3.3 检查日志 4. 服务验证4.1 访问Web UI 4.2 API健康检查5.…...

前端面试准备-3

1.let、const、var的区别 ①&#xff1a;let和const为块级作用域&#xff0c;var为全局作用域 ②&#xff1a;let和var可以重新赋值定义&#xff0c;而const不可以 ③&#xff1a;var会提升到作用域顶部&#xff0c;但不会初始化&#xff1b;let和const也会提升到作用不顶部…...

性能测试-jmeter实战1

课程&#xff1a;B站大学 记录软件测试-性能测试学习历程、掌握前端性能测试、后端性能测试、服务端性能测试的你才是一个专业的软件测试工程师 性能测试-jmeter实战1 为什么需要性能测试呢&#xff1f;性能测试的作用&#xff1f;性能测试体系性能测试基础性能测试工具性能监控…...

汽车高速通信的EMC挑战

随着“软件定义汽车”的理念全面渗透,中国汽车行业正加速向集中式电子电气架构(E/E架构)转型。SOA(面向服务的架构)理念推动下,整车开始围绕中央计算平台(OIB)与分布式域控制器(VIU)构建,硬件平台具备前所未有的数据处理能力,能掌控整车控制与实时感知决策。 一、…...

[SC]SystemC在CPU/GPU验证中的应用(五)

SystemC在CPU/GPU验证中的应用(五) 摘要:下面分享50个逐步升级SystemC编程能力的示例及建议的学习路线图。您可以一次一批地完成它们——从前五个基础的例子开始,然后转向channels, TLM, bus models, simple CPU/GPU kernels等等。在每个阶段掌握之后,再进行下一组…...

[蓝桥杯C++ 2024 国 B ] 立定跳远(二分)

题目描述 在运动会上&#xff0c;小明从数轴的原点开始向正方向立定跳远。项目设置了 n n n 个检查点 a 1 , a 2 , ⋯ , a n a_1, a_2, \cdots , a_n a1​,a2​,⋯,an​ 且 a i ≥ a i − 1 > 0 a_i \ge a_{i−1} > 0 ai​≥ai−1​>0。小明必须先后跳跃到每个检查…...

现代网络安全攻防技术与发展现状

1. 引言 随着数字化转型进程的加速&#xff0c;全球信息化程度不断深入&#xff0c;网络安全问题日益凸显。根据最新的统计数据&#xff0c;2022年全球范围内的网络攻击事件较前一年增长了约41%&#xff0c;造成的经济损失高达超过6万亿美元。在这个背景下&#xff0c;了解现代…...

杏仁海棠花饼的学习日记第十四天CSS

一&#xff0c;前言 第二天&#xff0c;今天看CSS。 二&#xff0c;CSS简介及导入方式 CSS简介 CSS&#xff08;层叠样式表&#xff0c;Cascading Style Sheets&#xff09;是一种用于描述 HTML 或 XML&#xff08;包括 SVG、XHTML 等&#xff09;文档呈现效果的样式语言。…...

ESP8266远程控制:实现网络通信与设备控制

概述&#xff1a; 最近一直在弄esp8266的网络通信&#xff0c;但是一直都还没搞懂到底esp8266可不可以通过连接一个网络过后&#xff0c;在很远的地方使用网络将其关掉 在网上找了两个教程都有程序&#xff0c;都跑通了 第一个 第二个找不到了&#xff0c;但是程序有 CSDN上放文…...

RabbitMQ监控:关键技术、技巧与最佳实践

RabbitMQ作为企业级消息中间件的核心组件&#xff0c;其稳定性和性能直接影响分布式系统的可靠性。有效的监控不仅能帮助快速定位问题&#xff0c;还能优化系统资源分配&#xff0c;预防潜在故障。本文基于RabbitMQ官方文档&#xff0c;深入探讨其监控的技术方案、实践技巧及最…...

【机器学习基础】机器学习入门核心算法:隐马尔可夫模型 (HMM)

机器学习入门核心算法&#xff1a;隐马尔可夫模型 &#xff08;HMM&#xff09; 一、算法逻辑与核心思想二、算法原理与数学推导核心问题与算法推导 三、模型评估四、应用案例1. 语音识别 (Speech Recognition)2. 自然语言处理 (Natural Language Processing - NLP)3. 手写体识…...

zookeeper 操作总结

zookeeper 中的节点类型 节点类型命令选项说明‌持久节点‌无选项&#xff08;默认&#xff09;永久存在&#xff0c;除非手动删除。‌临时节点‌-e与客户端会话绑定&#xff0c;会话结束自动删除&#xff08;‌不能有子节点‌&#xff09;。‌顺序节点‌-s节点名自动追加递增…...

golang 实现基于redis的并行流量控制(计数锁)

在业务开发中&#xff0c;有时需要对某个操作在整个集群中限制并发度&#xff0c;例如限制大模型对话的并行数。基于redis zset实现计数锁&#xff0c;做个笔记。 关键词&#xff1a;并行流量控制、计数锁 package redisutilimport ("context""fmt""…...

Leetcode 2819. 购买巧克力后的最小相对损失

1.题目基本信息 1.1.题目描述 现给定一个整数数组 prices&#xff0c;表示巧克力的价格&#xff1b;以及一个二维整数数组 queries&#xff0c;其中 queries[i] [ki, mi]。 Alice 和 Bob 去买巧克力&#xff0c;Alice 提出了一种付款方式&#xff0c;而 Bob 同意了。 对于…...

AI炼丹日志-25 - OpenAI 开源的编码助手 Codex 上手指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇&#xff1a; MyBatis 更新完毕目前开始更新 Spring&#xff0c;一起深入浅出&#xff01; 大数据篇 300&#xff1a; Hadoop&…...

AnyConv OGG 转换器:轻松转换音频格式

在数字音频世界中,不同的文件格式适用于不同的场景和设备。OGG 是一种开放、免费的音频格式,具有高压缩率和良好的音质。然而,有时我们需要将 OGG 文件转换为其他格式,或者将其他格式转换为 OGG。这就是 AnyConv OGG 转换器发挥作用的地方。 什么是 AnyConv OGG 转换器? …...