153 lines
5.3 KiB
JavaScript
153 lines
5.3 KiB
JavaScript
let currRenderDom = null
|
||
let currelRectification = ''
|
||
let currelRectificationLevel = ''
|
||
let resizeListener = null
|
||
let timer = null
|
||
let currScale = 1
|
||
let isAutofitRunnig = false
|
||
let isElRectification = false
|
||
|
||
function init(options = {}, isShowInitTip = true) {
|
||
if (isShowInitTip) {
|
||
console.log(
|
||
`%c` + `autofit.js` + ` is running`,
|
||
`font-weight: bold; color: #ffb712; background:linear-gradient(-45deg, #bd34fe 50%, #47caff 50% );background: -webkit-linear-gradient( 120deg, #bd34fe 30%, #41d1ff );background-clip: text;-webkit-background-clip: text; -webkit-text-fill-color:linear-gradient( -45deg, #bd34fe 50%, #47caff 50% ); padding: 8px 12px; border-radius: 4px;`
|
||
)
|
||
}
|
||
const {
|
||
dw = 3158,
|
||
dh = 1368,
|
||
el = typeof options === 'string' ? options : '#app',
|
||
resize = true,
|
||
ignore = [],
|
||
transition = 'none',
|
||
delay = 0
|
||
} = options
|
||
currRenderDom = el
|
||
let dom = document.querySelector(el)
|
||
if (!dom) {
|
||
console.error(`autofit: '${el}' is not exist`)
|
||
return
|
||
}
|
||
const style = document.createElement('style')
|
||
const ignoreStyle = document.createElement('style')
|
||
style.lang = 'text/css'
|
||
ignoreStyle.lang = 'text/css'
|
||
style.id = 'autofit-style'
|
||
ignoreStyle.id = 'ignoreStyle'
|
||
style.innerHTML = `body {overflow: hidden;}`
|
||
dom.appendChild(style)
|
||
dom.appendChild(ignoreStyle)
|
||
dom.style.height = `${dh}px`
|
||
dom.style.width = `${dw}px`
|
||
dom.style.transformOrigin = `0 0`
|
||
keepFit(dw, dh, dom, ignore)
|
||
resizeListener = () => {
|
||
clearTimeout(timer)
|
||
if (delay != 0)
|
||
timer = setTimeout(() => {
|
||
keepFit(dw, dh, dom, ignore)
|
||
isElRectification &&
|
||
elRectification(currelRectification, currelRectificationLevel)
|
||
}, delay)
|
||
else {
|
||
keepFit(dw, dh, dom, ignore)
|
||
isElRectification &&
|
||
elRectification(currelRectification, currelRectificationLevel)
|
||
}
|
||
}
|
||
resize && window.addEventListener('resize', resizeListener)
|
||
isAutofitRunnig = true
|
||
setTimeout(() => {
|
||
dom.style.transition = `${transition}s`
|
||
})
|
||
}
|
||
function off(el = '#app') {
|
||
try {
|
||
isElRectification = false
|
||
window.removeEventListener('resize', resizeListener)
|
||
document.querySelector('#autofit-style').remove()
|
||
document.querySelector(currRenderDom ? currRenderDom : el).style = ''
|
||
isElRectification && offelRectification()
|
||
} catch (error) {
|
||
console.error(`autofit: Failed to remove normally`, error)
|
||
isAutofitRunnig = false
|
||
}
|
||
isAutofitRunnig &&
|
||
console.log(
|
||
`%c` + `autofit.js` + ` is off`,
|
||
`font-weight: bold;color: #707070; background: #c9c9c9; padding: 8px 12px; border-radius: 4px;`
|
||
)
|
||
}
|
||
|
||
function elRectification(el, level = 1) {
|
||
if (!isAutofitRunnig) {
|
||
console.error('autofit.js:autofit has not been initialized yet')
|
||
}
|
||
!el && console.error(`autofit.js:bad selector: ${el}`)
|
||
currelRectification = el
|
||
currelRectificationLevel = level
|
||
const currEl = document.querySelectorAll(el)
|
||
if (currEl.length == 0) {
|
||
console.error('autofit.js:elRectification found no element')
|
||
return
|
||
}
|
||
for (let item of currEl) {
|
||
if (!isElRectification) {
|
||
item.originalWidth = item.clientWidth
|
||
item.originalHeight = item.clientHeight
|
||
}
|
||
let rectification = currScale == 1 ? 1 : currScale * level
|
||
item.style.width = `${item.originalWidth * rectification}px`
|
||
item.style.height = `${item.originalHeight * rectification}px`
|
||
item.style.transform = `scale(${1 / currScale})`
|
||
item.style.transformOrigin = `0 0`
|
||
}
|
||
isElRectification = true
|
||
}
|
||
function offelRectification() {
|
||
if (!currelRectification) return
|
||
for (let item of document.querySelectorAll(currelRectification)) {
|
||
item.style.width = ``
|
||
item.style.height = ``
|
||
item.style.transform = ``
|
||
}
|
||
}
|
||
function keepFit(dw, dh, dom, ignore) {
|
||
let clientHeight = document.documentElement.clientHeight
|
||
let clientWidth = document.documentElement.clientWidth
|
||
currScale =
|
||
clientWidth / clientHeight < dw / dh ? clientWidth / dw : clientHeight / dh
|
||
dom.style.height = `${clientHeight / currScale}px`
|
||
dom.style.width = `${clientWidth / currScale}px`
|
||
dom.style.transform = `scale(${currScale})`
|
||
for (let item of ignore) {
|
||
let itemEl = item.el || item.dom
|
||
typeof item == 'string' && (itemEl = item)
|
||
if (!itemEl) {
|
||
console.error(`autofit: bad selector: ${itemEl}`)
|
||
continue
|
||
}
|
||
let realScale = item.scale ? item.scale : 1 / currScale
|
||
let realFontSize = realScale != currScale ? item.fontSize : 'autofit'
|
||
let realWidth = realScale != currScale ? item.width : 'autofit'
|
||
let realHeight = realScale != currScale ? item.height : 'autofit'
|
||
let regex = new RegExp(`${itemEl}(\x20|{)`, 'gm')
|
||
let isIgnored = regex.test(document.querySelector('#ignoreStyle').innerHTML)
|
||
if (isIgnored) {
|
||
continue
|
||
}
|
||
document.querySelector('#ignoreStyle').innerHTML += `\n${itemEl} {
|
||
transform: scale(${realScale})!important;
|
||
transform-origin: 0 0;
|
||
width: ${realWidth}!important;
|
||
height: ${realHeight}!important;
|
||
}`
|
||
document.querySelector(
|
||
'#ignoreStyle'
|
||
).innerHTML += `\n${itemEl} div ,${itemEl} span,${itemEl} a,${itemEl} * {
|
||
font-size: ${realFontSize}px;
|
||
}`
|
||
}
|
||
}
|