优化导航栏、分享海报等显示效果;优化代码及性能

This commit is contained in:
2026-07-25 13:33:51 +08:00
parent 32bf39f733
commit 7d56858616
13 changed files with 498 additions and 416 deletions
+9
View File
@@ -595,6 +595,9 @@ function init_douban_page() {
requestList(1, state.type, false, {
onSuccess: function () {
$this.addClass('active').parent().siblings().children('.cat-link').removeClass('active');
if (window.pix && typeof pix.centerCategoryNavActive === 'function') {
pix.centerCategoryNavActive($this);
}
var currentUrl = new URL(window.location.href);
if (!targetTag || targetTag === '全部') {
@@ -653,12 +656,18 @@ function init_douban_page() {
}).first();
if ($matchedTag.length > 0) {
$matchedTag.addClass('active').parent().siblings().children('.cat-link').removeClass('active');
if (window.pix && typeof pix.centerCategoryNavActive === 'function') {
pix.centerCategoryNavActive($matchedTag);
}
state.type = $matchedTag.attr('data-type') || '';
} else {
state.type = $('.douban_cat_nav .cat-link.active').attr('data-type') || '';
}
} else {
state.type = $('.douban_cat_nav .cat-link.active').attr('data-type') || '';
if (window.pix && typeof pix.centerCategoryNavActive === 'function') {
pix.centerCategoryNavActive($('.douban_cat_nav .cat-link.active').first());
}
}
}
+322 -354
View File
File diff suppressed because it is too large Load Diff
+25
View File
@@ -163,6 +163,31 @@ var pix = {
},
centerCategoryNavActive: function ($link) {
var $activeLink = $link && $link.length ? $link : $('.moment_cat_nav .active, .posts_cat_nav .active, .photos_cat_nav .active, .douban_cat_nav .active, .friends_cat_nav .active').first();
if (!$activeLink || !$activeLink.length) {
return;
}
var navEl = $activeLink.closest('.moment_cat_nav, .posts_cat_nav, .photos_cat_nav, .douban_cat_nav, .friends_cat_nav').find('ul').get(0);
if (!navEl) {
return;
}
var linkEl = $activeLink.get(0);
var maxScrollLeft = navEl.scrollWidth - navEl.clientWidth;
if (maxScrollLeft <= 0) {
return;
}
var navRect = navEl.getBoundingClientRect();
var linkRect = linkEl.getBoundingClientRect();
var targetScrollLeft = navEl.scrollLeft + (linkRect.left - navRect.left) - (navRect.width / 2 - linkRect.width / 2);
targetScrollLeft = Math.max(0, Math.min(maxScrollLeft, targetScrollLeft));
$(navEl).stop(true).animate({ scrollLeft: targetScrollLeft }, 220);
},
topCategoriesBarScroll: function () {
if (document.getElementById("cat_nav_items")) {
let xscroll = document.getElementById("cat_nav_items");
+3 -4
View File
@@ -361,10 +361,9 @@ function mu_box_show() {
function mu_box_hide(time = 2000) {
clearTimeout(trigger);
trigger = setTimeout(function () {
// 获取屏幕宽度判断是否为手机端(与歌词容器响应式逻辑保持一致)
const isMobile = $(window).width() <= 767;
// 手机端隐藏时额外向下偏移50px(可根据需要调整数值),非手机端保持默认0px
const hideTop = isMobile ? "50px" : "0px";
const hasBottomMenu = $(window).width() <= 960;
// 底部导航可见时,播放器收起到导航栏后面。
const hideTop = hasBottomMenu ? "50px" : "0px";
// 执行隐藏动画
$('.footer_nav_box').animate({
+89 -33
View File
@@ -5,7 +5,7 @@ const poster = (function() {
const DEBUG = false
const WIDTH = 700
const HEIGHT = 1160
const HEIGHT = 850
/**
* 将图片URL加载为Image对象并返回Promise
@@ -47,9 +47,12 @@ const poster = (function() {
const $title = createDom('canvas', 'id', 'title')
const $content = createDom('canvas', 'id', 'content')
const $logo = createDom('canvas', 'id', 'logo')
const $siteName = createDom('canvas', 'id', 'siteName')
const $description = createDom('canvas', 'id', 'description')
const $customText1 = createDom('canvas', 'id', 'customText1')
const $customText2 = createDom('canvas', 'id', 'customText2')
appendChilds($wrapper, $canvas, $day, $date, $title, $content, $logo, $description)
appendChilds($wrapper, $canvas, $day, $siteName, $date, $title, $content, $logo, $description, $customText1, $customText2)
$container.appendChild($wrapper)
const date = new Date()
@@ -83,6 +86,58 @@ const poster = (function() {
titleStyle.position = (config.titleStyle && config.titleStyle.position) || titleStyle.position
drawMoreLines($title, titleStyle, config.title)
// site name canvas
const siteNameStyle = {
font: '40px Helvetica',
lineHeight: 1.3,
color: 'rgba(255, 255, 255, 0.95)',
position: 'left'
}
siteNameStyle.font = (config.siteNameStyle && config.siteNameStyle.font) || siteNameStyle.font
siteNameStyle.color = (config.siteNameStyle && config.siteNameStyle.color) || siteNameStyle.color
siteNameStyle.lineHeight = (config.siteNameStyle && config.siteNameStyle.lineHeight) || siteNameStyle.lineHeight
siteNameStyle.position = (config.siteNameStyle && config.siteNameStyle.position) || siteNameStyle.position
drawMoreLines($siteName, siteNameStyle, config.siteName)
// description canvas
const descriptionStyle = {
font: '25px Helvetica',
color: 'rgba(236, 241, 255, 1)',
lineHeight: 1.2,
position: 'left'
}
descriptionStyle.font = (config.descriptionStyle && config.descriptionStyle.font) || descriptionStyle.font
descriptionStyle.color = (config.descriptionStyle && config.descriptionStyle.color) || descriptionStyle.color
descriptionStyle.lineHeight = (config.descriptionStyle && config.descriptionStyle.lineHeight) || descriptionStyle.lineHeight
descriptionStyle.position = (config.descriptionStyle && config.descriptionStyle.position) || descriptionStyle.position
drawMoreLines($description, descriptionStyle, config.description)
// custom text 1 canvas
const customText1Style = {
font: '28px Helvetica',
lineHeight: 1.3,
position: 'left',
color: 'rgba(0, 0, 0, 1)'
}
customText1Style.font = (config.customText1Style && config.customText1Style.font) || customText1Style.font
customText1Style.color = (config.customText1Style && config.customText1Style.color) || customText1Style.color
customText1Style.lineHeight = (config.customText1Style && config.customText1Style.lineHeight) || customText1Style.lineHeight
customText1Style.position = (config.customText1Style && config.customText1Style.position) || customText1Style.position
drawMoreLines($customText1, customText1Style, config.customText1 || '')
// custom text 2 canvas
const customText2Style = {
font: '28px Helvetica',
lineHeight: 1.3,
position: 'left',
color: 'rgba(0, 0, 0, 1)'
}
customText2Style.font = (config.customText2Style && config.customText2Style.font) || customText2Style.font
customText2Style.color = (config.customText2Style && config.customText2Style.color) || customText2Style.color
customText2Style.lineHeight = (config.customText2Style && config.customText2Style.lineHeight) || customText2Style.lineHeight
customText2Style.position = (config.customText2Style && config.customText2Style.position) || customText2Style.position
drawMoreLines($customText2, customText2Style, config.customText2 || '')
// content canvas
const contentStyle = {
font: '22px Helvetica',
@@ -96,15 +151,6 @@ const poster = (function() {
contentStyle.position = (config.contentStyle && config.contentStyle.position) || contentStyle.position
drawMoreLines($content, contentStyle, config.content);
// description canvas
const descriptionStyle = {
font: '24px Helvetica',
color: 'rgba(180, 180, 180, 1)',
lineHeight: 1.2,
position: 'left'
}
drawMoreLines($description, descriptionStyle, config.description)
// ------------------ 【修复点 1:使用 Promise.all 等待所有图片加载】 ------------------
Promise.all([
@@ -126,7 +172,7 @@ const poster = (function() {
ctx.drawImage(image, imgRect.sx, imgRect.sy, imgRect.sWidth, imgRect.sHeight, 20, 20, $canvas.width - 40, $canvas.height / 1.2 - 40);
// 3. 绘制覆盖层
ctx.fillStyle="rgba(0, 0, 0, 0.3)";
ctx.fillStyle="rgba(0, 0, 0, 0.6)";
ctx.fillRect(20, 20, $canvas.width - 40, $canvas.height / 1.2 - 40);
// 4. 绘制时间 (使用预先绘制好的 Canvas)
@@ -134,17 +180,20 @@ const poster = (function() {
ctx.drawImage($date, -21, 125)
// 5. 绘制 Logo
var logoh = 60;
var logoh = 140;
var cwidth = logoh * (logo.width / logo.height);
ctx.drawImage(logo, 60, $canvas.height / 1.2 + 30, cwidth, logoh);
ctx.drawImage(logo, 20, $canvas.height / 1.2 - 10, cwidth, logoh);
// 6. 绘制二维码
ctx.drawImage(qrcode, $canvas.width - 160, $canvas.height / 1.2 + 20, 120, 120);
ctx.drawImage(qrcode, $canvas.width - 150, $canvas.height / 1.2 + 10, 120, 120);
// 7. 绘制文字 (使用预先绘制好的 Canvas)
ctx.drawImage($title, 20, $canvas.height / 2 + 20)
ctx.drawImage($siteName, 10, 60)
ctx.drawImage($description, 10, 120)
ctx.drawImage($customText1, 270, $canvas.height / 2 + 310)
ctx.drawImage($customText2, 215, $canvas.height / 2 + 360)
ctx.drawImage($title, 20, $canvas.height / 2 + 60)
ctx.drawImage($content, 20, $canvas.height / 2 + 120)
ctx.drawImage($description, 20, $canvas.height / 1.2 + 110)
ctx.strokeStyle = 'rgba(122, 122, 122, 0.5)';
// 8. 转换并显示最终图片
@@ -204,19 +253,14 @@ const poster = (function() {
}
}
// 覆盖函数(不变)
// 覆盖函数:按目标区域等比缩放并居中裁切,尽量不留白
function coverImg(box_w, box_h, source_w, source_h) {
var sx = 0,
sy = 0,
sWidth = source_w,
sHeight = source_h;
if (source_w > source_h || (source_w == source_h && box_w < box_h)) {
sWidth = box_w * sHeight / box_h;
sx = (source_w - sWidth) / 2;
} else if (source_w < source_h || (source_w == source_h && box_w > box_h)) {
sHeight = box_h * sWidth / box_w;
sY = (source_h - sHeight) / 2;
}
const scale = Math.max(box_w / source_w, box_h / source_h);
const sWidth = box_w / scale;
const sHeight = box_h / scale;
const sx = (source_w - sWidth) / 2;
const sy = (source_h - sHeight) / 2;
return {
sx,
sy,
@@ -397,7 +441,8 @@ $('body').on('click', '.cr_poster', function () {
var content = content_element.innerText;
var content_length = content.length;
var permalink = t_content.length > 0 ? window.location.origin + '/moments/' + post_id : window.location.origin + window.location.pathname;
var title = t_content.length > 0 ? Theme.site_title + '-瞬间' : document.title;
var title = t_content.length > 0 ? '瞬间' : (document.title || '').split(' - ')[0];
var siteName = Theme.site_title;
// 确保 QRious 库可用
if (typeof QRious === 'undefined') {
@@ -430,7 +475,7 @@ $('body').on('click', '.cr_poster', function () {
// -----------------------------------------------------------------------
if (content_length > 120) {
content = content.substring(0, 80) + '...'
content = content.substring(0, 82) + '...'
}
// 海报生成回调
@@ -456,10 +501,21 @@ $('body').on('click', '.cr_poster', function () {
selector: modal + ' .poster_box',
container: $posterBox[0],
title: title,
siteName: siteName,
description: Theme.admin_des,
content: content,
logo: Theme.site_logo,
qrcode: $('#twoCode').attr('src'),
description: Theme.admin_des,
customText1: '扫描右侧二维码',
customText2: '或访问:https://anian.net',
customText1Style: {
font: '24px Helvetica',
color: 'rgba(0, 0, 0, 1)'
},
customText2Style: {
font: '24px Helvetica',
color: 'rgba(0, 0, 0, 1)'
},
callback: Posterdown
});
});
@@ -565,4 +621,4 @@ function handleShare(e, pic, title, pathname) {
break
}
}
}