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

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
+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
}
}
}