今日主題 primevue番外篇-控制浮水印。
PrimeVue並沒有 浮水印套件,
浮水印利用別的套件呈現,利用primvue元件來控制字體大小和內容等。
這次,難度有點小提升...
Be cheerful and hopeful.
樂觀向上,充滿希望。
let ctx = canvas.getContext("2d")!;
ctx.fillStyle = props.waterColor;
ctx.font = "normal 18px Microsoft Yahei";
export default defineComponent({
props: {
inputText: {
type: String,
default: "",
},
waterWidth: {
type: Number,
default: "",
},
waterColor: {
type: String,
default: "",
},
waterRotate: {
type: Number,
default: "",
},
},
setup(props) {
const maskDiv = ref({} as HTMLDivElement);
const canvasWidth = ref(Number(props.waterWidth));
const canvasRef = ref(document.createElement("canvas"));
const inputText = ref(props.inputText);
移除水印容器,清理 DOM。
const removeMaskDiv = () => {
if (document.body.contains(maskDiv.value)) {
document.body.removeChild(maskDiv.value);
}
};
使用 MutationObserver 監視 DOM 變化,以便在水印容器被刪除或屬性改變時重新初始化水印。
const callback = (mutations: MutationRecord[]) => {
if (mutations[0].target.id === "_waterMark") {
removeMaskDiv();
}
if (mutations[0].attributeName === "id") {
removeMaskDiv();
init();
}
if (
mutations[0].removedNodes[0] &&
mutations[0].removedNodes[0].id === "_waterMark"
) {
init();
}
};
const Monitor = () => {
let body = document.getElementsByTagName("body")[0];
let options = {
childList: true,
attributes: true,
characterData: true,
subtree: true,
attributeOldValue: true,
characterDataOldValue: true,
};
let observer = new MutationObserver(callback);
observer.observe(body, options);
};
當 inputText、waterColor 或 waterRotate 改變時,重新初始化水印。
watch(
() => props.inputText,
() => {
removeMaskDiv();
inputText.value = props.inputText;
}
);
watch(
() => props.waterColor,
() => {
removeMaskDiv();
}
);
watch(
() => props.waterRotate,
() => {
removeMaskDiv();
}
);
onMounted(() => {
init();
Monitor();
});
onBeforeUnmount(() => {
removeMaskDiv();
});
提供一個界面讓用戶輸入水印文字、寬度、顏色和旋轉角度。
這些值會傳遞給 WatermarkComponent,以顯示相應的水印。
<script setup>
import { ref } from "vue";
import WatermarkComponent from "./component.vue";
const text = ref("同學姓名<br>yyyy/mm/dd hh:mm");
text.value = text.value.replace(/<br>/g, "\n");
const width = ref(300);
const color = ref("#4a4a4a");
const rotate = ref(30);
</script>
<template>
<div>
<textarea v-model="text"></textarea>
<input type="number" v-model="width" />
<input type="text" v-model="color" />
<input type="number" v-model="rotate" />
</div>
<WatermarkComponent
:inputText="text"
:waterWidth="width"
:waterColor="color"
:waterRotate="rotate"
/>
</template>
<style lang="scss" scoped></style>
參考資料:
https://github.com/StephenOo/vue-canvas-waterMark/blob/master/waterMark.vue