Commit 7cf954cf2f20f18a3216278ad4cf9cb26c8e84e7
1 parent
8c1626a5
feat(component): 支持水印功能 !#en: add watermark
Showing
2 changed files
with
83 additions
and
4 deletions
front-end/h5/src/components/plugins/lbp-background.js
| @@ -9,9 +9,29 @@ | @@ -9,9 +9,29 @@ | ||
| 9 | * @Copyright 2018 - 2019 luban-h5. All Rights Reserved | 9 | * @Copyright 2018 - 2019 luban-h5. All Rights Reserved |
| 10 | */ | 10 | */ |
| 11 | import PropTypes from '@luban-h5/plugin-common-props' | 11 | import PropTypes from '@luban-h5/plugin-common-props' |
| 12 | +import { renderWaterMark } from '../../utils/dom-helper' | ||
| 12 | 13 | ||
| 13 | export default { | 14 | export default { |
| 14 | name: 'lbp-background', | 15 | name: 'lbp-background', |
| 16 | + props: { | ||
| 17 | + imgSrc: PropTypes.image({ label: '背景图' }), | ||
| 18 | + backgroundColor: PropTypes.color({ label: '背景色', defaultValue: 'rgba(255, 255, 255, 0.2)' }), | ||
| 19 | + waterMarkText: PropTypes.string({ label: '水印文字', defaultValue: '水印文字' }), | ||
| 20 | + waterMarkFontSize: PropTypes.number({ label: '水印文字大小(px)', defaultValue: 16 }), | ||
| 21 | + waterMarkRotate: PropTypes.number({ label: '水印旋转角度', defaultValue: 10 }), | ||
| 22 | + waterMarkColor: PropTypes.color({ label: '水印文字颜色', defaultValue: 'rgba(184, 184, 184, 0.2)' }) | ||
| 23 | + }, | ||
| 24 | + methods: { | ||
| 25 | + renderWaterMark () { | ||
| 26 | + renderWaterMark({ | ||
| 27 | + container: this.$refs.root, | ||
| 28 | + content: this.waterMarkText, | ||
| 29 | + fontSize: this.waterMarkFontSize, | ||
| 30 | + rotate: this.waterMarkRotate, | ||
| 31 | + fillStyle: this.waterMarkColor | ||
| 32 | + }) | ||
| 33 | + } | ||
| 34 | + }, | ||
| 15 | render () { | 35 | render () { |
| 16 | let style = { | 36 | let style = { |
| 17 | width: '100%', | 37 | width: '100%', |
| @@ -35,13 +55,16 @@ export default { | @@ -35,13 +55,16 @@ export default { | ||
| 35 | 55 | ||
| 36 | return ( | 56 | return ( |
| 37 | // [知识点:CSS] : https://codesandbox.io/s/ziyuansuzindexzaigao-wufafugaifuyuansudexiongdiyuansu-n15rd?file=/index.html | 57 | // [知识点:CSS] : https://codesandbox.io/s/ziyuansuzindexzaigao-wufafugaifuyuansudexiongdiyuansu-n15rd?file=/index.html |
| 38 | - <div style="width: 100%; height: 100%; overflow: hidden; position: absolute; z-index: 0; opacity: 1;"> | 58 | + <div style="width: 100%; height: 100%; overflow: hidden; position: absolute; z-index: 0; opacity: 1;" ref="root"> |
| 39 | <div style={style}></div> | 59 | <div style={style}></div> |
| 40 | </div> | 60 | </div> |
| 41 | ) | 61 | ) |
| 42 | }, | 62 | }, |
| 43 | - props: { | ||
| 44 | - imgSrc: PropTypes.image(), | ||
| 45 | - backgroundColor: PropTypes.color({ label: '背景色', defaultValue: 'rgba(255, 255, 255, 0.2)' }) | 63 | + mounted () { |
| 64 | + this.renderWaterMark() | ||
| 65 | + | ||
| 66 | + ;['waterMarkText', 'waterMarkFontSize', 'waterMarkRotate', 'waterMarkColor'].forEach(key => { | ||
| 67 | + this.$watch(key, this.renderWaterMark) | ||
| 68 | + }) | ||
| 46 | } | 69 | } |
| 47 | } | 70 | } |
front-end/h5/src/utils/dom-helper.js
| @@ -9,3 +9,59 @@ export function contains (root, n) { | @@ -9,3 +9,59 @@ export function contains (root, n) { | ||
| 9 | 9 | ||
| 10 | return false | 10 | return false |
| 11 | } | 11 | } |
| 12 | + | ||
| 13 | +/** | ||
| 14 | + * | ||
| 15 | + * @param {*} param0 canvas 实现 watermark | ||
| 16 | + */ | ||
| 17 | +export function renderWaterMark ({ | ||
| 18 | + // 使用 ES6 的函数默认值方式设置参数的默认取值 | ||
| 19 | + // 具体参见 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Default_parameters | ||
| 20 | + container = document.body, | ||
| 21 | + width = '100px', | ||
| 22 | + height = '100px', | ||
| 23 | + textAlign = 'center', | ||
| 24 | + textBaseline = 'middle', | ||
| 25 | + fontSize = 16, | ||
| 26 | + fillStyle = 'rgba(184, 184, 184, 0.2 )', | ||
| 27 | + content = '水印文字', | ||
| 28 | + rotate = 0, | ||
| 29 | + zIndex = 1000 | ||
| 30 | +} = {}) { | ||
| 31 | + var canvas = document.createElement('canvas') | ||
| 32 | + | ||
| 33 | + canvas.setAttribute('width', width) | ||
| 34 | + canvas.setAttribute('height', height) | ||
| 35 | + var ctx = canvas.getContext('2d') | ||
| 36 | + | ||
| 37 | + ctx.textAlign = textAlign | ||
| 38 | + ctx.textBaseline = textBaseline | ||
| 39 | + ctx.font = `${fontSize}px Arial` | ||
| 40 | + ctx.fillStyle = fillStyle | ||
| 41 | + // ctx.rotate(Math.PI / 180 * rotate); | ||
| 42 | + ctx.fillText(content, 0, parseFloat(height) / 3) | ||
| 43 | + | ||
| 44 | + var base64Url = canvas.toDataURL() | ||
| 45 | + const wmEl = document.querySelector('.luban_h5__wm') | ||
| 46 | + | ||
| 47 | + const watermarkDiv = wmEl || document.createElement('div') | ||
| 48 | + const styleStr = ` | ||
| 49 | + transform: rotate(${rotate}deg); | ||
| 50 | + position:absolute; | ||
| 51 | + top:0; | ||
| 52 | + left:0; | ||
| 53 | + width:100%; | ||
| 54 | + height:100%; | ||
| 55 | + z-index:${zIndex}; | ||
| 56 | + pointer-events:none; | ||
| 57 | + background-repeat:repeat; | ||
| 58 | + background-image:url('${base64Url}')` | ||
| 59 | + | ||
| 60 | + watermarkDiv.setAttribute('style', styleStr) | ||
| 61 | + | ||
| 62 | + if (!wmEl) { | ||
| 63 | + watermarkDiv.classList.add('luban_h5__wm') | ||
| 64 | + container.style.position = 'relative' | ||
| 65 | + container.insertBefore(watermarkDiv, container.firstChild) | ||
| 66 | + } | ||
| 67 | +} |