微件:ScrollText
来自卡厄思梦境WIKI
<style> .scroll-text {
position: relative; overflow: hidden; display: flex; align-items: flex-start;
}
.scroll-text .scroll-text-content {
word-wrap: break-word; word-break: break-all; position: relative; width: 100%; text-align: center; animation: scrollText linear infinite;
}
.scroll-text .scroll-text-content:hover {
animation-play-state: paused;
} </style>
<script> (function() {
var processedElements = new WeakSet();
function initScroll() {
var wrappers = document.querySelectorAll('.scroll-text');
wrappers.forEach(function(wrapper, index) {
if (processedElements.has(wrapper)) {
return;
}
var content = wrapper.querySelector('.scroll-text-content');
if (!content) {
return;
}
var rect = wrapper.getBoundingClientRect();
if (rect.width === 0 || rect.height === 0) {
return;
}
processedElements.add(wrapper);
var speed = parseFloat(content.getAttribute('data-speed')) || 10;
var animationName = 'scrollText-' + index + '-' + Date.now();
// 使用双重 RAF 确保布局完成
requestAnimationFrame(function() {
requestAnimationFrame(function() {
var contentHeight = content.scrollHeight;
var wrapperHeight = wrapper.offsetHeight;
var scrollDistance = contentHeight - wrapperHeight;
if (scrollDistance <= 0) {
return;
}
var styleId = 'scroll-text-animation-' + index + '-' + Date.now();
var style = document.createElement('style');
style.id = styleId;
style.textContent = `
@keyframes ${animationName} {
0% { transform: translateY(0); }
100% { transform: translateY(-${scrollDistance}px); }
}
`;
document.head.appendChild(style);
var text = content.textContent || content.innerText;
var charCount = text.replace(/\s+/g, ).length;
var duration = Math.max(speed, charCount / 8);
content.style.animationName = animationName;
content.style.animationDuration = duration + 's';
});
});
});
}
var observer = new MutationObserver(function(mutations) {
var shouldInit = false;
mutations.forEach(function(mutation) {
if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
var target = mutation.target;
if (target.classList.contains('card-modal') && target.style.display === 'block') {
shouldInit = true;
}
}
if (mutation.addedNodes.length > 0) {
shouldInit = true;
}
});
if (shouldInit) {
setTimeout(initScroll, 300); // 增加延迟
}
});
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['style']
});
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
setTimeout(initScroll, 200);
});
} else {
setTimeout(initScroll, 200);
}
if (typeof mw !== 'undefined' && mw.hook) {
mw.hook('wikipage.content').add(function() {
setTimeout(initScroll, 300);
});
}
})(); </script>