Canvas水印是将文字或图片直接绘制到像素层,导出后不可分离;必须确保img.onload完成、设置crossOrigin、正确使用textBaseline/translate/rotate、适配DPR并规范toDataURL参数。
Canvas 水印不是“加一层遮罩”,而是把文字或图片真正画进像素——导出后不可分离,但必须手动控制加载、坐标、透明度和导出参数,否则白忙一场。
canvas.drawImage 必须等 img.onload 完成才能调用
直接
后立刻
,画布会是空的。浏览器不会报错,但什么也画不出来。
图片必须监听
事件,且该事件只在图片完全解码后触发
跨域图片(如 CDN 上的图)需额外加
,否则后续
会抛
用
读取本地文件时,不用设
,但记得上传后及时
防内存泄漏
fillText 坐标和对齐容易偏移,textBaseline 和 textAlign 得配着用
的
是文字基线位置,不是顶部。默认
,导致文字“悬空”;不设
时,
对应左边缘,极易错位。
居中显示推荐:
+
字体必须显式声明大小和字体族,例如
,否则可能回退到极小的默认值(如 10px)
半透明建议用
,别用
后再填色——后者会影响后续所有绘制
斜向平铺水印要用 save/restore + translate + rotate,不能只 rotate 一次
只写
,整个 canvas 坐标系就歪了,后面所有
或
全部错位,而且无法恢复。
使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
下载
立即学习
“
前端免费学习笔记(深入)
”;
每次旋转前必须
,绘制完立即
旋转中心点靠
移过去,再
,否则绕的是画布原点(0, 0)
平铺效果要循环计算多个位置,例如每 120px 放一个,角度统一为 20°,避免单行水印被裁剪
高 DPR 屏幕(如 Retina)下,记得用
缩放 canvas.width/height,并相应调整
toDataURL 导出时 MIME 类型、质量、跨域三者必须同时对齐
看似简单,但参数错一个,导出就失效:PNG 体积大但无损,JPEG 体积小但模糊,跨域图不处理直接崩。
导出 JPEG 必须传两个参数:
;只传类型不传质量,某些安卓 WebView 会忽略质量并返回 PNG
跨域图未设
就调
,会抛
大图(宽/高 > 4096px)在 Safari iOS 上可能截断,建议预缩放至安全尺寸再绘制
导出后若要替换原
,直接赋值
即可,无需 base64 解码
最常被跳过的其实是 DPR 适配和
配合旋转——前者让水印在 iPhone 上发虚,后者让整页布局突然错乱。这两处没处理,水印就算加上了,也不算“可用”。
img.src = "xxx.jpg"ctx.drawImage(img, 0, 0)onloadimg.crossOrigin = "anonymous"toDataURL()SecurityErrorURL.createObjectURL(file)crossOriginrevokeObjectURLctx.fillText("水印", x, y)ytextBaseline = "alphabetic"textAlignxctx.textBaseline = "middle"ctx.textAlign = "center"ctx.font = "bold 16px sans-serif"rgba(255, 255, 255, 0.25)ctx.globalAlpha = 0.25ctx.rotate(Math.PI / 9)fillTextdrawImagectx.save()ctx.restore()ctx.translate(x, y)rotatewindow.devicePixelRatioctx.scale(dpr, dpr)canvas.toDataURL()toDataURL("image/jpeg", 0.85)crossOrigin="anonymous"toDataURLDOMException: The canvas has been tainted by cross-origin dataimg.src = dataUrlsave/restore