最近工作需求,需要在页面上加水印,但发现网上示例无法满足我的需求,所以还是自己动手写。
有几个特别需求:
1.可以写多行水印,并且中心对齐。
2.每行水印错开。
PS:我找到的例子都是单行水印,所以用不了,想做的效果如下。
(图1)
实现思路
实现页面水印主要是有两种方法。
1.DOM元素
就是将水印放置DOM元素里,按一定规律铺设在目标区域。
优点:
(1).元素计算方式相对简单些
缺点:
2.canvas
先将水印写在canvas里,然后生成背景图,用背景图铺设。
优点:
(1).不用担心目标区域动态变化。
缺点:
(2).计算方式复杂。
思量后,选择了第二种实现方式,性能为重。
实现难点
1.canvas没有针对文字的旋转
在canvas绘图里面,没有针对文字旋转的控制,所以只能旋转画布后,对每行文字一个个按规律排放。
如下图,x0y是视区(也就是你能看到的),x’0y’是旋转了A角度后的画布,所以我们在画布绘制时,每行文字的位置都要做一个修正。
(图2)
PS:矩形代表每行文字,width是每行文字的水平间距,height是第一行文字y坐标。
得出每行文字坐标公式是(伪代码):
x = width * cosA;
y = x * tanA + height;
(图3)
所以在错开的方法上,我使用了三个canvas,第一个canvas正式绘制,第二个将文字数组倒过来绘制,将前两个绘制在第三个canvas上,这样就错开了。
3.每行文字长度不等引起的水平间距问题
如下图,a、b是两段文字,较长的b会导致水平方向间距变大,如果直接使用做背景图,那么在背景repeat时候,将存在水平方向长短不一情况,看起来很难受。
(图4)
对于这个问题,我的解决方法是,将a、b两段文字水平方向上重复绘制多次,就变成绘制a、b、a、b、a、b,在足够多的次数后,看到间距就正常。
4.第一行文字x不是从0开始
其实在画布旋转后,在视窗里看到的第一行就不是从0开始(虽然绘制是0),从图2就可以看到,还有一段距离。
(图5)
例如将第一行移到视窗p点,那么就要做tx、ty的修正,伪代码:
tx = height * sinA * cosA;
ty = height * sinA * sinA;
PS:这个地方如果有人看我代码,就会发现ty乘多一个sinA,位移才正确,这一点我也想不懂,希望有人知道告诉我。
代码
我将代码放到GitHub上,有啥建议请提。
代码地址: https://github.com/codingforme/jquery-watermark
最后的效果,其实就是图1。
总结
这是个简单的插件,代码不多,其实本身也不需要jquery,只是习惯性这么实现。这里其实有个重点,就是视区和画布,我在svg文章里面有总结过,可以看看,另外我遇到的几个难点的解决办法,希望对大家有所发现。
本文为原创文章,转载请保留原出处,方便溯源,如有错误地方,谢谢指正。