update theme to butterfly
This commit is contained in:
@@ -159,7 +159,7 @@ if hexo-config('enter_transitions')
|
||||
animation: titleScale 1s
|
||||
|
||||
canvas:not(#ribbon-canvas),
|
||||
#web_bg
|
||||
#web_bg.bg-animation
|
||||
animation: to_show 4s
|
||||
|
||||
#ribbon-canvas
|
||||
|
||||
@@ -100,18 +100,23 @@ $code-block
|
||||
.highlight-tools
|
||||
display: flex
|
||||
align-items: center
|
||||
overflow: hidden
|
||||
padding: 0 8px
|
||||
min-height: 24px
|
||||
height: 2.15em
|
||||
background: var(--hltools-bg)
|
||||
color: var(--hltools-color)
|
||||
font-size: $code-font-size
|
||||
overflow: hidden
|
||||
|
||||
& > *
|
||||
padding: 5px
|
||||
flex: 0 0 auto
|
||||
margin: 2px
|
||||
|
||||
i
|
||||
display: inline-flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
padding: 5px
|
||||
cursor: pointer
|
||||
transition: all .3s
|
||||
|
||||
@@ -127,31 +132,28 @@ $code-block
|
||||
|
||||
if !$highlight_macstyle
|
||||
& > .macStyle
|
||||
padding: 0
|
||||
margin: 0
|
||||
|
||||
.code-lang
|
||||
flex: 1
|
||||
flex: 1 1 auto
|
||||
overflow: hidden
|
||||
padding-right: 10px
|
||||
text-transform: uppercase
|
||||
text-overflow: ellipsis
|
||||
white-space: nowrap
|
||||
font-weight: bold
|
||||
font-size: 1.15em
|
||||
user-select: none
|
||||
-webkit-user-select: none
|
||||
padding 2px
|
||||
|
||||
.copy-notice
|
||||
padding-right: 2px
|
||||
opacity: 0
|
||||
transition: opacity .4s
|
||||
|
||||
if hexo-config('code_blocks.language')
|
||||
.code-lang
|
||||
flex: 1
|
||||
else if (!$highlight_macstyle && hexo-config('code_blocks.shrink') != 'none')
|
||||
& > div:nth-child(2)
|
||||
flex: 1
|
||||
margin-right: auto
|
||||
else if !$highlight_macstyle && hexo-config('code_blocks.shrink') != 'none'
|
||||
& > :nth-child(2)
|
||||
margin-right: auto
|
||||
else
|
||||
.macStyle
|
||||
flex: 1
|
||||
& > :nth-child(1)
|
||||
margin-right: auto
|
||||
|
||||
.gutter
|
||||
user-select: none
|
||||
@@ -163,17 +165,28 @@ $code-block
|
||||
td
|
||||
border: none
|
||||
|
||||
.copy-notice
|
||||
position: absolute
|
||||
z-index: 99999
|
||||
padding: 2px 6px
|
||||
border-radius: 3px
|
||||
background: var(--hltools-bg)
|
||||
white-space: nowrap
|
||||
font-size: 12px
|
||||
pointer-events: none
|
||||
|
||||
if $highlight_macstyle
|
||||
.container
|
||||
figure.highlight
|
||||
margin: 0 0 24px
|
||||
border-radius: 7px
|
||||
border-radius: 8px
|
||||
box-shadow: 0 5px 10px 0 $highlight-mac-border
|
||||
-webkit-transform: translateZ(0)
|
||||
|
||||
.highlight-tools
|
||||
.macStyle
|
||||
display: flex
|
||||
padding: 3px
|
||||
|
||||
& > *
|
||||
margin-right: 8px
|
||||
@@ -231,7 +244,7 @@ if hexo-config('code_blocks.height_limit')
|
||||
& ~ pre
|
||||
overflow: hidden
|
||||
height: unit(hexo-config('code_blocks.height_limit'), px)
|
||||
|
||||
|
||||
@keyframes code-expand-key
|
||||
0%
|
||||
opacity: .6
|
||||
@@ -264,8 +277,8 @@ if hexo-config('code_blocks.fullpage')
|
||||
& ~ table
|
||||
display: block
|
||||
overflow: auto
|
||||
height: calc(100vh - 2.15em)
|
||||
margin-bottom: 0
|
||||
height: calc(100vh - 2.15em)
|
||||
|
||||
@keyframes code-fullpage
|
||||
0%,
|
||||
|
||||
@@ -130,6 +130,7 @@ if hexo-config('darkmode.enable') || hexo-config('display_mode') == 'dark'
|
||||
|
||||
// hide-tags
|
||||
.hide-button,
|
||||
.toggle-button,
|
||||
#post-outdate-notice,
|
||||
.error-img,
|
||||
.container iframe,
|
||||
@@ -140,9 +141,9 @@ if hexo-config('darkmode.enable') || hexo-config('display_mode') == 'dark'
|
||||
|
||||
img:not(.cover)
|
||||
if hexo-config('lazyload.enable') && hexo-config('lazyload.blur') && !hexo-config('lazyload.placeholder')
|
||||
filter: blur(0) brightness(.8)
|
||||
filter: blur(0) brightness(.88) contrast(.95)
|
||||
else
|
||||
filter: brightness(.8)
|
||||
filter: brightness(.88) contrast(.95)
|
||||
|
||||
#aside-content .aside-list > .aside-list-item:not(:last-child)
|
||||
border-bottom: 1px dashed alpha(#FFFFFF, .1)
|
||||
|
||||
@@ -42,6 +42,7 @@ if hexo-config('readmode')
|
||||
font-size: 16px
|
||||
transition: background .3s
|
||||
addBorderRadius(8)
|
||||
@extend .btn-effects
|
||||
|
||||
+maxWidth768()
|
||||
top: initial
|
||||
|
||||
@@ -39,11 +39,26 @@
|
||||
border: 1px solid $tag-hide-toggle-bg
|
||||
addBorderRadius(5, true)
|
||||
|
||||
& > .toggle-content
|
||||
margin: 30px 24px
|
||||
|
||||
& > .toggle-button
|
||||
padding: 6px 15px
|
||||
background: $tag-hide-toggle-bg
|
||||
color: #1F2D3D
|
||||
list-style: none
|
||||
cursor: pointer
|
||||
|
||||
& > .toggle-content
|
||||
margin: 30px 24px
|
||||
&::-webkit-details-marker
|
||||
display: none
|
||||
|
||||
&::before
|
||||
@extend .fontawesomeIcon
|
||||
margin-right: 8px
|
||||
content: '\f0d7'
|
||||
transition: transform .3s ease
|
||||
transform: rotate(-90deg)
|
||||
transform-origin: center center
|
||||
|
||||
&[open] summary::before
|
||||
transform: rotate(0)
|
||||
@@ -68,7 +68,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const isPrismjs = plugin === 'prismjs'
|
||||
const highlightShrinkClass = isHighlightShrink === true ? 'closed' : ''
|
||||
const highlightShrinkEle = isHighlightShrink !== undefined ? '<i class="fas fa-angle-down expand"></i>' : ''
|
||||
const highlightCopyEle = highlightCopy ? '<div class="copy-notice"></div><i class="fas fa-paste copy-button"></i>' : ''
|
||||
const highlightCopyEle = highlightCopy ? '<i class="fas fa-paste copy-button"></i>' : ''
|
||||
const highlightMacStyleEle = '<div class="macStyle"><div class="mac-close"></div><div class="mac-minimize"></div><div class="mac-maximize"></div></div>'
|
||||
const highlightFullpageEle = highlightFullpage ? '<i class="fa-solid fa-up-right-and-down-left-from-center fullpage-button"></i>' : ''
|
||||
|
||||
@@ -76,9 +76,46 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
if (GLOBAL_CONFIG.Snackbar !== undefined) {
|
||||
btf.snackbarShow(text)
|
||||
} else {
|
||||
ele.textContent = text
|
||||
ele.style.opacity = 1
|
||||
setTimeout(() => { ele.style.opacity = 0 }, 800)
|
||||
const newEle = document.createElement('div')
|
||||
newEle.className = 'copy-notice'
|
||||
newEle.textContent = text
|
||||
document.body.appendChild(newEle)
|
||||
|
||||
const buttonRect = ele.getBoundingClientRect()
|
||||
const scrollTop = window.pageYOffset || document.documentElement.scrollTop
|
||||
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft
|
||||
|
||||
// X-axis boundary check
|
||||
const halfWidth = newEle.offsetWidth / 2
|
||||
const centerLeft = buttonRect.left + scrollLeft + buttonRect.width / 2
|
||||
const finalLeft = Math.max(halfWidth + 10, Math.min(window.innerWidth - halfWidth - 10, centerLeft))
|
||||
|
||||
// Show tooltip below button if too close to top
|
||||
const normalTop = buttonRect.top + scrollTop - 40
|
||||
const shouldShowBelow = buttonRect.top < 60 || normalTop < 10
|
||||
|
||||
const topValue = shouldShowBelow ? buttonRect.top + scrollTop + buttonRect.height + 10 : normalTop
|
||||
|
||||
newEle.style.cssText = `
|
||||
top: ${topValue + 10}px;
|
||||
left: ${finalLeft}px;
|
||||
transform: translateX(-50%);
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease, top 0.3s ease;
|
||||
`
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
newEle.style.opacity = '1'
|
||||
newEle.style.top = `${topValue}px`
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
newEle.style.opacity = '0'
|
||||
newEle.style.top = `${topValue + 10}px`
|
||||
setTimeout(() => {
|
||||
newEle?.remove()
|
||||
}, 300)
|
||||
}, 800)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +136,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const preCodeSelector = isPrismjs ? 'pre code' : 'table .code pre'
|
||||
const codeElement = $buttonParent.querySelector(preCodeSelector)
|
||||
if (!codeElement) return
|
||||
copy(codeElement.innerText, clickEle.previousElementSibling)
|
||||
copy(codeElement.innerText, clickEle)
|
||||
$buttonParent.classList.remove('copy-true')
|
||||
}
|
||||
|
||||
@@ -126,6 +163,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
// 獲取隱藏狀態下元素的真實高度
|
||||
const getActualHeight = item => {
|
||||
if (item.offsetHeight > 0) return item.offsetHeight
|
||||
const hiddenElements = new Map()
|
||||
|
||||
const fix = () => {
|
||||
@@ -512,17 +550,29 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const $articleList = $article.querySelectorAll('h1,h2,h3,h4,h5,h6')
|
||||
let detectItem = ''
|
||||
|
||||
// Optimization: Cache header positions
|
||||
let headerList = []
|
||||
const updateHeaderPositions = () => {
|
||||
headerList = Array.from($articleList).map(ele => ({
|
||||
ele,
|
||||
top: btf.getEleTop(ele),
|
||||
id: ele.id
|
||||
}))
|
||||
}
|
||||
|
||||
updateHeaderPositions()
|
||||
btf.addEventListenerPjax(window, 'resize', btf.throttle(updateHeaderPositions, 200))
|
||||
|
||||
const findHeadPosition = top => {
|
||||
if (top === 0) return false
|
||||
|
||||
let currentId = ''
|
||||
let currentIndex = ''
|
||||
|
||||
for (let i = 0; i < $articleList.length; i++) {
|
||||
const ele = $articleList[i]
|
||||
if (top > btf.getEleTop(ele) - 80) {
|
||||
const id = ele.id
|
||||
currentId = id ? '#' + encodeURI(id) : ''
|
||||
for (let i = 0; i < headerList.length; i++) {
|
||||
const item = headerList[i]
|
||||
if (top > item.top - 80) {
|
||||
currentId = item.id ? '#' + encodeURI(item.id) : ''
|
||||
currentIndex = i
|
||||
} else {
|
||||
break
|
||||
@@ -600,7 +650,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
$body.classList.add('read-mode')
|
||||
newEle.type = 'button'
|
||||
newEle.className = 'fas fa-sign-out-alt exit-readmode'
|
||||
newEle.className = 'exit-readmode'
|
||||
newEle.innerHTML = '<i class="fas fa-sign-out-alt"></i>'
|
||||
newEle.addEventListener('click', exitReadMode)
|
||||
$body.appendChild(newEle)
|
||||
},
|
||||
|
||||
@@ -14,37 +14,35 @@
|
||||
}
|
||||
},
|
||||
|
||||
throttle: function (func, wait, options = {}) {
|
||||
let timeout, context, args
|
||||
throttle: (func, wait, options = {}) => {
|
||||
let timeout, args
|
||||
let previous = 0
|
||||
|
||||
const later = () => {
|
||||
previous = options.leading === false ? 0 : new Date().getTime()
|
||||
timeout = null
|
||||
func.apply(context, args)
|
||||
if (!timeout) context = args = null
|
||||
func(...args)
|
||||
if (!timeout) args = null
|
||||
}
|
||||
|
||||
const throttled = (...params) => {
|
||||
return (...params) => {
|
||||
const now = new Date().getTime()
|
||||
if (!previous && options.leading === false) previous = now
|
||||
const remaining = wait - (now - previous)
|
||||
context = this
|
||||
args = params
|
||||
|
||||
if (remaining <= 0 || remaining > wait) {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout)
|
||||
timeout = null
|
||||
}
|
||||
previous = now
|
||||
func.apply(context, args)
|
||||
if (!timeout) context = args = null
|
||||
func(...args)
|
||||
if (!timeout) args = null
|
||||
} else if (!timeout && options.trailing !== false) {
|
||||
timeout = setTimeout(later, remaining)
|
||||
}
|
||||
}
|
||||
|
||||
return throttled
|
||||
},
|
||||
|
||||
overflowPaddingR: {
|
||||
@@ -169,17 +167,7 @@
|
||||
|
||||
isHidden: ele => ele.offsetHeight === 0 && ele.offsetWidth === 0,
|
||||
|
||||
getEleTop: ele => {
|
||||
let actualTop = ele.offsetTop
|
||||
let current = ele.offsetParent
|
||||
|
||||
while (current !== null) {
|
||||
actualTop += current.offsetTop
|
||||
current = current.offsetParent
|
||||
}
|
||||
|
||||
return actualTop
|
||||
},
|
||||
getEleTop: ele => ele.getBoundingClientRect().top + window.scrollY,
|
||||
|
||||
loadLightbox: ele => {
|
||||
const service = GLOBAL_CONFIG.lightbox
|
||||
@@ -190,7 +178,7 @@
|
||||
}
|
||||
|
||||
if (service === 'fancybox') {
|
||||
Array.from(ele).forEach(i => {
|
||||
ele.forEach(i => {
|
||||
if (i.parentNode.tagName !== 'A') {
|
||||
const dataSrc = i.dataset.lazySrc || i.src
|
||||
const dataCaption = i.title || i.alt || ''
|
||||
|
||||
Reference in New Issue
Block a user