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

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 值在合理区间之内即可。

相关文章:

  • Linux应用开发之网络套接字编程
  • 本地部署消息代理软件 RabbitMQ 并实现外部访问( Windows 版本 )
  • .NET8入门:14.ASP.NET Core MVC进阶——Model
  • MMR搜索和LangChain整合Milvus实战
  • 使用 Flutter 开发 App 时,想要根据 Figma 设计稿开发出响应式 UI 界面
  • 将 Figma 设计稿通过编码一比一还原成 App 界面
  • 数学复习笔记 21
  • 【科研绘图系列】R语言绘制GO term 富集分析图(enrichment barplot)
  • 100个 Coze 智能体实战案例
  • Vite打包优化实践:从分包到性能提升
  • WPS 免登录解锁编辑
  • window 显示驱动开发-转换 Direct3D 固定函数状态(二)
  • 软件工程 3.0:智能驱动的软件新时代
  • OpenFeign vs MQ:微服务通信如何选型?详解同步与异步的适用场景
  • kafka学习笔记(三、消费者Consumer使用教程——从指定位置消费)
  • 性能测试-jmeter实战1
  • SSE流式传输
  • QML视图组件ListView、TableView、GridView介绍
  • 逻辑回归知识点
  • PostgreSQL学会如何建表
  • 优秀网站要素/网站制作郑州
  • 怎么做企业网站推广的方法/seo 重庆
  • 凯里网站设计/最新军事动态最新消息
  • 企业网站建设定制网站建设公司/郑州网络推广哪家口碑好
  • 做家政网站公司名称/周口seo
  • 高端网站开发平台/优化建站seo门户