Skip to content

Commit

Permalink
feat: add custom-shape
Browse files Browse the repository at this point in the history
  • Loading branch information
Simon-He95 committed Sep 6, 2023
1 parent a6fa808 commit e1dfd00
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 59 deletions.
60 changes: 21 additions & 39 deletions playground/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,55 +10,35 @@ const textInput = ref('')
function onload() {
const stop = useRaf(() => {
date.value = formateDate(randomDate())
color.value = randomRgba()
color.value = randomRgba(1)
stop()
})
}, 1000)
}
const onShape1 = (ctx, x, y) => {
ctx.font = '10px serif'
ctx.fillText('🐼', x, y)
}
const onShape2 = (ctx, x, y) => {
ctx.font = '10px serif'
ctx.fillText('💩', x, y)
}
</script>

<template>
<main font-sans p="x-4 y-10" text="center gray-700 dark:gray-200">
<dot-text
ref="dotTextel"
:text="text"
:color="color"
font-size="40"
font-weight="10"
ma
/>
<dot-text text="Hi,Simon" color="grey" font-size="20" font-weight="5" ma m-y-20 />
<dot-text
:text="date"
color="grey"
:onload="onload"
font-size="20"
font-weight="20"
ma
m-y-20
/>
<dot-text text="China No.1" color="grey" font-size="20" font-weight="5" ma m-y-10 />
<main font-sans p="x-4 y-10" text="center gray-700 dark:gray-200" w-full>
<dot-text ref="dotTextel" :text="text" :color="color" font-size="40" font-weight="10" ma />
<dot-text text="China No.1" color="grey" font-size="20" font-weight="44" ma m-y-10 />
<dot-text :text="date" color="grey" :onload="onload" font-size="20" font-weight="20" ma m-y-10 />
<dot-text text="熊猫哥" color="grey" font-size="100" :custom-shape="onShape1" font-weight="10" ma m-y-5 />
<dot-text text="熊猫哥" color="grey" font-size="500" :custom-shape="onShape2" font-weight="10" ma m-y-5 />
<div w-55 overflow-hidden ma>
<dot-text
text="壹 贰 叁 肆 伍 陆 柒 捌 玖 拾 百 千 万 円"
color="grey"
font-size="30"
font-weight="10"
ma
m-y-5
text="壹 贰 叁 肆 伍 陆 柒 捌 玖 拾 百 千 万 円" color="grey" font-size="30" font-weight="10" ma m-y-5
class="dot-text-wrap"
/>
</div>
<input
v-model="textInput"
type="text"
placeholder="尝试输入吧"
border-1
border-dark
border-rd-1
indent-2
color-black
>
<dot-text :text="textInput" color="grey" font-size="40" font-weight="10" ma m-y-5 />
<input v-model="textInput" type="text" placeholder="尝试输入吧" border-1 border-dark border-rd-1 indent-2 color-black>
<dot-text :text="textInput" color="grey" font-size="100" font-weight="10" ma m-y-5 />
<Footer />
</main>
</template>
Expand All @@ -67,10 +47,12 @@ function onload() {
.dot-text-wrap {
animation: dot-text-wrap-animation 5s linear infinite;
}
@keyframes dot-text-wrap-animation {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-90%);
}
Expand Down
30 changes: 24 additions & 6 deletions src/DotText.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { DefineComponent } from 'vue'
import type { DefineComponent, PropType } from 'vue'
import { defineComponent, h, onMounted, ref, watch } from 'vue'
import { useRaf } from 'lazy-js-utils'
import { DotTextCanvas } from './DotTextCanvas'
import type { DotType } from './types'
import type { DotType, Options } from './types'

export const DotText = defineComponent({
props: {
Expand Down Expand Up @@ -31,20 +31,36 @@ export const DotText = defineComponent({
type: Function,
default: () => { },
},
customShape: {
type: Function as PropType<Options['customShape']>,
},
},
setup(props) {
const dotText = new DotTextCanvas(props.text, +props.fontSize, props.color, +props.fontWeight)
const dotText = new DotTextCanvas({
text: props.text,
fontSize: +props.fontSize,
color: props.color,
fontWeight: +props.fontWeight,
customShape: props.customShape,
})
const dotTextEl = ref<HTMLElement>()
onMounted(() => {
update(dotTextEl.value!, dotText.canvas!)
const stop = useRaf(() => {
if (dotText.status === 'success')
if (dotText.status === 'success') {
props.onload?.()
stop()
stop()
}
})
})
watch(props, async () => {
const newDotText = await dotText.repaint(props.text, +props.fontSize, props.color, +props.fontWeight)
const newDotText = await dotText.repaint({
text: props.text,
fontSize: +props.fontSize,
color: props.color,
fontWeight: +props.fontWeight,
customShape: props.customShape,
})
const stop = useRaf(() => {
if (newDotText.status === 'success') {
update(dotTextEl.value!, newDotText.canvas!)
Expand All @@ -60,6 +76,8 @@ export const DotText = defineComponent({
}) as DefineComponent<DotType>

function update(dotTextEl: HTMLElement, canvas: HTMLCanvasElement) {
if (!dotTextEl)
return
const attributes = dotTextEl.attributes
Object.values(attributes).forEach((key) => {
if (key.name === 'width' || key.name === 'height')
Expand Down
36 changes: 24 additions & 12 deletions src/DotTextCanvas.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { memorizeFn, useRic } from 'lazy-js-utils'
import type { Options } from './types'

export class DotTextCanvas {
canvas: HTMLCanvasElement = document.createElement('canvas')
Expand All @@ -10,11 +11,14 @@ export class DotTextCanvas {
fontWeight: number
textPointSet: Array<number[]> = []
status = 'pending'
constructor(text: string, fontSize: number, color: string, fontWeight: number) {
customShape?: (ctx: CanvasRenderingContext2D, posX: number, posY: number) => void
constructor(options: Options) {
const { text, fontSize, color, fontWeight, customShape } = options
this.originText = text
this.fontSize = fontSize
this.color = color
this.fontWeight = fontWeight
this.customShape = customShape
this.executor()
}

Expand Down Expand Up @@ -74,33 +78,41 @@ export class DotTextCanvas {
const size = oneTempLength * this.fontWeight / h
this.canvas.height = this.fontSize
this.canvas.width = this.fontSize * this.originText.length

for (let i = 0; i < h; i++) {
tasks.push(() => {
for (let j = 0; j < w; j++) {
if (this.textPointSet[i][j]) {
this.ctx.beginPath()
this.ctx.arc(getPoint(j), getPoint(i), size, 0, Math.PI * 2)
this.ctx.fillStyle = this.color
this.ctx.fill()
if (this.customShape) {
this.customShape(this.ctx, getPoint(j), getPoint(i))
}
else {
this.ctx.arc(getPoint(j), getPoint(i), size, 0, Math.PI * 2)
this.ctx.fillStyle = this.color
this.ctx.fill()
}
}
}
})
}
useRic(tasks, {
callback: () => this.status = 'success',
callback: () => {
this.status = 'success'
},
})
}

repaint(this: any, text: string, fontSize: number, color: string, fontWeight: number): DotTextCanvas {
repaint(options: Options): DotTextCanvas {
this.status = 'pending'

// 如果text相同
if (this.originText !== text)
return new DotTextCanvas(text, fontSize, color, fontWeight)
if (this.originText !== options.text)
return new DotTextCanvas(options)

this.fontSize = fontSize
this.color = color
this.fontWeight = fontWeight
this.fontSize = options.fontSize
this.color = options.color
this.fontWeight = options.fontWeight
this.customShape = options.customShape
this.clearCanvas()
this.getCanvas()
return this
Expand Down
14 changes: 12 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
export interface DotType {
text: string
color?: string
fontWeight?: number
fontSize?: number
clear?: Function
onload?: Function
customShape?: (ctx: CanvasRenderingContext2D, posX: number, posY: number) => void
}

export interface Options {
text: string
fontSize: number
color: string
fontWeight: number
fontSize: number
clear: Function
customShape?: (ctx: CanvasRenderingContext2D, posX: number, posY: number) => void
}

0 comments on commit e1dfd00

Please sign in to comment.