UNPKG

vxe-pc-ui

Version:
168 lines (139 loc) 4.76 kB
import { defineComponent, ref, h, reactive, computed, onMounted, watch, PropType, onUnmounted } from 'vue' import XEUtils from 'xe-utils' import { getConfig, createEvent, globalEvents } from '../../ui' import { toCssUnit } from '../../ui/src/dom' import { getContentUrl } from './util' import type { WatermarkReactData, VxeWatermarkEmits, WatermarkMethods, VxeWatermarkPropTypes, WatermarkPrivateMethods, ValueOf, VxeComponentStyleType, WatermarkPrivateRef, VxeWatermarkPrivateComputed, VxeWatermarkConstructor, VxeWatermarkPrivateMethods } from '../../../types' export default defineComponent({ name: 'VxeWatermark', props: { width: String as PropType<VxeWatermarkPropTypes.Width>, height: String as PropType<VxeWatermarkPropTypes.Height>, imageUrl: String as PropType<VxeWatermarkPropTypes.ImageUrl>, rotate: { type: [Number, String] as PropType<VxeWatermarkPropTypes.Rotate>, default: () => getConfig().watermark.rotate }, gap: { type: [Array, Number, String] as PropType<VxeWatermarkPropTypes.Gap>, default: () => XEUtils.clone(getConfig().watermark.gap, true) }, content: [String, Array] as PropType<VxeWatermarkPropTypes.Content>, font: Object as PropType<VxeWatermarkPropTypes.Font>, offset: Object as PropType<VxeWatermarkPropTypes.Offset>, zIndex: [String, Number] as PropType<VxeWatermarkPropTypes.ZIndex> }, emits: [ ] as VxeWatermarkEmits, setup (props, context) { const { emit } = context const xID = XEUtils.uniqueId() const refElem = ref<HTMLDivElement>() const reactData = reactive<WatermarkReactData>({ markUrl: '' }) const refMaps: WatermarkPrivateRef = { refElem } const computeFontOpts = computed(() => { return XEUtils.assign({}, XEUtils.clone(getConfig().watermark.font, true), props.font) }) const computeWrapperStyle = computed(() => { const { width, height, zIndex } = props const { markUrl } = reactData const stys: VxeComponentStyleType = {} if (width) { stys.width = toCssUnit(width) } if (height) { stys.height = toCssUnit(height) } if (markUrl) { stys.backgroundImage = `url(${markUrl})` } if (zIndex) { stys.zIndex = zIndex } return stys }) const computeMaps: VxeWatermarkPrivateComputed = { } const $xeWatermark = { xID, props, context, reactData, getRefMaps: () => refMaps, getComputeMaps: () => computeMaps } as unknown as VxeWatermarkConstructor & VxeWatermarkPrivateMethods const dispatchEvent = (type: ValueOf<VxeWatermarkEmits>, params: Record<string, any>, evnt: Event | null) => { emit(type, createEvent(evnt, { $watermark: $xeWatermark }, params)) } const collapsePaneMethods: WatermarkMethods = { dispatchEvent } const updateMarkStyle = () => { const { content, gap, rotate, offset } = props const el = refElem.value const fontOpts = computeFontOpts.value if (el) { if (content) { getContentUrl(content, getComputedStyle(el).fontSize, { font: fontOpts, rotate, gap, offset }).then(url => { reactData.markUrl = url }) } } } const collapsePanePrivateMethods: WatermarkPrivateMethods = { } Object.assign($xeWatermark, collapsePaneMethods, collapsePanePrivateMethods) const renderVN = () => { const wrapperStyle = computeWrapperStyle.value return h('div', { ref: refElem, class: 'vxe-watermark', style: wrapperStyle }) } watch(() => props.imageUrl, () => { updateMarkStyle() }) watch(() => props.content, () => { updateMarkStyle() }) watch(() => props.gap, () => { updateMarkStyle() }) watch(() => props.rotate, () => { updateMarkStyle() }) watch(() => props.width, () => { updateMarkStyle() }) watch(() => props.height, () => { updateMarkStyle() }) watch(() => props.font, () => { updateMarkStyle() }) onMounted(() => { updateMarkStyle() globalEvents.on($xeWatermark, 'resize', XEUtils.throttle(() => { updateMarkStyle() }, 300, { trailing: true, leading: true })) }) onUnmounted(() => { globalEvents.off($xeWatermark, 'resize') }) $xeWatermark.renderVN = renderVN return $xeWatermark }, render () { return this.renderVN() } })