Skip to content

Commit

Permalink
feat: 更新水印组件
Browse files Browse the repository at this point in the history
  • Loading branch information
Tyh2001 committed Sep 28, 2023
1 parent 98aef1e commit 4fefaff
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 56 deletions.
4 changes: 2 additions & 2 deletions packages/fighting-design/_hooks/use-watermark/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ export const useWatermark = (prop: WatermarkProps): UseWatermarkReturn => {

const { width } = ctx.measureText(prop.content)

const cavasSize = Math.max(100, width) * prop.gap * devicePixeRatio
const cavasSize = Math.max(100, width) * devicePixeRatio + prop.gap

canvas.width = cavasSize
canvas.height = cavasSize

ctx.translate(canvas.width / 2, canvas.height / 2)
ctx.rotate((Math.PI / 190) * -45)
ctx.fillStyle = '#111'
ctx.fillStyle = prop.fontColor
ctx.font = font
ctx.textAlign = 'center'
ctx.textBaseline = 'middle'
Expand Down
18 changes: 7 additions & 11 deletions packages/fighting-design/watermark/src/props.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,28 @@
import {
setBooleanProp,
setStringProp,
setNumberProp
setNumberProp,
setStringNumberProp
} from '../../_utils'
import type { ExtractPropTypes } from 'vue'

export const Props = {
/** 水印内容 */
content: setStringProp(),
/** 水印的宽度 */
width: setNumberProp(280),
/** 水印的高度 */
height: setNumberProp(200),
gap: setNumberProp(20),
/** 文字大小 */
fontSize: setNumberProp(24),
fontSize: setNumberProp(40),
/** 间距 */
gap: setNumberProp(40),
/** 文字颜色 */
fontColor: setStringProp<string>('#333'),
/** 自定义图片水印 */
image: setStringProp(),
fontColor: setStringProp<string>('#111'),
/** 是否为块级元素 */
block: setBooleanProp(),
/**
* 原生 z-index 属性
*
* @see z-index https://developer.mozilla.org/zh-CN/docs/Web/CSS/z-index
*/
zIndex: setNumberProp(100)
zIndex: setStringNumberProp(9999)
} as const

/** watermark 组件 props 类型 */
Expand Down
109 changes: 86 additions & 23 deletions packages/fighting-design/watermark/src/watermark.vue
Original file line number Diff line number Diff line change
@@ -1,44 +1,107 @@
<script lang="ts" setup>
import { Props } from './props'
import { ref, onMounted, computed } from 'vue'
import { useCanvas } from '../../_hooks'
import type { CSSProperties, Ref } from 'vue'
import { ref, onMounted, onUnmounted } from 'vue'
import { useWatermark } from '../../_hooks'
defineOptions({ name: 'FWatermark' })
const prop = defineProps(Props)
/** 水印样式列表 */
const style: Ref<CSSProperties> = ref({})
const bg = useWatermark(prop)
/** 水印外层容器节点 */
const watermarkRef = ref<HTMLDivElement | undefined>()
/** 水印元素 */
let div: HTMLDivElement | undefined
/** 文字水印 */
const baseWatermark = computed((): CSSProperties => {
const image = useCanvas(prop).create()
/** 渲染水印 */
const renderWatermark = (): void => {
if (!watermarkRef.value) {
return
}
return { backgroundImage: `url(${image})` }
})
if (div) {
div.remove()
}
const { base64, size } = bg.value
div = document.createElement('div')
div.style.position = 'absolute'
div.style.backgroundImage = `url(${base64})`
div.style.backgroundSize = `${size}px ${size}px`
div.style.zIndex = prop.zIndex.toString()
div.style.inset = '0'
/** 图片水印 */
const imageWatermark = computed((): CSSProperties => {
const { image, width, height } = prop
watermarkRef.value.appendChild(div)
}
return {
backgroundImage: `url(${image})`,
backgroundSize: `${width}px ${height}px`
/**
* 元素挂载之后生成水印元素
*/
onMounted(renderWatermark)
/**
* @see MutationObserver https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver
*/
const ob = new MutationObserver((entries: MutationRecord[]): void => {
for (const entrie of entries) {
if (entrie.removedNodes && entrie.removedNodes.length) {
/** 被删除的元素结合 */
const removedNodesArray: Node[] = Array.from(entrie.removedNodes)
// 删除了水印元素
for (const dom of removedNodesArray) {
if (dom === div) {
renderWatermark()
return
}
}
}
// 修改了水印元素
if (entrie.target === div) {
renderWatermark()
return
}
}
})
/** 初始化的时候设置水印样式 */
onMounted((): void => {
style.value = prop.image ? imageWatermark.value : baseWatermark.value
/**
* 开始监视水印的变化
*/
onMounted(() => {
if (watermarkRef.value) {
/**
* @see MutationObserver.observe() https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver/observe
*/
ob.observe(watermarkRef.value, {
/**
* 监控子节点
*/
childList: true,
/**
* 监控子树
*/
subtree: true,
/**
* 监控属性
*/
attributes: true
})
}
})
/**
* 如何卸载之后停止监听
*
* @see
*/
onUnmounted(ob.disconnect)
</script>

<template>
<div
:class="['f-watermark', { 'f-watermark__block': block }]"
:style="[style, { zIndex }]"
>
<div ref="watermarkRef" class="f-watermark">
<slot />
</div>
</template>
6 changes: 1 addition & 5 deletions packages/fighting-theme/src/watermark.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
.f-watermark {
display: inline-block;

&.f-watermark__block {
display: block;
}
position: relative;
}
17 changes: 2 additions & 15 deletions start/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,3 @@
<template>
<f-watermark content="机密文件" :height="100" :width="130">
</f-watermark>
</template>
<script lang="ts" setup></script>

<style scoped>
.f-watermark {
display: flex;
justify-content: center;
align-items: center;
height: 500px;
}
.f-card {
width: 240px;
}
</style>
<template></template>

0 comments on commit 4fefaff

Please sign in to comment.