Skip to content

Commit

Permalink
fix(comp:watermark): flickering problem (#1206)
Browse files Browse the repository at this point in the history
  • Loading branch information
tuchg authored and danranVm committed Oct 21, 2022
1 parent e46d5cb commit 49863e9
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 52 deletions.
10 changes: 8 additions & 2 deletions packages/components/watermark/demo/Custom.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,24 @@
<IxWatermark
:rotate="30"
:opacity="0.2"
content="你好 iDux🚀"
:content="text"
font="small-caps bold 24px HGKY_CNKI"
fontColor="#1c6eff"
:fontSize="24"
:offsetLeft="10"
:renderFn="canvasDebugger"
>
<div style="height: 500px"></div>
<div style="height: 500px">
<IxInput v-model:value="text"></IxInput>
</div>
</IxWatermark>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const text = ref('你好 iDux🚀')
const canvasDebugger = (ctx: CanvasRenderingContext2D) => {
console.log(ctx.lineWidth)
}
Expand Down
13 changes: 9 additions & 4 deletions packages/components/watermark/src/Watermark.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,16 @@ export default defineComponent({
const canvasRef = ref<HTMLCanvasElement>()
const base64Ref = useCalcBase64(props, densityData)

let antiTamper: ReturnType<typeof useAntiTamper> | undefined = undefined

watch(
[() => props.strict, () => base64Ref.value],
([strict, base64]) => {
if (strict && base64 !== '') {
useAntiTamper(wrapperRef, canvasRef)
[wrapperRef, canvasRef, () => props.strict, base64Ref],
([wrapperEl, canvasEl, strict, base64]) => {
if (strict && wrapperEl && canvasEl && base64 !== '') {
if (antiTamper) {
antiTamper.stop()
}
antiTamper = useAntiTamper(wrapperEl, canvasEl)
}
},
{
Expand Down
77 changes: 31 additions & 46 deletions packages/components/watermark/src/composables/useAntiTamper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,61 +5,46 @@
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE
*/

import { watch } from 'vue'
import { NoopFunction } from '@idux/cdk/utils'

import { MaybeElementRef, convertElement } from '@idux/cdk/utils'

export function useAntiTamper(wrapperRef: MaybeElementRef, elRef: MaybeElementRef): void {
export function useAntiTamper(wrapper: HTMLElement, el: HTMLElement): { stop: typeof NoopFunction } {
const options: MutationObserverInit = {
childList: true,
subtree: true,
attributeFilter: ['style', 'class'],
attributeOldValue: true,
}

let observer: MutationObserver | null = null
let el: HTMLElement | null | undefined = null

watch(
() => convertElement(wrapperRef)!,
wrapper => {
if (!el) {
el = convertElement(elRef)
}
const observer = new MutationObserver((records: MutationRecord[]) => {
records
.filter(record => record.target === el || record.target === wrapper)
.forEach(record => {
// avoid modifying data
if (record.type === 'attributes') {
reset(() => {
el!.setAttribute(record.attributeName!, record.oldValue!)
})
}
// avoid deleted
if (record.type === 'childList') {
reset(() => {
wrapper!.appendChild(record.removedNodes[0])
})
}
})
})

if (wrapper && !observer) {
observer = new MutationObserver((records: MutationRecord[]) => {
records
.filter(record => record.target === el || record.target === wrapper)
.forEach(record => {
// avoid modifying data
if (record.type === 'attributes') {
reset(() => {
el!.setAttribute(record.attributeName!, record.oldValue!)
})
}
// avoid deleted
if (record.type === 'childList') {
reset(() => {
wrapper!.appendChild(record.removedNodes[0])
})
}
})
})
observer.observe(wrapper, options)

observer.observe(wrapper, options)
const reset = (resume = NoopFunction) => {
requestAnimationFrame(() => {
observer.disconnect()
resume()
observer.observe(wrapper, options)
})
}

const reset = (resume = () => {}) => {
setTimeout(() => {
observer?.disconnect()
resume()
observer?.observe(wrapper, options)
}, 0)
}
}
},
{
immediate: true,
},
)
return {
stop: () => observer.disconnect(),
}
}

0 comments on commit 49863e9

Please sign in to comment.