fixed: 修复友圈掉帧bug

This commit is contained in:
Vaica committed 2026-01-22 13:28:49 +08:00
1 parent 904f9f40c4
commit f09d6a7f71
1 file changed
+159 -16
+159 -16
View File
@@ -49,11 +49,9 @@
background-color 0.3s ease, background-color 0.3s ease,
border-color 0.3s ease; border-color 0.3s ease;
will-change: transform; will-change: transform;
overflow: hidden;
opacity: 0;
animation: ukFadeInUp 0.6s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
text-decoration: none; text-decoration: none;
transform: translateZ(0); /* Enable GPU acceleration */ transform: translateZ(0); /* Enable GPU acceleration */
overflow: hidden; /* 防止背景图溢出 */
} }
.friend-circle-list a { .friend-circle-list a {
@@ -110,17 +108,6 @@
transition: all 0.15s ease; transition: all 0.15s ease;
} }
@keyframes ukFadeInUp {
0% {
opacity: 0;
transform: translateY(40px) scale(0.95);
}
100% {
opacity: 1;
transform: translateY(0) scale(1);
}
}
/* Top: Title */ /* Top: Title */
.fc-title { .fc-title {
font-size: 18px; font-size: 18px;
@@ -305,8 +292,74 @@
[data-theme="dark"] .artalk .atk-main-editor { [data-theme="dark"] .artalk .atk-main-editor {
border: 1px solid rgba(255, 255, 255, 0.1) !important; border: 1px solid rgba(255, 255, 255, 0.1) !important;
} }
/* Friend Circle Tooltip Card */
.fc-tooltip {
position: fixed;
z-index: 9999;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 12px;
padding: 16px;
width: 300px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
pointer-events: none;
opacity: 0;
transform: scale(0.95) translateY(10px);
transition: opacity 0.2s ease, transform 0.2s ease;
font-size: 14px;
line-height: 1.6;
color: #333;
display: none; /* Hidden by default */
}
.fc-tooltip.is-visible {
opacity: 1;
transform: scale(1) translateY(0);
display: block;
}
.fc-tooltip-title {
font-weight: 700;
margin-bottom: 8px;
font-size: 15px;
color: #000;
border-bottom: 1px solid rgba(0,0,0,0.05);
padding-bottom: 6px;
}
.fc-tooltip-content {
color: #555;
text-align: justify;
display: -webkit-box;
-webkit-line-clamp: 6; /* Limit lines */
-webkit-box-orient: vertical;
overflow: hidden;
}
[data-theme="dark"] .fc-tooltip {
background: rgba(35, 35, 35, 0.95);
border: 1px solid rgba(255, 255, 255, 0.1);
color: #eee;
}
[data-theme="dark"] .fc-tooltip-title {
color: #fff;
border-bottom-color: rgba(255,255,255,0.1);
}
[data-theme="dark"] .fc-tooltip-content {
color: #ccc;
}
</style> </style>
<div id="fc-tooltip" class="fc-tooltip">
<div class="fc-tooltip-title"></div>
<div class="fc-tooltip-content"></div>
</div>
<script> <script>
// 使用全局对象管理友圈逻辑 // 使用全局对象管理友圈逻辑
window.FriendCircle = { window.FriendCircle = {
@@ -334,10 +387,13 @@
const dateStr = this.timeAgo(post.date); const dateStr = this.timeAgo(post.date);
// 减少延迟时间,避免动画积压 // 减少延迟时间,避免动画积压
const delay = index * 0.05; const delay = index * 0.05;
const bgImageSrc = post.image || post.avatar; // 背景图固定使用头像,以获得一致的装饰效果
const bgImageSrc = post.avatar;
// Escape quotes for data attribute
const description = post.description ? post.description.replace(/"/g, '&quot;') : '';
html += ` html += `
<a href="${post.link}" target="_blank" class="fc-item" style="animation-delay: ${delay}s"> <a href="${post.link}" target="_blank" class="fc-item uk-animation-slide-bottom-small" style="animation-delay: ${delay}s" data-desc="${description}" data-title="${post.title}">
<div class="fc-title" title="${post.title}">${post.title}</div> <div class="fc-title" title="${post.title}">${post.title}</div>
<img src="${bgImageSrc}" class="fc-bg-image" loading="lazy" onerror="this.style.opacity=0"> <img src="${bgImageSrc}" class="fc-bg-image" loading="lazy" onerror="this.style.opacity=0">
<div class="fc-bottom"> <div class="fc-bottom">
@@ -385,10 +441,97 @@
}); });
}, },
initTooltip: function() {
if (this.tooltipInitialized) return;
this.tooltipInitialized = true;
const tooltip = document.getElementById('fc-tooltip');
const titleEl = tooltip.querySelector('.fc-tooltip-title');
const contentEl = tooltip.querySelector('.fc-tooltip-content');
const container = document.getElementById('friend-circle-container');
if (!tooltip || !container) return;
// Move tooltip to body to prevent clipping by overflow:hidden or transforms
if (tooltip.parentNode !== document.body) {
document.body.appendChild(tooltip);
}
// Cleanup tooltip when navigating away (PJAX)
const cleanup = () => {
if (tooltip && tooltip.parentNode === document.body) {
tooltip.remove();
}
document.removeEventListener('pjax:send', cleanup);
};
document.addEventListener('pjax:send', cleanup);
const updateTooltip = (e) => {
const item = e.target.closest('.fc-item');
if (item) {
const desc = item.getAttribute('data-desc');
const title = item.getAttribute('data-title');
if (desc) {
titleEl.innerText = title;
contentEl.innerText = desc;
tooltip.classList.add('is-visible');
const tooltipWidth = tooltip.offsetWidth;
const tooltipHeight = tooltip.offsetHeight;
const winWidth = window.innerWidth;
const winHeight = window.innerHeight;
const gap = 15; // Gap between cursor and tooltip
let left = e.clientX + gap;
let top = e.clientY + gap;
// Horizontal Logic
if (left + tooltipWidth > winWidth - gap) {
// Flip to left
left = e.clientX - tooltipWidth - gap;
// If flipping makes it go off-screen to the left (e.g. wide tooltip, cursor near left)
if (left < gap) {
// Clamp to left edge
left = gap;
}
}
// Vertical Logic
if (top + tooltipHeight > winHeight - gap) {
// Flip to top
top = e.clientY - tooltipHeight - gap;
// If flipping makes it go off-screen to the top
if (top < gap) {
// Clamp to top edge
top = gap;
}
}
tooltip.style.left = `${left}px`;
tooltip.style.top = `${top}px`;
} else {
tooltip.classList.remove('is-visible');
}
} else {
tooltip.classList.remove('is-visible');
}
};
container.addEventListener('mousemove', updateTooltip);
container.addEventListener('mouseleave', () => {
tooltip.classList.remove('is-visible');
});
},
init: function () { init: function () {
const container = document.getElementById("friend-circle-container"); const container = document.getElementById("friend-circle-container");
if (!container) return; if (!container) return;
this.initTooltip();
// 防止重复初始化导致掉帧 // 防止重复初始化导致掉帧
if (this.isFetching) return; if (this.isFetching) return;
this.isFetching = true; this.isFetching = true;