效果展示
原理讲解
1、计算水印添加的容器的高度和宽度。
2、根据输入的横向间隔和纵向间隔以及水印的大小计算填充满这个页面所需要的水印行数和列数。
3、如果直接按照行数和列数绘制水印可能会导致 边界出现 部分空白的现象,所以需要根据行数和列数重新计算水印的间隔。
使水印可以刚好填充整个容器。
4、根据行数和列数创建DOM节点 按照行或者列绘制水印。
5、为了水印DOM不会影响下面其他DOM元素的鼠标事件,需要设置核心的CSS属性 pointer-events: none;
6、监听浏览器窗口大小改变事件,重新绘制水印。
完整代码
完整代码 github地址 https://github.com/FWC1994/watermark
核心代码
1、自动调整每个水印间距 使其可以填充整个页面
this.pageWidth = Math.max(this.options.node.scrollWidth,this.options.node.clientWidth); this.pageHeight = 1 + Math.max(this.options.node.scrollHeight,this.options.node.clientHeight); // 获取水印行数 并根据行数调整间距使水印填满屏幕 this.options.rows = Math.ceil((this.pageHeight - this.options.startY) / (this.options.markHeight + this.options.ySpace)); this.options.ySpace = Math.floor((this.pageHeight - this.options.startY) / this.options.rows - this.options.markHeight); // 获取水印列数 并根据列数调整间距使水印填满屏幕 this.options.cols = 1 + Math.ceil((this.pageWidth - this.options.startX) / (this.options.markWidth + this.options.xSpace)); this.options.xSpace = Math.floor((this.pageWidth - this.options.startX) / this.options.cols - this.options.markWidth);
2、 填充水印
var domTemp = document.createDocumentFragment(); for(var i = 0; i < this.options.rows; i++){ var posY = i * (this.options.markHeight + this.options.ySpace) + this.options.startY; for(var j = 0; j < this.options.cols; j++){ var posX = j * (this.options.markWidth + this.options.xSpace) + this.options.startX; domTemp.appendChild(this._createWaterMark(posX, posY)); } } var markContainer = document.createElement('div'); markContainer.className = 'water-mark-container'; markContainer.appendChild(domTemp); this.options.node.appendChild(markContainer);
3、构造每个水印节点
var markDiv = document.createElement('div'); markDiv.className = 'water-mark-item'; if(this.options.imageSrc){ markDiv.innerHTML = "<div>"+this.options.text+"</div><img src='"+this.options.imageSrc+"'/>"; }else{ markDiv.appendChild(document.createTextNode(this.options.text)); } //设置水印div倾斜显示 markDiv.style.webkitTransform = "rotate(-" + this.options.angle + "deg)"; markDiv.style.MozTransform = "rotate(-" + this.options.angle + "deg)"; markDiv.style.msTransform = "rotate(-" + this.options.angle + "deg)"; markDiv.style.OTransform = "rotate(-" + this.options.angle + "deg)"; markDiv.style.transform = "rotate(-" + this.options.angle + "deg)"; markDiv.style.position = "absolute"; markDiv.style.left = x + 'px'; markDiv.style.top = y + 'px'; markDiv.style.overflow = "hidden"; markDiv.style.zIndex = "99999"; markDiv.style.width = this.options.markWidth + 'px'; markDiv.style.height = this.options.markHeight + 'px'; markDiv.style.display = "block"; markDiv.style.pointerEvents='none'; markDiv.style.opacity = this.options.opacity; markDiv.style.textAlign = "center"; markDiv.style.fontFamily = this.options.fontFamily; markDiv.style.fontSize = this.options.fontSize; markDiv.style.color = this.options.color;
使用方法
var waterMark = new WaterMark(document.getElementsByTagName('body')[0],{ text:"这是一条水印", color:"#000000", imageSrc:'./logo.png' });
外部接口
- show() 显示水印
- hide() 隐藏水印
- refresh() 容器大小改变后主动刷新调用