一、创建项目
本项目采用的是extjs6.2,话说个人感觉ext4到ext6变化其实也并不大,大部分之前写的ext4的代码迁移至ext6上,并没有太大的问题,修改的地方并不多。至于前端项目是否采用cmd进行创建,看个人喜欢。本人是不太喜欢,虽然编译后代码做了压缩,但是页面耦合性太紧,很难共用某些页面(iframe)方式。废话少说,具体实现页面如下:
主要分两部分,左侧为导航栏(文档缩略图),右侧为文档主视图;
设计思想是把它作为单独模块,能够被其他页面所引用,所以建一个文件以document命名,其他页面要引用直接Ext.create或者iframe方式就行了。
document下的文件有:Config.js(配置页)、Document.js(主入口页)、PageIndex.js(左侧菜单栏)、PagePanel.js(主视图页)、PageSvg.js(主视图svg)、Statusbar.js(工具栏);
document.js负责装载PageIndex和PagePanel两个主件;
Ext.define('App.document.Document', {
extend: 'Ext.panel.Panel',
layout: 'border',
initComponent: function () {
var me = this;
me.pageIndex = Ext.create('App.document.PageIndex', {
region: 'west',
scrollable: 'y',
width: '10%',
split: true,
parent: me
});
me.pagePanel = Ext.create('App.document.PagePanel', {
region: 'center',
parent: me
});
me.items = [me.pageIndex, me.pagePanel];
me.callParent(arguments);
}
});
接着是左侧导航栏PageIndex.js,用容器Ext.container.Container装载Ext.Img和Ext.form.Label:
Ext.define('App.document.PageIndex', {
extend: 'Ext.panel.Panel',
requires: [
'Ext.Img',
'Ext.form.Label'
],
title: '文档页导航',
autoScroll: true,
layout: 'column',
frame: true,
collapsible: true,
currentPage: null,
load: function (doc) {
var me = this, pageList = [];
for (var i = 0; i < doc.total; i++) {
var url = url;
pageList[i] = Ext.create('Ext.container.Container', {
layout: 'column',
items: [
Ext.create('Ext.Img', {
margin: '10 15 10 15',
columnWidth: 1,
src: url
}),
Ext.create('Ext.form.Label', {
columnWidth: 1,
cls: 'PageCode',
text: (i + 1),
style: 'text-align:center'
})
],
columnWidth: 1,
margin: '20 40 20 20',
border: 2,
style: {
borderColor: 'red',
borderStyle: 'hidden'
}
});
}
me.add(pageList);
}
});
完成了左侧导航栏后,接着是主视图
PagePanel,投机取巧的方法是采用和左侧导航栏相同的方式实现,不过这里存在个问题,当页面多的时候,滑动会卡;因为本人会对主视图进行编辑等操作,故不用此方式,转而用svg的方式实现,同时为了避免卡顿,默认只显示两页,代码如下:
Ext.define('App.document.PagePanel', {
extend: 'Ext.panel.Panel',
layout: 'absolute',
frame: false,
autoScroll: true,
reality: null,
initComponent: function () {
var me = this;
me.bbar = me.statusbar = Ext.create('App.document.Statusbar', {});
me.callParent(arguments);
},
load: function (doc) {
var me = this;
me.doc = doc;
var next = me.body.first();
while (next) {
next.setSize(0, 0);
next = next.next();
}
me.pageMap = {};
for (var i = 0; i < doc.total; i++) {
me.pageMap[i] = Ext.create('App.document.PageSvg', {
canvas: me,
parent: me,
doc: doc,
page: i
});
}
}
});
PageSvg.js
Ext.define('App.document.PageSvg', {
hidden: true,
layers: null,
constructor: function (config) {
var me = this;
if (config) {
Ext.apply(me, config);
}
me.init();
},
init: function () {
var me = this;
me.layers = {};
me.body = me.canvas.body.createChild();
me.buildHTML();
},
getDPI: function () {
var dpiX, dpiY;
if (window.screen.deviceXDPI != undefined) {
dpiX = window.screen.deviceXDPI;
dpiY = window.screen.deviceYDPI;
} else {
var tmpNode = document.createElement("DIV");
tmpNode.style.cssText = "width:1in;height:1in;position:absolute;left:0px;top:0px;z-index:99;visibility:hidden";
document.body.appendChild(tmpNode);
dpiX = parseInt(tmpNode.offsetWidth);
dpiY = parseInt(tmpNode.offsetHeight);
tmpNode.parentNode.removeChild(tmpNode);
}
return dpiX === dpiY ? dpiX : {dpiX: dpiX, dpiY: dpiY};
},
buildHTML: function () {
var me = this, canvas = me.canvas, reality = canvas.reality, scale = me.parent.getPageScale();
var doc = me.doc, pageInfo = doc.children[me.page];
me.realHeight = (pageInfo.height * 2.54 / (pageInfo.ydpi || me.getDPI())).toFixed(2);
me.realWidth = (pageInfo.width * 2.54 / (pageInfo.xdpi || me.getDPI()));
var margin = (reality || canvas).getPageMargin() * scale, width = (reality || canvas).body.getWidth();
me.realWidth = parseInt(me.realWidth * me.getDPI() / 2.54);
width = width > me.realWidth ? width : me.realWidth;
var layer_name = 'page';
me.layers[layer_name] = {
tag: 'g',
name: layer_name,
children: [
{
tag: 'image',
width: pageInfo.width,
height: pageInfo.height,
style: 'border: 1px solid #000',
'xlink:href': url
}
]
};
var children = [];
for (var key in me.layers) {
children.push(me.layers[key]);
}
var svg = {
tag: 'svg',
width: (width * scale) - 40,
height: me.realHeight * scale + 'cm',
viewBox: '0 0 {width} {height}'.replace('{width}', pageInfo.width).replace('{height}', pageInfo.height),
preserveAspectRatio: 'xMidYMin meet',
style: 'margin:' + [margin, margin, margin, margin].join(' '),
children: me.hidden ? null : children
};
var svgHtml = Ext.DomHelper.markup(svg);
me.body.setHtml('');
me.body.setHtml(svgHtml);
me.svg = me.body.child('svg');
},
onScale: function () {
var me = this;
me.buildHTML();
},
show: function () {
var me = this;
me.hidden = false;
me.buildHTML();
},
hide: function () {
var me = this;
me.hidden = true;
me.buildHTML();
}
});
Statusbar.js
Ext.define('App.document.Statusbar', {
extend: 'Ext.toolbar.Toolbar',
initComponent: function () {
var me = this;
me.pageDisplay = Ext.create('Ext.form.Field', {
width: 100,
originValue: '第{page}/{pageTotal}' + '页'
});
me.items = ['->', me.pageDisplay, '->'];
me.callParent(arguments);
},
paging: function (page, total) {
var me = this;
me.pageDisplay.setValue(me.pageDisplay.originValue
.replace('{page}', page + 1)
.replace('{pageTotal}', total));
}
});
大概就是这样,还有一些点击触发事件,以及页面编辑的事件,可以在这里的基础上进行扩展;