mirror of
https://gitee.com/ulthon/ulthon_information.git
synced 2026-07-01 14:42:48 +08:00
feat(phone-image): DOM分页預覽CSS+HTML基礎結構和數據模型
This commit is contained in:
@@ -1096,3 +1096,126 @@ body > .page-header-right .layui-btn:not(.layui-btn-primary):not(.layui-btn-norm
|
||||
color: #888;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
DOM Page Container (DOM分页预览容器)
|
||||
右侧分页预览区使用纯DOM渲染,不依赖截图
|
||||
JS动态填充这些容器
|
||||
============================================ */
|
||||
|
||||
/* --- DOM分页容器基础 --- */
|
||||
.dom-page-container {
|
||||
background: #ffffff;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 尺寸 - 复用size class模式 */
|
||||
.size-xiaohongshu .dom-page-container {
|
||||
width: 540px;
|
||||
height: 720px;
|
||||
}
|
||||
|
||||
.size-douyin .dom-page-container {
|
||||
width: 540px;
|
||||
height: 960px;
|
||||
}
|
||||
|
||||
/* --- DOM分页品牌标识头 --- */
|
||||
.dom-page-brand-header {
|
||||
height: 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
font-size: 13px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.dom-page-brand-header img {
|
||||
height: 20px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.dom-page-brand-header span {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* --- DOM分页内容区域 --- */
|
||||
.dom-page-content {
|
||||
padding: 20px;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
height: calc(100% - 36px - 30px);
|
||||
font-size: calc(14px * var(--pi-font-scale, 1));
|
||||
line-height: 1.8;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
/* DOM分页内容区对齐支持 (复用valign模式) */
|
||||
.dom-page-content.valign-center {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.dom-page-content.valign-bottom {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
/* --- DOM分页页码 --- */
|
||||
.dom-page-footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
padding: 6px 0;
|
||||
font-size: 11px;
|
||||
color: #999;
|
||||
border-top: 1px solid #f5f5f5;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* --- 纯图片页 --- */
|
||||
.dom-page-pure-image .dom-page-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.dom-page-pure-image .dom-page-content img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
DOM分页内容区代码块样式
|
||||
参照 #render-preview pre (L926-935)
|
||||
============================================ */
|
||||
.dom-page-content pre {
|
||||
background: #f6f8fa;
|
||||
border-radius: 6px;
|
||||
padding: 12px 16px;
|
||||
overflow-x: auto;
|
||||
font-size: calc(13px * var(--pi-code-font-scale, 1));
|
||||
line-height: 1.6;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.dom-page-content code {
|
||||
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
|
||||
font-size: calc(13px * var(--pi-code-font-scale, 1));
|
||||
}
|
||||
|
||||
.dom-page-content pre code {
|
||||
background: none;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
@@ -100,9 +100,15 @@ var PhoneImageEngine = (function () {
|
||||
},
|
||||
contentPadding: 20,
|
||||
fontScale: 1,
|
||||
tableFontScale: 1
|
||||
tableFontScale: 1,
|
||||
useDomPreview: true
|
||||
};
|
||||
|
||||
// ===== DOM分页预览状态 =====
|
||||
var domPages = [];
|
||||
var currentDomPageIndex = 0;
|
||||
var totalDomPages = 0;
|
||||
|
||||
// ===== 文章数据 =====
|
||||
var postData = {
|
||||
id: 0,
|
||||
@@ -248,19 +254,30 @@ var PhoneImageEngine = (function () {
|
||||
}
|
||||
|
||||
// 渲染缩略图
|
||||
renderThumbnails(sizeConfig).then(function() {
|
||||
PhoneImageLogPanel.log('渲染完成,共 ' + pages.length + ' 页', 'success');
|
||||
if (config.useDomPreview) {
|
||||
renderDomPages();
|
||||
PhoneImageLogPanel.log('DOM预览渲染完成,共 ' + pages.length + ' 页', 'success');
|
||||
render._locked = false;
|
||||
if (render._pending) {
|
||||
render._pending = false;
|
||||
render().catch(function() {});
|
||||
}
|
||||
deferred.resolve(pages);
|
||||
}).catch(function(err) {
|
||||
PhoneImageLogPanel.log('渲染失败: ' + err, 'error');
|
||||
render._locked = false;
|
||||
deferred.reject(err);
|
||||
});
|
||||
} else {
|
||||
renderThumbnails(sizeConfig).then(function() {
|
||||
PhoneImageLogPanel.log('渲染完成,共 ' + pages.length + ' 页', 'success');
|
||||
render._locked = false;
|
||||
if (render._pending) {
|
||||
render._pending = false;
|
||||
render().catch(function() {});
|
||||
}
|
||||
deferred.resolve(pages);
|
||||
}).catch(function(err) {
|
||||
PhoneImageLogPanel.log('渲染失败: ' + err, 'error');
|
||||
render._locked = false;
|
||||
deferred.reject(err);
|
||||
});
|
||||
}
|
||||
}).catch(function(err) {
|
||||
PhoneImageLogPanel.log('分页计算失败: ' + err, 'error');
|
||||
render._locked = false;
|
||||
@@ -1311,6 +1328,68 @@ var PhoneImageEngine = (function () {
|
||||
return deferred.promise();
|
||||
}
|
||||
|
||||
/**
|
||||
* DOM分页预览 - 将pages[]转换为domPages格式
|
||||
* 替代canvas截图方案,直接操作DOM渲染
|
||||
*/
|
||||
function renderDomPages() {
|
||||
var sizeConfig = config.sizes[config.size] || config.sizes.xiaohongshu;
|
||||
|
||||
// 清空domPages
|
||||
domPages = [];
|
||||
|
||||
// 如果没有pages数据,返回
|
||||
if (!pages || pages.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 遍历pages,创建domPage对象
|
||||
for (var i = 0; i < pages.length; i++) {
|
||||
var page = pages[i];
|
||||
var domPage = {
|
||||
html: page.html || '',
|
||||
type: page.type || 'content',
|
||||
pageNum: page.pageNum || (i + 1),
|
||||
valign: (config.pageAlignments && config.pageAlignments[i]) || 'top',
|
||||
isPureImage: page.type === 'pure-image'
|
||||
};
|
||||
domPages.push(domPage);
|
||||
}
|
||||
|
||||
totalDomPages = domPages.length;
|
||||
currentDomPageIndex = 0;
|
||||
|
||||
// 调用渲染
|
||||
renderDomPageThumbnails(sizeConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* DOM分页预览 - 渲染所有页面的缩略图
|
||||
* TODO: T3将实现完整逻辑
|
||||
* 当前只清空容器并创建占位
|
||||
* @param {Object} sizeConfig
|
||||
*/
|
||||
function renderDomPageThumbnails(sizeConfig) {
|
||||
var $preview = $('#paginated-preview');
|
||||
$preview.empty();
|
||||
// 完整实现在T3中
|
||||
}
|
||||
|
||||
/**
|
||||
* DOM分页预览 - 刷新指定页面的对齐方式
|
||||
* TODO: T3将实现完整逻辑
|
||||
* @param {number} pageIndex - 页面索引(0-based)
|
||||
*/
|
||||
function refreshDomPage(pageIndex) {
|
||||
var $containers = $('#paginated-preview .dom-page-container');
|
||||
if (pageIndex >= 0 && pageIndex < $containers.length) {
|
||||
var $content = $containers.eq(pageIndex).find('.dom-page-content');
|
||||
$content.removeClass('valign-top valign-center valign-bottom');
|
||||
var alignment = config.pageAlignments[pageIndex] || 'top';
|
||||
$content.addClass('valign-' + alignment);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化缩略图容器(流式渲染第一步:清空容器)
|
||||
* @param {Object} sizeConfig
|
||||
@@ -1735,6 +1814,9 @@ var PhoneImageEngine = (function () {
|
||||
syncPreview: syncPreview,
|
||||
setPageAlignment: setPageAlignment,
|
||||
exportLongImage: exportLongImage,
|
||||
renderDomPages: renderDomPages,
|
||||
renderDomPageThumbnails: renderDomPageThumbnails,
|
||||
refreshDomPage: refreshDomPage,
|
||||
logPanel: PhoneImageLogPanel,
|
||||
getContentHtml: function () {
|
||||
if (window.phoneImageEditor) {
|
||||
|
||||
@@ -261,16 +261,16 @@
|
||||
<div id="render-preview"></div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧:分页排版预览 -->
|
||||
<!-- 右侧:分页排版预览 (DOM分页渲染) -->
|
||||
<div class="paginated-preview-area">
|
||||
<div class="preview-header">
|
||||
<span>画布预览</span>
|
||||
<span>分页预览</span>
|
||||
<div style="display:inline-flex;align-items:center;gap:8px;float:right;">
|
||||
<button id="btn-reset-alignments" type="button" style="height:26px;font-size:12px;border:1px solid #d9d9d9;border-radius:3px;padding:0 8px;cursor:pointer;background:#fff;">重置</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="preview-thumb-zone">
|
||||
<div id="paginated-preview" class="preview-thumbnails"></div>
|
||||
<div id="paginated-preview"></div>
|
||||
</div>
|
||||
<!-- 日志面板由 LogPanel.init() 动态插入 -->
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user