forked from didirus/AstralRinth
refactor: migrate to common eslint+prettier configs (#4168)
* refactor: migrate to common eslint+prettier configs * fix: prettier frontend * feat: config changes * fix: lint issues * fix: lint * fix: type imports * fix: cyclical import issue * fix: lockfile * fix: missing dep * fix: switch to tabs * fix: continue switch to tabs * fix: rustfmt parity * fix: moderation lint issue * fix: lint issues * fix: ui intl * fix: lint issues * Revert "fix: rustfmt parity" This reverts commit cb99d2376c321d813d4b7fc7e2a213bb30a54711. * feat: revert last rs
This commit is contained in:
@@ -1,41 +1,41 @@
|
||||
import { computed, onMounted, onUnmounted, type Ref } from 'vue'
|
||||
import { useElementSize } from '@vueuse/core'
|
||||
import { computed, onMounted, onUnmounted, type Ref } from 'vue'
|
||||
|
||||
export interface DynamicFontSizeOptions {
|
||||
containerElement: Ref<HTMLElement | null>
|
||||
text: Ref<string | undefined>
|
||||
baseFontSize?: number
|
||||
minFontSize?: number
|
||||
maxFontSize?: number
|
||||
availableWidthRatio?: number
|
||||
maxContainerWidth?: number
|
||||
padding?: number
|
||||
fontFamily?: string
|
||||
fontWeight?: string | number
|
||||
containerElement: Ref<HTMLElement | null>
|
||||
text: Ref<string | undefined>
|
||||
baseFontSize?: number
|
||||
minFontSize?: number
|
||||
maxFontSize?: number
|
||||
availableWidthRatio?: number
|
||||
maxContainerWidth?: number
|
||||
padding?: number
|
||||
fontFamily?: string
|
||||
fontWeight?: string | number
|
||||
}
|
||||
|
||||
export function useDynamicFontSize(options: DynamicFontSizeOptions) {
|
||||
const {
|
||||
containerElement,
|
||||
text,
|
||||
baseFontSize = 1.25,
|
||||
minFontSize = 0.75,
|
||||
maxFontSize = 2,
|
||||
availableWidthRatio = 0.9,
|
||||
maxContainerWidth = 400,
|
||||
padding = 24,
|
||||
fontFamily = 'inherit',
|
||||
fontWeight = 'inherit',
|
||||
} = options
|
||||
const {
|
||||
containerElement,
|
||||
text,
|
||||
baseFontSize = 1.25,
|
||||
minFontSize = 0.75,
|
||||
maxFontSize = 2,
|
||||
availableWidthRatio = 0.9,
|
||||
maxContainerWidth = 400,
|
||||
padding = 24,
|
||||
fontFamily = 'inherit',
|
||||
fontWeight = 'inherit',
|
||||
} = options
|
||||
|
||||
const { width: containerWidth } = useElementSize(containerElement)
|
||||
let measurementElement: HTMLElement | null = null
|
||||
const { width: containerWidth } = useElementSize(containerElement)
|
||||
let measurementElement: HTMLElement | null = null
|
||||
|
||||
const createMeasurementElement = () => {
|
||||
if (measurementElement) return measurementElement
|
||||
const createMeasurementElement = () => {
|
||||
if (measurementElement) return measurementElement
|
||||
|
||||
measurementElement = document.createElement('div')
|
||||
measurementElement.style.cssText = `
|
||||
measurementElement = document.createElement('div')
|
||||
measurementElement.style.cssText = `
|
||||
position: absolute;
|
||||
top: -9999px;
|
||||
left: -9999px;
|
||||
@@ -45,73 +45,73 @@ export function useDynamicFontSize(options: DynamicFontSizeOptions) {
|
||||
font-family: ${fontFamily};
|
||||
font-weight: ${fontWeight};
|
||||
`
|
||||
measurementElement.setAttribute('aria-hidden', 'true')
|
||||
document.body.appendChild(measurementElement)
|
||||
measurementElement.setAttribute('aria-hidden', 'true')
|
||||
document.body.appendChild(measurementElement)
|
||||
|
||||
return measurementElement
|
||||
}
|
||||
return measurementElement
|
||||
}
|
||||
|
||||
const cleanupMeasurementElement = () => {
|
||||
if (measurementElement?.parentNode) {
|
||||
measurementElement.parentNode.removeChild(measurementElement)
|
||||
measurementElement = null
|
||||
}
|
||||
}
|
||||
const cleanupMeasurementElement = () => {
|
||||
if (measurementElement?.parentNode) {
|
||||
measurementElement.parentNode.removeChild(measurementElement)
|
||||
measurementElement = null
|
||||
}
|
||||
}
|
||||
|
||||
const measureTextWidth = (textContent: string, fontSize: number): number => {
|
||||
if (!textContent) return 0
|
||||
const measureTextWidth = (textContent: string, fontSize: number): number => {
|
||||
if (!textContent) return 0
|
||||
|
||||
const element = createMeasurementElement()
|
||||
element.style.fontSize = `${fontSize}rem`
|
||||
element.textContent = textContent
|
||||
const element = createMeasurementElement()
|
||||
element.style.fontSize = `${fontSize}rem`
|
||||
element.textContent = textContent
|
||||
|
||||
return element.getBoundingClientRect().width
|
||||
}
|
||||
return element.getBoundingClientRect().width
|
||||
}
|
||||
|
||||
const findOptimalFontSize = (textContent: string, availableWidth: number): number => {
|
||||
let low = minFontSize
|
||||
let high = maxFontSize
|
||||
let bestSize = minFontSize
|
||||
const findOptimalFontSize = (textContent: string, availableWidth: number): number => {
|
||||
let low = minFontSize
|
||||
let high = maxFontSize
|
||||
let bestSize = minFontSize
|
||||
|
||||
const maxWidth = measureTextWidth(textContent, maxFontSize)
|
||||
if (maxWidth <= availableWidth) return maxFontSize
|
||||
const maxWidth = measureTextWidth(textContent, maxFontSize)
|
||||
if (maxWidth <= availableWidth) return maxFontSize
|
||||
|
||||
for (let i = 0; i < 8; i++) {
|
||||
const mid = (low + high) / 2
|
||||
const width = measureTextWidth(textContent, mid)
|
||||
for (let i = 0; i < 8; i++) {
|
||||
const mid = (low + high) / 2
|
||||
const width = measureTextWidth(textContent, mid)
|
||||
|
||||
if (width <= availableWidth) {
|
||||
bestSize = mid
|
||||
low = mid
|
||||
} else {
|
||||
high = mid
|
||||
}
|
||||
if (width <= availableWidth) {
|
||||
bestSize = mid
|
||||
low = mid
|
||||
} else {
|
||||
high = mid
|
||||
}
|
||||
|
||||
if (high - low < 0.01) break
|
||||
}
|
||||
if (high - low < 0.01) break
|
||||
}
|
||||
|
||||
return Math.max(bestSize, minFontSize)
|
||||
}
|
||||
return Math.max(bestSize, minFontSize)
|
||||
}
|
||||
|
||||
const fontSize = computed(() => {
|
||||
if (!text.value || !containerWidth.value) return `${baseFontSize}rem`
|
||||
const fontSize = computed(() => {
|
||||
if (!text.value || !containerWidth.value) return `${baseFontSize}rem`
|
||||
|
||||
const availableWidth =
|
||||
Math.min(containerWidth.value * availableWidthRatio, maxContainerWidth) - padding
|
||||
const availableWidth =
|
||||
Math.min(containerWidth.value * availableWidthRatio, maxContainerWidth) - padding
|
||||
|
||||
const baseWidth = measureTextWidth(text.value, baseFontSize)
|
||||
if (baseWidth <= availableWidth) return `${baseFontSize}rem`
|
||||
const baseWidth = measureTextWidth(text.value, baseFontSize)
|
||||
if (baseWidth <= availableWidth) return `${baseFontSize}rem`
|
||||
|
||||
const optimalSize = findOptimalFontSize(text.value, availableWidth)
|
||||
return `${optimalSize}rem`
|
||||
})
|
||||
const optimalSize = findOptimalFontSize(text.value, availableWidth)
|
||||
return `${optimalSize}rem`
|
||||
})
|
||||
|
||||
onMounted(createMeasurementElement)
|
||||
onUnmounted(cleanupMeasurementElement)
|
||||
onMounted(createMeasurementElement)
|
||||
onUnmounted(cleanupMeasurementElement)
|
||||
|
||||
return {
|
||||
fontSize,
|
||||
containerWidth,
|
||||
cleanup: cleanupMeasurementElement,
|
||||
}
|
||||
return {
|
||||
fontSize,
|
||||
containerWidth,
|
||||
cleanup: cleanupMeasurementElement,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user