iep-ui
Version:
An enterprise-class UI design language and Vue-based implementation
220 lines (208 loc) • 7.24 kB
JavaScript
import _extends from 'babel-runtime/helpers/extends';
import PropTypes from '../_util/vue-types';
import classNames from 'classnames';
import { ConfigConsumerProps } from '../config-provider/configConsumerProps';
/**
* 返回当前显示设备的物理像素分辨率与CSS像素分辨率之比
*
* @param context
* @see 其实类型 CanvasRenderingContext2D
*/
var getPixelRatio = function getPixelRatio(context) {
if (!context) {
return 1;
}
var backingStore = context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1;
return (window.devicePixelRatio || 1) / backingStore;
};
export default {
name: 'AWaterMark',
props: {
/** 类名 */
customClass: PropTypes.string,
/** 样式 */
customStyle: PropTypes.object,
/** 水印样式 */
markStyle: PropTypes.object,
/** 水印类名 */
markClassName: PropTypes.string,
/** 水印之间的水平间距 */
gapX: PropTypes.number.def(212),
/** 水印之间的垂直间距 */
gapY: PropTypes.number.def(212),
/** 追加的水印元素的z-index */
zIndex: PropTypes.number.def(9),
/** 水印的宽度 */
width: PropTypes.number.def(120),
/** 水印的高度 */
height: PropTypes.number.def(64),
/** 水印在canvas 画布上绘制的垂直偏移量,正常情况下,水印绘制在中间位置, 即 offsetTop = gapY / 2 */
offsetTop: PropTypes.number, // 水印图片距离绘制 canvas 单元的顶部距离
/** 水印在canvas 画布上绘制的水平偏移量, 正常情况下,水印绘制在中间位置, 即 offsetTop = gapX / 2 */
offsetLeft: PropTypes.number,
/** 水印绘制时,旋转的角度,单位 ° */
rotate: PropTypes.number.def(-22),
/** 高清印图片源, 为了高清屏幕显示,建议使用 2倍或3倍图,优先使用图片渲染水印。 */
image: PropTypes.string,
/** 水印文字内容 */
content: PropTypes.string,
/** 文字颜色 */
fontColor: PropTypes.string.def('rgba(0,0,0,.15)'),
/** 文字样式 */
fontStyle: PropTypes.oneOf(['none', 'normal', 'italic', 'oblique']).def('normal'),
/** 文字族 */
fontFamily: PropTypes.string.def('sans-serif'),
/** 文字粗细 */
fontWeight: PropTypes.number.def(400),
/** 文字大小 */
fontSize: PropTypes.number.def(16)
},
data: function data() {
return {
base64Url: ''
};
},
computed: {
watchParams: function watchParams() {
var _$props = this.$props,
gapX = _$props.gapX,
gapY = _$props.gapY,
offsetLeft = _$props.offsetLeft,
offsetTop = _$props.offsetTop,
rotate = _$props.rotate,
fontStyle = _$props.fontStyle,
fontWeight = _$props.fontWeight,
width = _$props.width,
height = _$props.height,
fontFamily = _$props.fontFamily,
fontColor = _$props.fontColor,
image = _$props.image,
content = _$props.content,
fontSize = _$props.fontSize;
return {
gapX: gapX,
gapY: gapY,
offsetLeft: offsetLeft,
offsetTop: offsetTop,
rotate: rotate,
fontStyle: fontStyle,
fontWeight: fontWeight,
width: width,
height: height,
fontFamily: fontFamily,
fontColor: fontColor,
image: image,
content: content,
fontSize: fontSize
};
}
},
inject: {
configProvider: { 'default': function _default() {
return ConfigConsumerProps;
} }
},
watch: {
watchParams: {
handler: function handler(e) {
this.initCanvas();
},
immediate: true
}
},
methods: {
initCanvas: function initCanvas() {
var _this = this;
var _$props2 = this.$props,
gapX = _$props2.gapX,
gapY = _$props2.gapY,
offsetLeft = _$props2.offsetLeft,
offsetTop = _$props2.offsetTop,
width = _$props2.width,
height = _$props2.height,
rotate = _$props2.rotate,
image = _$props2.image,
fontSize = _$props2.fontSize,
fontStyle = _$props2.fontStyle,
fontWeight = _$props2.fontWeight,
fontFamily = _$props2.fontFamily,
fontColor = _$props2.fontColor,
content = _$props2.content;
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var ratio = getPixelRatio(ctx);
var canvasWidth = (gapX + width) * ratio + 'px';
var canvasHeight = (gapY + height) * ratio + 'px';
var canvasOffsetLeft = offsetLeft || gapX / 2;
var canvasOffsetTop = offsetTop || gapY / 2;
canvas.setAttribute('width', canvasWidth);
canvas.setAttribute('height', canvasHeight);
if (ctx) {
ctx.translate(canvasOffsetLeft * ratio, canvasOffsetTop * ratio);
ctx.rotate(Math.PI / 180 * Number(rotate));
var markWidth = width * ratio;
var markHeight = height * ratio;
if (image) {
var img = new Image();
img.crossOrigin = 'anonymous';
img.referrerPolicy = 'no-referrer';
img.src = image;
img.onload = function () {
ctx.drawImage(img, 0, 0, markWidth, markHeight);
_this.base64Url = canvas.toDataURL();
};
} else if (content) {
var markSize = Number(fontSize) * ratio;
ctx.font = fontStyle + ' normal ' + fontWeight + ' ' + markSize + 'px/' + markHeight + 'px ' + fontFamily;
ctx.fillStyle = fontColor;
ctx.fillText(content, 0, 0);
this.base64Url = canvas.toDataURL();
}
} else {
console.error('当前环境不支持Canvas');
}
}
},
render: function render() {
var h = arguments[0];
var customizePrefixCls = this.prefixCls,
$slots = this.$slots,
$props = this.$props,
base64Url = this.base64Url;
var customStyle = $props.customStyle,
customClass = $props.customClass,
markClassName = $props.markClassName,
zIndex = $props.zIndex,
markStyle = $props.markStyle,
gapX = $props.gapX,
width = $props.width;
var getPrefixCls = this.configProvider.getPrefixCls;
var prefixCls = getPrefixCls('water-mark', customizePrefixCls);
var wrapperCls = classNames(prefixCls + '-wrapper', customClass);
var waterMarkCls = classNames(prefixCls, markClassName);
return h(
'div',
{
style: _extends({
position: 'relative'
}, customStyle),
'class': wrapperCls
},
[$slots['default'], h('div', {
'class': waterMarkCls,
style: _extends({
zIndex: zIndex,
position: 'absolute',
left: 0,
top: 0,
width: '100%',
height: '100%',
backgroundSize: gapX + width + 'px',
pointerEvents: 'none',
backgroundRepeat: 'repeat',
backgroundImage: 'url(\'' + base64Url + '\')'
}, markStyle)
})]
);
}
};