Skip to content

Commit

Permalink
Merge pull request #110 from rashagu/develop
Browse files Browse the repository at this point in the history
fix: [Vue warn]: Slot "default" invoked outside the render function
  • Loading branch information
wingkwong authored Apr 8, 2024
2 parents 07f74b0 + 9a7fe6e commit 22a5c8f
Showing 1 changed file with 72 additions and 72 deletions.
144 changes: 72 additions & 72 deletions src/components/Watermark.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { PropType } from 'vue'
import { defineComponent, h, onMounted, reactive, ref, toRefs, watch } from 'vue'
import { defineComponent, h, reactive, ref, toRefs, watch } from 'vue'
import { defaultOptions } from '../options'
import { BaseSize, FontGap } from '../constants'
import type { WatermarkDrawingParams, WatermarkOptions } from '../types'
Expand All @@ -13,13 +13,6 @@ export const Watermark = defineComponent({
},
},
setup(props, ctx) {
// Get the default slot content
const slots = ctx.slots.default?.()
// Throw an error if no slot content is provided
if (!slots) throw new Error('@watermarkify: Slot is required to use <Watermark>')
// Throw an error if more than one slot content is provided
if (slots.length !== 1) throw new Error(`@watermarkify: <Watermark> requires exactly one slot, but got ${slots.length}`)

// Merge props.options with defaultOptions
const options = reactive({
...defaultOptions,
Expand Down Expand Up @@ -60,7 +53,7 @@ export const Watermark = defineComponent({
canvasCtx.font = `${Number(fontSize)}px ${fontFamily}`
const contents = Array.isArray(content.value) ? content.value : [content.value]
// Measure the width of each content item
const widths = contents.map((item) => canvasCtx.measureText(item!).width)
const widths = contents.map(item => canvasCtx.measureText(item!).width)
// Calculate the default width and height based on the measured content
defaultWidth = Math.ceil(Math.max(...widths))
defaultHeight = Number(fontSize) * contents.length + (contents.length - 1) * FontGap
Expand Down Expand Up @@ -188,62 +181,6 @@ export const Watermark = defineComponent({
addWatermark(canvas.toDataURL(), watermarkWidth)
}

const renderWatermark = () => {
const slot = slots[0]
// Create a new canvas element and get its context
const canvas = document.createElement('canvas')
const canvasCtx = canvas.getContext('2d')
if (canvasCtx) {
// Create a new div element for the watermark if it doesn't exist yet
if (!watermarkRef.value) watermarkRef.value = document.createElement('div')
// Get the watermark size and canvas dimensions
const [watermarkWidth, watermarkHeight] = getWatermarkSize(canvasCtx)
const canvasWidth = (gapX.value + watermarkWidth) * devicePixelRatio
const canvasHeight = (gapY.value + watermarkHeight) * devicePixelRatio
const drawWidth = watermarkWidth * devicePixelRatio
const drawHeight = watermarkHeight * devicePixelRatio
// Set the canvas dimensions
canvas.setAttribute('width', `${appendPixel(canvasWidth * BaseSize)}`)
canvas.setAttribute('height', `${appendPixel(canvasHeight * BaseSize)}`)
// Set the drawing parameters
const drawingParams = {
drawX: (gapX.value * devicePixelRatio) / 2,
drawY: (gapY.value * devicePixelRatio) / 2,
rotateX: (drawWidth + gapX.value * devicePixelRatio) / 2,
rotateY: (drawHeight + gapY.value * devicePixelRatio) / 2,
}
// Set the alternate drawing parameters
const alternateDrawingParams = {
drawX: drawingParams.drawX + canvasWidth,
drawY: drawingParams.drawY + canvasHeight,
rotateX: drawingParams.rotateX + canvasWidth,
rotateY: drawingParams.rotateY + canvasHeight,
}
// Save the canvas state
canvasCtx.save()
// Rotate the canvas
rotateWatermark(canvasCtx, drawingParams.rotateX, drawingParams.rotateY, rotate.value)

if (image.value) {
// TODO: handle image watermark
} else {
// Draw the text watermark
drawText(canvas, canvasCtx, drawWidth, drawHeight, watermarkWidth, drawingParams, alternateDrawingParams)
}
}
// Return a div element containing the original content and the watermark container
return h(
'div',
{
ref: watermarkContainerRef,
style: { position: 'relative' },
},
[slot],
)
}

onMounted(renderWatermark)

watch(
() => props.options,
() => {
Expand All @@ -255,17 +192,80 @@ export const Watermark = defineComponent({
...props.options?.font,
},
})
renderWatermark()
},
{ deep: true, immediate: true },
)

return {
renderWatermark,
}
},
render() {
// Render the watermark overlay
return h('div', {}, this.renderWatermark())
return () => {
// Get the default slot content
const slots = ctx.slots.default?.()
// Throw an error if no slot content is provided
if (!slots)
throw new Error('@watermarkify: Slot is required to use <Watermark>')
// Throw an error if more than one slot content is provided
if (slots.length !== 1)
throw new Error(`@watermarkify: <Watermark> requires exactly one slot, but got ${slots.length}`)

const renderWatermark = () => {
const slot = slots[0]
// Create a new canvas element and get its context
const canvas = document.createElement('canvas')
const canvasCtx = canvas.getContext('2d')
if (canvasCtx) {
// Create a new div element for the watermark if it doesn't exist yet
if (!watermarkRef.value)
watermarkRef.value = document.createElement('div')
// Get the watermark size and canvas dimensions
const [watermarkWidth, watermarkHeight] = getWatermarkSize(canvasCtx)
const canvasWidth = (gapX.value + watermarkWidth) * devicePixelRatio
const canvasHeight = (gapY.value + watermarkHeight) * devicePixelRatio
const drawWidth = watermarkWidth * devicePixelRatio
const drawHeight = watermarkHeight * devicePixelRatio
// Set the canvas dimensions
canvas.setAttribute('width', `${appendPixel(canvasWidth * BaseSize)}`)
canvas.setAttribute('height', `${appendPixel(canvasHeight * BaseSize)}`)
// Set the drawing parameters
const drawingParams = {
drawX: (gapX.value * devicePixelRatio) / 2,
drawY: (gapY.value * devicePixelRatio) / 2,
rotateX: (drawWidth + gapX.value * devicePixelRatio) / 2,
rotateY: (drawHeight + gapY.value * devicePixelRatio) / 2,
}
// Set the alternate drawing parameters
const alternateDrawingParams = {
drawX: drawingParams.drawX + canvasWidth,
drawY: drawingParams.drawY + canvasHeight,
rotateX: drawingParams.rotateX + canvasWidth,
rotateY: drawingParams.rotateY + canvasHeight,
}
// Save the canvas state
canvasCtx.save()
// Rotate the canvas
rotateWatermark(canvasCtx, drawingParams.rotateX, drawingParams.rotateY, rotate.value)

if (image.value) {
// TODO: handle image watermark
}
else {
// Draw the text watermark
drawText(canvas, canvasCtx, drawWidth, drawHeight, watermarkWidth, drawingParams, alternateDrawingParams)
}
}
// Return a div element containing the original content and the watermark container
return h(
'div',
{
ref: watermarkContainerRef,
style: { position: 'relative' },
},
[slot],
)
}
renderWatermark()

return h('div', {}, renderWatermark())
}
},

})

0 comments on commit 22a5c8f

Please sign in to comment.