资源描述
图书资源阅览之
web网页上TXT电子书阅览翻页效果展示研究
基于unity3d 可以很好的跟网页进行相互传递消息,故选择在web网页上先实现txt电子书翻页效果阅览,以供后续整合使用。
一、 web网页上翻页效果txt电子书实现主要涉及的内容和应用的技术有:
html、css、js脚本语言(网页中主要代码以js实现,其中关键的分页技术中应用了js正则表达式进行准确划分)、jquery(js的一个类库,方便的对网页文档对象进行访问、设置css样式、点击以及鼠标事件等系列事件的处理、网页元素的动态效果实现等)。
二、 web网页上翻页效果实现原理:
借鉴于网络上已有的一个jQuery.pagePeel.js实现卷页的原理(只是动画用的是flash组件)。与unity3d类比,网页document对象的window对象类似于unity3d的摄像机视野窗口。unity3d的GUI系统是二维的,在垂直于窗口的方向上有z-index值对不同纵深的GUI组件进行分层排布。而网页上的div等元素对象的排布显示同样是通过z-index来控制的。以左右两个div来作为当前左右页显示区域,默认z-index为0,在左区域的左下角和右区域的右下角各有两个不同z-index的div,一个div(id为trigger)默认style为z-index=1层次高于显示内容区域,display为block用来响应鼠标的进入和离开事件;另一个div(id为pagepeel)用来包含表示卷页效果的图片,默认情况下该div的z-index= 10层次高于trigger div层次和显示内容区域层次,但display值为none,所以默认是不显示的,不会阻隔trigger div感应鼠标事件。如下图(红色区域为鼠标事件感应区,橙色区域为卷页效果区):
以右下角翻页为例(翻至下一页)。当鼠标进入trigger div区域,pagepeel div display值变为block显示出来,并通过jquery的animate对pagepeel div的宽、高和左上角的绝对位置进行动态改变,形似卷起开始遮挡住内容区域部分内容。鼠标离开后则pagepeel div display值变为none不显示。如下图:
当在卷角处点击鼠标时,通过过jquery的animate使卷角区域向左上角变的更大,中途换掉pagepeel 图片为实际的书页即将被翻过的状态图片,然后开始改变当前页码值重新显示左右两个区域的内容。如下图(状态图片等待修改):
三、分页及翻页技术具体实现如下:
1)左右内容显示区、鼠标感应区、卷页显示区等区域定位:
$("#contentAreaLeft").css({"position":"absolute","width":contentAreaWidth,"height":contentAreaHeight,"left":contentAreaLeft_left,"top":contentAreatop,"color":"#77ff00","font-size":font_size,"line-height":line_height,"background-color":"#777777","font-family":"幼圆"});
$("#contentAreaRight").css({"position":"absolute","width":contentAreaWidth,"height":contentAreaHeight,"left":contentAreaRight_left,"top":contentAreatop,"color":"#77ff00","font-size":font_size,"line-height":line_height,"background-color":"#777777","font-family":"幼圆"});
$("#selectpage").css({"position":"absolute","left":document.body.offsetWidth*1/2-200,"top":contentAreatop+contentAreaHeight+font_size,"color":"#000000","font-size":font_size,"line-height":line_height,"background-color":"#ffffff"});
//left page peel css set
$("#pagePeel_area_left").css({"position":"absolute","width":pagePeelArealeft_Width,"height": pagePeelArealeft_height,"left":pagePeelAreaLeft_left,"top":pagePeelAreaLeft_top,"z-index":"10","display":"none"});
$("#TriggerArea_left").css({"position":"absolute","width":"300","height": "300","left":contentAreaLeft_left,"top":contentAreatop+contentAreaHeight-300,"z-index":"1","display":"block"});
//right page peel css set
$("#pagePeel_area_right").css({"position":"absolute","width":pagePeelArearight_Width,"height": pagePeelArearight_height,"left":pagePeelAreaRight_left,"top":pagePeelAreaRight_top,"z-index":"10","display":"none"});
$("#TriggerArea_right").css({"position":"absolute","width":"300","height": "300","left":contentAreaRight_left+contentAreaWidth-300,"top":contentAreatop+contentAreaHeight-300,"z-index":"1","display":"block"});
2)txt文件的载入:通过jquery的ajax异步载入指定url位置的txt文件。代码如下:
htmlobj= $.ajax({url:"康熙王朝.txt",async:true});
receivedTxt=htmlobj.responseText;
3)将接收到的txt文本根据回车符判断按段落数分为多个子文本块,避免文件过大时一开始对所有文本进行处理缓慢。代码如下:
temp=receivedTxt.split(/\n/);
//按段落数先分成几组
if(temp.length%paragraphsPergroup!=0){
groupsNum=parseInt(temp.length/paragraphsPergroup)+1
for(var i=0;i<groupsNum;i++){
if(i<groupsNum-1){
groups[i]=temp.slice(i*paragraphsPergroup,(i+1)*paragraphsPergroup);
}else{
groups[groupsNum-1]=temp.slice((groupsNum-1)*paragraphsPergroup,temp.length);
}
}
}else{
groupsNum=parseInt(temp.length/paragraphsPergroup);
for(var i=0;i<groupsNum;i++){
groups[i]=temp.slice(i*paragraphsPergroup,(i+1)*paragraphsPergroup);
}
}
4)document ready的时候(相当于unity3d的Start)将所有子文本快中的第一快进行处理,往pages中添加页。
//对当前组(元素为一个个字符串段落的数组)的所有段落进行处理
for(var i=0;i< groups[currentgroupIndex].length;i++){
//还原文本换行
groups[currentgroupIndex][i]+="<br />";
groups[currentgroupIndex][i]=groups[currentgroupIndex][i].replace(/[*]/g," ");//文本自带的一些*换为空格
//处理不够一整行的情况
if(getlength(groups[currentgroupIndex][i])<charsPerline){
//填空直到够整行
while(getlength(groups[currentgroupIndex][i])<charsPerline){
groups[currentgroupIndex][i]=groups[currentgroupIndex][i].replace(/(.{6}$)/," $1");
}
}else if(getlength(groups[currentgroupIndex][i])>charsPerline){//处理占多行的文本段
var _lines=parseInt(getlength(groups[currentgroupIndex][i])/charsPerline);
if(getlength(groups[currentgroupIndex][i])%charsPerline>0){
while(getlength(groups[currentgroupIndex][i])<(_lines+1)*charsPerline){
groups[currentgroupIndex][i]=groups[currentgroupIndex][i].replace(/(.{6}$)/," $1");
}
}
}
}
groupstr=groups[currentgroupIndex].join(" ");
currentgroupcharsNum=getlength(groupstr);
if(currentgroupcharsNum%charsPerpage!=0){
currentgrouppagesNum=parseInt(currentgroupcharsNum/charsPerpage)+1;
pagesNum=pages.push(substr_chn(groupstr, 0, charsPerpage));
for(var i=1;i<currentgrouppagesNum;i++){
var startindex=0;
for(var n=0;n<i;n++){
startindex+=pages[n+groupIndexpre].length;//初始groupIndexpre为0
}
if(i<currentgrouppagesNum-1){
pagesNum=pages.push(substr_chn(groupstr,startindex, charsPerpage));
}else{
pagesNum=pages.push(groupstr.substr(startindex));
}
}
}else {
currentgrouppagesNum=parseInt(currentgroupcharsNum/charsPerpage);
pagesNum=pages.push(substr_chn(groupstr, 0, charsPerpage));
for(var i=1;i<currentgrouppagesNum;i++){
var startindex=0;
for(var n=0;n<i;n++){
startindex+=pages[n+groupIndexpre].length;
}
pagesNum=pages.push(substr_chn(groupstr,startindex, charsPerpage));
}
}
leftAreaContent=pages[2*currentpagePairIndex-2];
rightAreaContent=pages[2*currentpagePairIndex-1];
$("#contentAreaLeft").html(leftAreaContent);
$("#contentAreaRight").html(rightAreaContent);
$("#pageIndexInput").val(currentpagePairIndex);
5)左右trigger div区域鼠标进入和离开事件对于卷角效果的实现:
//mouse events for right
$("#TriggerArea_right").hover(function(){
$("#pagePeel_area_right").css({"display":"block"});
$("#pagePeel_area_right").stop().animate({"width":"100","height": "100","left":contentAreaRight_left+contentAreaWidth-100,"top":contentAreatop+contentAreaHeight-100},500,function(){
});
},function(){
$("#pagePeel_area_right").stop().animate({"width":pagePeelArearight_Width,"height": pagePeelArealeft_height,"left":contentAreaRight_left+contentAreaWidth-pagePeelArearight_Width,"top":contentAreatop+contentAreaHeight-pagePeelArealeft_height},1000,function(){
$("#btn_right").css({"z-index":"-20","display":"none"});
});
$("#pagePeel_area_right").css({"display":"none"});
}
);
// mouse events for left
$("#TriggerArea_left").hover(function(){
$("#pagePeel_area_left").css({"display":"block"});
$("#pagePeel_area_left").stop().animate({"width":"100","height": "100","top":contentAreatop+contentAreaHeight-100},500,function(){
$("#btn_left").css({"z-index":"20","display":"block"});
});
},function(){
$("#pagePeel_area_left").stop().animate({"width":pagePeelArealeft_Width,"height": pagePeelArealeft_height,"top":contentAreatop+contentAreaHeight-pagePeelArealeft_height},1000,function(){
$("#btn_left").css({"z-index":"-20","display":"none"});
});
$("#pagePeel_area_left").css({"display":"none"});
}
);
6)往回翻页的处理(在左卷角区域点击鼠标时):
$("#pagePeel_area_left").click(function (){
if(currentpagePairIndex>=2){
isEnd=false;
indexOut=false;
document.getElementById('pagePeel_img_left').src="imgs/pagePeelleft_500.png";
$("#pagePeel_area_left").stop().animate({"width":contentAreaWidth+50,"height": contentAreaHeight+150,"top":contentAreatop+contentAreaHeight-(contentAreaHeight+150)},500,function(){
currentpagePairIndex-=1;
leftAreaContent=pages[2*currentpagePairIndex-2];
rightAreaContent=pages[2*currentpagePairIndex-1];
$("#contentAreaLeft").html(leftAreaContent);
$("#contentAreaRight").html(rightAreaContent);
$("#pageIndexInput").val(currentpagePairIndex);
$("#pagePeel_area_left").css({"position":"absolute","width":pagePeelArealeft_Width,"height": pagePeelArealeft_height,"left":pagePeelAreaLeft_left,"top":pagePeelAreaLeft_top,"z-index":"10","display":"none"});
document.getElementById('pagePeel_img_left').src="imgs/pagePeelleft_100.png";
});
}else {alert("已经是首页");}
});
7)往后翻页的处理(当前子文本快内容显示到末尾的时候对下一个子文本快进行处理,往pages中添加页),代码如下:
$("#pagePeel_area_right").click(function (){
//当前group所分的页数不够,需要新的group页添加进来
if(pagesNum<2*(currentpagePairIndex+1)){
if(currentgroupIndex<groupsNum-1){
currentgroupIndex+=1;
//对当前组(元素为一个个段落的字符串的数组)的所有段落进行处理
for(var i=0;i< groups[currentgroupIndex].length;i++){
//还原文本换行
groups[currentgroupIndex][i]+="<br />";
groups[currentgroupIndex][i]=groups[currentgroupIndex][i].replace(/[*]/g," ");//文本自带的一些*换为空格
//处理不够一整行的情况
if(getlength(groups[currentgroupIndex][i])<charsPerline){
//填空直到够整行
while(getlength(groups[currentgroupIndex][i])<charsPerline){
groups[currentgroupIndex][i]=groups[currentgroupIndex][i].replace(/(.{6}$)/," $1");
}
}else if(getlength(groups[currentgroupIndex][i])>charsPerline){//处理占多行的文本段
var _lines=parseInt(getlength(groups[currentgroupIndex][i])/charsPerline);
if(getlength(groups[currentgroupIndex][i])%charsPerline>0){
while(getlength(groups[currentgroupIndex][i])<(_lines+1)*charsPerline){
groups[currentgroupIndex][i]=groups[currentgroupIndex][i].replace(/(.{6}$)/," $1");
}
}
}
}
groupstr=groups[currentgroupIndex].join(" ");
currentgroupcharsNum=getlength(groupstr);
if(currentgroupcharsNum%charsPerpage!=0){
currentgrouppagesNum=parseInt(currentgroupcharsNum/charsPerpage)+1;
groupIndexpre=pagesNum;
//alert("组的页索引前缀"+groupIndexpre+ "当前组有"+currentgrouppagesNum+"页");
pagesNum=pages.push(substr_chn(groupstr, 0, charsPerpage));
for(var i=1;i<currentgrouppagesNum;i++){
var startindex=0;
for(var n=0;n<i;n++){
startindex+=pages[n+groupIndexpre].length;
}
if(i<currentgrouppagesNum-1){
pagesNum=pages.push(substr_chn(groupstr,startindex, charsPerpage));
}else{
pagesNum=pages.push(groupstr.substr(startindex));
}
}
}else {
currentgrouppagesNum=parseInt(currentgroupcharsNum/charsPerpage);
groupIndexpre=pagesNum;
alert(groupIndexpre);
pagesNum=pages.push(substr_chn(groupstr, 0, charsPerpage));
for(var i=1;i<currentgrouppagesNum;i++){
var startindex=0;
for(var n=0;n<i;n++){
startindex+=pages[n+groupIndexpre].length;
}
pagesNum=pages.push(substr_chn(groupstr,startindex, charsPerpage));
}
}
//添加新group页结束
}else{alert("当前已是末尾");
isEnd=true;
}
//alert("共"+pagesNum+"页");
}//判读当前组页不够的if end
//向后翻一页处理开始
if(isEnd!=true){
document.getElementById('pagePeel_img_right').src="imgs/pagePeelright_500.png";
$("#pagePeel_area_right").stop().animate({"width":contentAreaWidth+50,"height": contentAreaHeight+150,"left":contentAreaRight_left+contentAreaWidth-(contentAreaWidth+50),"top":contentAreatop+contentAreaHeight-(contentAreaHeight+150)},500,function(){
currentpagePairIndex+=1;
leftAreaContent=pages[2*currentpagePairIndex-2];
rightAreaContent=pages[2*currentpagePairIndex-1];
$("#contentAreaLeft").html(leftAreaContent);
$("#contentAreaRight").html(rightAreaContent);
$("#pageIndexInput").val(currentpagePairIndex);
$("#pagePeel_area_right").css({"position":"absolute","width":pagePeelArearight_Width,"height": pagePeelArearight_height,"left":pagePeelAreaRight_left,"top":pagePeelAreaRight_top,"z-index":"10","display":"none"});
document.getElementById('pagePeel_img_right').src="imgs/pagePeelright_100.png";
});//翻页animate结束
}
});//click end
8)直接跳转到指定页的处理(往前跳转判断是否到首页,往后跳转判断当前子文本快是否显示完和指定跳转的页码是否超出所有文本页码数),代码如下:
//跳转至指定页
$("#goto").click(function (){
gotoIndex= parseInt($("#pageIndexInput").val());
//往前跳转
if(gotoIndex<currentpagePairIndex&&gotoIndex>=1){
indexOut=false;
document.getElementById('pagePeel_img_left').src="imgs/pagePeelleft_500.png";
$("#pagePeel_area_left").stop().animate({"width":contentAreaWidth+50,"height": contentAreaHeight+150,"top":contentAreatop+contentAreaHeight-(contentAreaHeight+150)},500,function(){
currentpagePairIndex=gotoIndex;
leftAreaContent=pages[2*currentpagePairIndex-2];
rightAreaContent=pages[2*currentpagePairIndex-1];
$("#contentAreaLeft").html(leftAreaContent);
$("#contentAreaRight").html(rightAreaContent);
$("#pageIndexInput").val(currentpagePairIndex);
$("#pagePeel_area_left").css({"position":"absolute","width":pagePeelArealeft_Width,"height": pagePeelArealeft_height,"left":pagePeelAreaLeft_left,"top":pagePeelAreaLeft_top,"z-index":"10","display":"none"});
document.getElementById('pagePeel_img_left').src="imgs/pagePeelleft_100.png";
});
}else if(gotoIndex>currentpagePairIndex){
if(pagesNum<2*gotoIndex){
while(pagesNum<2*gotoIndex){
if(currentgroupIndex<groupsNum-1){
currentgroupIndex+=1;
//对当前组(元素为一个个段落的字符串的数组)的所有段落进行处理
for(var i=0;i< groups[currentgroupIndex].length;i++){
//还原文本换行
groups[currentgroupIndex][i]+="<br />";
groups[currentgroupIndex][i]=groups[currentgroupIndex][i].replace(/[*]/g," ");//文本自带的一些*换为空格
//处理不够一整行的情况
if(getlength(groups[currentgroupIndex][i])<charsPerline){
//填空直到够整行
while(getlength(groups[currentgroupIndex][i])<charsPerline){
groups[currentgroupIndex][i]=groups[currentgroupIndex][i].replace(/(.{6}$)/," $1");
}
}else if(getlength(groups[currentgroupIndex][i])>charsPerline){//处理占多行的文本段
var _lines=parseInt(getlength(groups[currentgroupIndex][i])/charsPerline);
if(getlength(groups[currentgroupIndex][i])%charsPerline>0){
while(getlength(groups[currentgroupIndex][i])<(_lines+1)*charsPerline){
groups[currentgroupIndex][i]=groups[currentgroupIndex][i].replace(/(.{6}$)/," $1");
}
}
}
}
groupstr=groups[currentgroupIndex].join(" ");
currentgroupcharsNum=getlength(groupstr);
if(currentgroupcharsNum%charsPerpage!=0){
currentgrouppagesNum=parseInt(currentgroupcharsNum/charsPerpage)+1;
groupIndexpre=pagesNum;
//alert("组的页索引前缀"+groupIndexpre+ "当前组有"+currentgrouppagesNum+"页");
pagesNum=pages.push(substr_chn(groupstr, 0, charsPerpage));
for(var i=1;i<currentgrouppagesNum;i++){
var startindex=0;
for(
展开阅读全文