mirror of
https://gitee.com/ulthon/ulthon_information.git
synced 2026-07-08 21:12: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;
|
color: #888;
|
||||||
margin-right: 8px;
|
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,
|
contentPadding: 20,
|
||||||
fontScale: 1,
|
fontScale: 1,
|
||||||
tableFontScale: 1
|
tableFontScale: 1,
|
||||||
|
useDomPreview: true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ===== DOM分页预览状态 =====
|
||||||
|
var domPages = [];
|
||||||
|
var currentDomPageIndex = 0;
|
||||||
|
var totalDomPages = 0;
|
||||||
|
|
||||||
// ===== 文章数据 =====
|
// ===== 文章数据 =====
|
||||||
var postData = {
|
var postData = {
|
||||||
id: 0,
|
id: 0,
|
||||||
@@ -248,19 +254,30 @@ var PhoneImageEngine = (function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 渲染缩略图
|
// 渲染缩略图
|
||||||
renderThumbnails(sizeConfig).then(function() {
|
if (config.useDomPreview) {
|
||||||
PhoneImageLogPanel.log('渲染完成,共 ' + pages.length + ' 页', 'success');
|
renderDomPages();
|
||||||
|
PhoneImageLogPanel.log('DOM预览渲染完成,共 ' + pages.length + ' 页', 'success');
|
||||||
render._locked = false;
|
render._locked = false;
|
||||||
if (render._pending) {
|
if (render._pending) {
|
||||||
render._pending = false;
|
render._pending = false;
|
||||||
render().catch(function() {});
|
render().catch(function() {});
|
||||||
}
|
}
|
||||||
deferred.resolve(pages);
|
deferred.resolve(pages);
|
||||||
}).catch(function(err) {
|
} else {
|
||||||
PhoneImageLogPanel.log('渲染失败: ' + err, 'error');
|
renderThumbnails(sizeConfig).then(function() {
|
||||||
render._locked = false;
|
PhoneImageLogPanel.log('渲染完成,共 ' + pages.length + ' 页', 'success');
|
||||||
deferred.reject(err);
|
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) {
|
}).catch(function(err) {
|
||||||
PhoneImageLogPanel.log('分页计算失败: ' + err, 'error');
|
PhoneImageLogPanel.log('分页计算失败: ' + err, 'error');
|
||||||
render._locked = false;
|
render._locked = false;
|
||||||
@@ -1311,6 +1328,68 @@ var PhoneImageEngine = (function () {
|
|||||||
return deferred.promise();
|
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
|
* @param {Object} sizeConfig
|
||||||
@@ -1735,6 +1814,9 @@ var PhoneImageEngine = (function () {
|
|||||||
syncPreview: syncPreview,
|
syncPreview: syncPreview,
|
||||||
setPageAlignment: setPageAlignment,
|
setPageAlignment: setPageAlignment,
|
||||||
exportLongImage: exportLongImage,
|
exportLongImage: exportLongImage,
|
||||||
|
renderDomPages: renderDomPages,
|
||||||
|
renderDomPageThumbnails: renderDomPageThumbnails,
|
||||||
|
refreshDomPage: refreshDomPage,
|
||||||
logPanel: PhoneImageLogPanel,
|
logPanel: PhoneImageLogPanel,
|
||||||
getContentHtml: function () {
|
getContentHtml: function () {
|
||||||
if (window.phoneImageEditor) {
|
if (window.phoneImageEditor) {
|
||||||
|
|||||||
@@ -261,16 +261,16 @@
|
|||||||
<div id="render-preview"></div>
|
<div id="render-preview"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 右侧:分页排版预览 -->
|
<!-- 右侧:分页排版预览 (DOM分页渲染) -->
|
||||||
<div class="paginated-preview-area">
|
<div class="paginated-preview-area">
|
||||||
<div class="preview-header">
|
<div class="preview-header">
|
||||||
<span>画布预览</span>
|
<span>分页预览</span>
|
||||||
<div style="display:inline-flex;align-items:center;gap:8px;float:right;">
|
<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>
|
<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>
|
</div>
|
||||||
<div class="preview-thumb-zone">
|
<div class="preview-thumb-zone">
|
||||||
<div id="paginated-preview" class="preview-thumbnails"></div>
|
<div id="paginated-preview"></div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 日志面板由 LogPanel.init() 动态插入 -->
|
<!-- 日志面板由 LogPanel.init() 动态插入 -->
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user