EPUB.js 解決圖片裁剪問題(縮放問題)

在EPUB.js中,若是須要實現自動縮放,經過添加smartimages.js就能夠實現圖片自動縮放了,通過研究smartimages.js,發現,他能夠是實現圖片的縮放,但只能實現圖片比須要顯示的空間高時纔會把圖片縮小,所以,對於比較寬的圖片就會出現截斷的問題,通過對smartimages.js的修改我實現了經過smartimages.js實現EPUB.js電子書閱讀的圖片自動縮放。git

EPUB.js的圖片縮放是經過EPUB.js的Hooks功能實現的,smartimages.js的第一行代碼就是:github

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的屬性取得的,經過上面的代碼就能夠取到時間顯示區域的寬度。spa

如下是代碼修改部分(只貼了相關部分):prototype

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才能夠然圖片居中。code

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在圖片顯示時圖片裁剪的問題

相關文章
相關標籤/搜索