—
1.背景
—
3.实现
CSS3 column 多栏布局方案
多栏布局可以将内容分隔成多列进行展示,类似于报纸的栏目排版,这里可以利用多栏布局来模拟分页效果。
column-width: 每栏的宽度,设定后会根据容器宽度自动分列(真实宽度受容器尺寸影响);
column-count: 分栏个数;
column: column-width 和 column-count 的简写,俩值转成同一属性,谁小用谁,为了计算准确一般都写上 column: 100px 1;
column-gap: 每栏之间的间隔,默认 1em;
3.翻页只能支持滑动效果,并不能支持“覆盖”、“仿真翻页”效果。
附:
canvas 解析分页数据的部分代码思路:
chapterData(content) {
// 已经解析过的内容按行加入数组
var hasResolved = [];
var hasResolvedByP = [];
// 已解析行数
var hasResolvedLength = 0;
// 上一页最后的段落下标
var current = this.curPage.end.pIndex;
// 是否是每屏的第一行
var firstLine = true;
var lineHeight = 20;
var spacing = 30;
// 当前段落索引 < 总段落长度
while (current < content.length) {
// 当前段落
var curParagraph = content[current];
// 解析当前段落按行加入数组
var resolving = [];
// 带有行间距的数据结构
var withLineHeightResolving = []
// 每行的起始位置文字的索引
var start = 0;
if (firstLine) {
// 上一页最后的段落的文字偏移量
start = this.curPage.end.offset;
firstLine = false;
}
// 计算每行的文字宽度,超过了行宽就重新解析下一行
for (var i = start; i < curParagraph.length; i++) {
if (this.ctx.measureText(curParagraph.substring(start, i)).width > (window.innerWidth - 50)) {
resolving.push(curParagraph.substring(start, i));
if (start === 0) {
withLineHeightResolving.push({
text: curParagraph.substring(start, i),
// 每一段的第一行
isStart: true
});
} else {
withLineHeightResolving.push({
text: curParagraph.substring(start, i)
});
}
start = i;
}
}
// 最后一行没有满一行时,全部加入
if (start < i) {
resolving.push(curParagraph.substring(start, i));
// 当前段只有一行
if (start === 0) {
withLineHeightResolving.push({
text: curParagraph.substring(start, i),
isStart: true
});
} else {
withLineHeightResolving.push({
text: curParagraph.substring(start, i)
});
}
}
// 记录当前页的最后一个字的索引值
var offset = 0;
// 当前段解析完成后,计算是否已经满了一屏, 没有满屏则解析下一段落
// 总行高 + 总段间距 > 绘制区高 则超出一屏
if ((hasResolvedLength + resolving.length)*lineHeight + (current - this.curPage.end.pIndex)*spacing) > (window.innerHeight - 64 - 20)) {
// 找出最后一段的字偏移量
for (var j = 0; j < resolving.length && j + hasResolvedLength < totalRow; j++) {
offset += resolving[j].length;
hasResolved.push(withLineHeightResolving[j]);
}
// 记录最后一段的信息
this.curPage.end.pIndex = current;
this.curPage.end.offset = offset;
// 按段加入
hasResolvedByP.push(curParagraph.substring(0, offset))
// 一屏的内容
this.chapter.pdata[this.chapter.pcount] = hasResolved;
this.chapter.pdata2[this.chapter.pcount] = hasResolvedByP;
// 下一屏开始前要重置
hasResolved = [];
hasResolvedByP = [];
hasResolvedLength = 0;
firstLine = true;
this.chapter.pcount++;
} else {
// 将当前段落的分行数组合并到页面的数组里
hasResolved = hasResolved.concat(withLineHeightResolving);
hasResolvedLength += resolving.length
hasResolvedByP.push(resolving.join(''))
// 继续绘制下一个段落
current++;
}
}
/* 检查是否正常跳出满屏---如果没有 表示到达书尾,直接加入 */
if (hasResolvedLength) {
this.chapter.pdata[this.chapter.pcount] = hasResolved;
this.chapter.pdata2[this.chapter.pcount] = hasResolvedByP;
}
}
本文作者:关小峰
欢迎大家关注我们的站酷以及知乎账号:阅文体验设计YUX
后面思路怎么变成点点点啦