EPUB.js 解决图片裁剪问题(缩放问题)

在EPUB.js中,如果需要实现自动缩放,通过添加smartimages.js就可以实现图片自动缩放了,经过研究smartimages.js,发现,他可以是实现图片的缩放,但只能实现图片比需要显示的空间高时才会把图片缩小,因此,对于比较宽的图片就会出现截断的问题,经过对smartimages.js的修改我实现了通过smartimages.js实现EPUB.js电子书阅读的图片自动缩放。

EPUB.js的图片缩放是通过EPUB.js的Hooks功能实现的,smartimages.js的第一行代码就是:

EPUBJS.Hooks.register("beforeChapterDisplay").smartimages

EPUB.js会在每一章数据加载并开始显示是调用该函数。他原来的实现如下:

EPUBJS.Hooks.register("beforeChapterDisplay").smartimages = function(callback, renderer){
    var images = renderer.contents.querySelectorAll('img'),
        items = Array.prototype.slice.call(images),
        iheight = renderer.height,//chapter.bodyEl.clientHeight,//chapter.doc.body.getBoundingClientRect().height,
        oheight;

    if(renderer.layoutSettings.layout != "reflowable") {
        callback();
        return; //-- Only adjust images for reflowable text
    }

    items.forEach(function(item){
        
        function size() {
            var itemRect = item.getBoundingClientRect(),
                rectHeight = itemRect.height,
                top = itemRect.top,
                oHeight = item.getAttribute('data-height'),
                height = oHeight || rectHeight,
                newHeight,
                fontSize = Number(getComputedStyle(item, "").fontSize.match(/(\d*(\.\d*)?)px/)[1]),
                fontAdjust = fontSize ? fontSize / 2 : 0;
                
            iheight = renderer.contents.clientHeight;
            if(top < 0) top = 0;
    
            if(height + top >= iheight) {
            
                if(top < iheight/2) {
                    // Remove top and half font-size from height to keep container from overflowing
                    newHeight = iheight - top - fontAdjust;
                    item.style.maxHeight = newHeight + "px";
                    item.style.width= "auto";
                }else{
                    if(height > iheight) {
                        item.style.maxHeight = iheight + "px";
                        item.style.width= "auto";
                        itemRect = item.getBoundingClientRect();
                        height = itemRect.height;
                    }
                    item.style.display = "block";
                    item.style["WebkitColumnBreakBefore"] = "always";
                    item.style["breakBefore"] = "column";
                    
                }
                
                item.setAttribute('data-height', newHeight);
                
            }else{
                item.style.removeProperty('max-height');
                item.style.removeProperty('margin-top');
            }
        }
        
        item.addEventListener('load', size, false);
        
        renderer.on("renderer:resized", size);
        
        renderer.on("renderer:chapterUnloaded", function(){
            item.removeEventListener('load', size);
            renderer.off("renderer:resized", size);
        });
        
        size();

    });

    if(callback) callback();

}

从上面的代码可以看出,他只计算了高度,如果高度大于iheight,就修改图片的高度样式为特定的高度,并没有对高度进行处理。

经过分析,EPUB.js可以对图文进行分栏显示,如果我要对宽度超出的显示宽度的图片进行缩放,就需要知道显示区域的宽度。经过浏览器的调试工具和代码搜索,终于发现,EPUB.js的数据显示是通过一个叫做cloumnWidth的样式来决定显示区域的宽度的。

var columnWidth = parseInt(item.ownerDocument.documentElement.style[EPUBJS.core.prefixed('columnWidth')]);

这个columnWidth具体的名称是有EPUBJS的一个前缀决定的,可能是考虑到浏览器兼容的关系。为了得到图片的document对象,可以通过对象的ownerDocument获得文档对象,由于EPUB.js的显示是通过在内嵌的iframe组件显示的,所以需要得到显示的根文档对象,通过documentElement获得文档的元素,再取得其样式,这个样式通过prefixed的属性取得的,通过上面的代码就可以取到时间显示区域的宽度。

以下是代码修改部分(只贴了相关部分):

var columnWidth = parseInt(item.ownerDocument.documentElement.style[EPUBJS.core.prefixed('columnWidth')]);
if (item.clientWidth > item.clientHeight){
    //land image
    if (item.clientWidth > columnWidth){
        item.style.width = "100%";
        item.style.height = "auto";
        // recheck clientHeight
        if (item.clientHeight > top + iheight){
            item.style.width = "auto";
            item.style.height = "100%";
            item.align = "middle";
        }
    }else if (item.clientHeight > top + iheight){
        item.style.width = "auto";
        item.style.height = "100%";
    }else{
        item.style.width = "auto";
        item.style.height = "auto";
    }
}else{
    // port image
    if (item.clientHeight > top + iheight){
        item.style.width = "auto";
        item.style.height = "100%";
        //recheck clientWidth
        if (item.clientWidth > columnWidth){
            item.style.width = "100%";
            item.style.height = "auto";
        }
    }else if (item.clientWidth > columnWidth){
        item.style.width = "100%";
        item.style.height = "auto";
    }else{
        item.style.width = "auto";
        item.style.height = "auto";
    }
}
item.style.display = "block";
item.style.marginLeft = "auto";
item.style.marginRight = "auto";

上面的代码就是监测img组件的clientWidth和clientHeight来比较现实区域的高度和宽度的,在通过设定对象的宽度和高度样式。这里需要注意两点:

1. 要实现图像的缩放,其实很简单,比如,如果需要把一个图片的宽度设定到区域的100%,那么他的宽度就是显示区域的宽度,而高度设置为auto即可,这样图片的比例就可以得到保证,相反也是可以得,为了美观,我设置了图片居中,,把图片放在中间会比较好看些。注意:设置align为middle是无效的,需要设置display为block,再把marginLeft, marginRight样式修改为auto才可以然图片居中。

2. EPUB.js在调用该函数的时候,前面一次调用,img的clientWidth和clientHeight为0,后面一次的调用才会是图片的实际大小,为此,我在size函数的前面加上了一句:

function size() {
    // return while item has not client position
    if (item.clientWidth == 0 && item.clientHeight == 0) return;
    //...
}

为此完美解决了EPUB.js在图片显示时图片裁剪的问题

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 25
    评论
Vue是一种流行的JavaScript框架,而epub.js是一个用于在浏览器中呈现EPUB电子书的开源库。Vue和epub.js可以很好地结合使用,以创建动态和交互式的EPUB电子书阅读器。 在使用Vue时,可以使用其强大的组件化特性将epub.js集成到Vue应用程序中。通过将epub.js作为Vue组件的一部分,我们可以方便地管理和控制EPUB电子书的加载、显示和互动。 例如,可以创建一个名为EpubReader的Vue组件,该组件包含一个用于显示EPUB电子书内容的容器元素。在该组件的生命周期钩子中,可以使用epub.js提供的API方法加载和渲染EPUB电子书。同时,还可以使用Vue的数据绑定和事件监听来动态更新和响应EPUB电子书的变化。 在EpubReader组件中,可以通过将epub.js提供的方法与Vue模板和方法进行关联,实现一些功能,例如切换章节、搜索、标注和添加书签等。通过Vue的响应式特性,可以实现EPUB电子书内部的数据变化与Vue组件之间的交互和更新。 除了基本的EPUB电子书阅读功能外,还可以使用Vue的插件系统和其他Vue库,进一步扩展和定制EPUB电子书阅读器。例如,可以使用Vue Router来实现EPUB电子书的路由导航,以及使用Vuex来管理EPUB电子书的全局状态。 总之,Vue和epub.js的结合能够提供一种高效、灵活和可交互的EPUB电子书阅读体验。通过借助Vue的组件化和响应式特性,我们能够更方便地开发和定制EPUB电子书阅读器,满足用户对于电子书阅读的各种需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值