HTML5画布drawimage偏移和宽高比错误?

时间:2014-03-05 13:47:35

标签: javascript html5 image canvas

当我使用canvas上下文的drawImage(img,offsetx,offsety)函数时,我遇到了一个奇怪的问题。这是我的所作所为:

  1. 在调用drawImage之前创建画布上下文并获取图像源canvasContext.toDataUrl()
  2. 将图片来源应用到new Image()并使用prevImage.onload等待图片加载
  3. 问题是,当我绘制图像时,偏移似乎在x和y上都是关闭的。 这是一个例子。

    在: before drawing (original)

    在: after drawing (drawimage)

    我在原始图片上绘制原始图片(经过几次操作后,但我认为不相关)。请注意,拉丝后的质量也要降低。

    在我的初始化功能中,我有:

    editingPage = PDFView.pages[pageNumber - 1];
    canvasElement = editingPage.canvas;
    rect = canvasElement.getBoundingClientRect();
    imgSource = canvasElement.toDataURL();   
    

    以后(在用户互动之后),我有:

    prevImage = new Image(); //prevImage opnieuw initialiseren
    prevImage.src = imgSource; //Afbeelding source uit canvas in source van prevImage plaatsen (kopieren)
    prevImage.onload = function() {
        canvasContext.drawImage(prevImage, 0, 0);
    }
    

    这里有什么问题? 我很感激;)

    修改:整个脚本

    var canvas,
        canvasContext,
        rect,
        inserting = false,
        toolEnabled = false,
        pageNumber;
    
    var     prevX = 0,
        drawWidth = 0,
            prevY = 0,
       drawHeight = 0;
    
    var canvasElement = null,
            imgSource = null,
            prevImage = null,
          editingPage = null;
    
    var interactiveElements = new Array(),
                     pdfObj = null,
              pagesPrepared = false,
          pageNumberElement = null;
    
    function isToolEnabled() {
        return toolEnabled;
    }
    
    function initEditor() {
        pageNumber = PDFView.page;
        if (interactiveElements[pageNumber] === undefined) //Als nog geen array bestaat voor deze pagina...
            interactiveElements[pageNumber] = new Array(); //maak nieuwe array aan voor deze pagina
        if (toolEnabled) {
            editingPage = PDFView.pages[pageNumber - 1];
            disableEditor();
            toolEnabled = false;
        } else {
            editingPage = PDFView.pages[pageNumber - 1];
            canvasElement = editingPage.canvas;
            rect = canvasElement.getBoundingClientRect();
            imgSource = canvasElement.toDataURL();
            if (canvasElement !== null) {
                initializeCanvas(true);
                var textLayer = editingPage.el.childNodes[1];
                if (textLayer !== undefined)
                    textLayer.style.zIndex = 0;
            }
            toolEnabled = true;
        }
        return toolEnabled;
    }
    
    function initNewPageEditor() {
        if (toolEnabled && pageNumber !== PDFView.page) {
            if (interactiveElements[pageNumber] === undefined) //Als nog geen array bestaat voor deze pagina...
                interactiveElements[pageNumber] = new Array(); //maak nieuwe array aan
            rect = canvasElement.getBoundingClientRect(); //Dimensies van huidige pagina opvragen
            editingPage.el.style.zIndex = 1; //zIndex (weergaveniveau instellen op 1 (achter elementen / canvas)
            canvasElement.style.border = "0px solid blue"; //Visuele hint voor editor op deze pagina uitschakelen
    
            editingPage = PDFView.pages[PDFView.page - 1]; //Nieuwe pagina ophalen in viewer.js
            pageNumber = currentPageNumber; //currentPageNumber is variabele in viewer.js
            canvasElement = editingPage.canvas; //Canvas uit de PDFView pagina ophalen
            if (canvasElement !== null) { //Kan zijn dat deze nog niet bestaat
                initializeCanvas(true); //Canvas initializeren (true == mouse down/up events koppelen
                var textLayer = editingPage.el.childNodes[1]; //Wordt nu niet gebruikt, maar staat er toch voor later (eventueel)
                if (textLayer !== undefined) //Als deze bestaat
                    textLayer.style.zIndex = 0; //achter pagina plaatsen (niet selecteerbaar in editeermodus
            }
        }
    }
    
    function disableEditor() {
        editingPage.el.style.zIndex = 1;
        canvasElement.style.border = "0px solid blue";
        prevImage = null;
        imgSource = null;
        toolEnabled = false;
    }
    
    /*
     * Zal een backup afbeelding maken van het canvas om later opnieuw te resetten na het tekenen van een vierhoek
     * Bovendien worden mouseup & mousedown events aan het canvas gekoppeld
     * @param {bool} bindMouse
     * @returns {undefined}
     */
    function initializeCanvas(bindMouse) {
        canvasContext = canvasElement.getContext("2d"); //2d-context van het canvas opvragen
        if (bindMouse) {
            canvasElement.addEventListener("mousedown", function (e) {
                findxy('down', e);
            }, false);
            canvasElement.addEventListener("mouseup", function (e) {
                findxy('up', e);
            }, false);
        }
        canvasElement.style.border = "2px solid blue";
    }
    
    /*
     * Tekent de vierhoek aangegeven door de gebruiker ter referentie
     * @returns {undefined}
     */
    function draw() {
        canvasContext.beginPath();
        canvasContext.fillStyle="black";
        canvasContext.fillRect(prevX, prevY, drawWidth, drawHeight);
        canvasContext.closePath();
    }
    
    /*
     * Zal (indien niet aan het editeren) de x en y posities van de muis opvragen bij mouseup en mousedown
     * de getekende hoogte en breedte worden bij mouseup berekent en getekent.
     * een inputpopup vraagt een url (youtube of link) om in het vierhoek te plaatsen
     * Tenslotte wordt het canvas hersteld met de backup foto
     * @param {string} res
     * @param {evt} e
     * @returns {undefined}
     */
    function findxy(res, e) {
        if (!inserting) {
            if (res === 'down') {
                prevX = e.clientX - rect.left;
                prevY = e.clientY - rect.top;
            } else if (res === "up") {
                inserting = true;
                drawWidth = e.clientX - rect.left - prevX;
                drawHeight = e.clientY - rect.top - prevY;
                draw();
                var link=prompt("Geef een link of youtube url","www.google.be");
                if (link !== null && link.indexOf("watch?v=") !== -1)
                    insertYoutube(link);
                else if (link !== null)
                    insertLink(link);
    
                prevImage = new Image(); //prevImage opnieuw initialiseren
                prevImage.src = imgSource; //Afbeelding source uit canvas in source van prevImage plaatsen (kopieren)
                prevImage.onload = function() {
                    canvasContext.drawImage(prevImage, 0, 0);
                }
                inserting = false;
            }
        }
    }
    
    /*
     * Stelt een youtube speler samen om te tonen op het getekende vierhoek.
     * De marges worden opgezet in percentage om de juiste positioneren te behouden tijdens het zoomen.
     * @param {string} link
     * @returns {undefined}
     */
    function insertYoutube(link) {
        if (link.indexOf("www.youtube.com/watch?v=") === -1 || link.indexOf("www.youtube.com/watch?v=") === -1) {
            alert("!match"); //Als geen correcte youtube link gevonden wordt -> functie abreken.
            return;
        }
        var youtubeFrame = document.createElement("IFRAME"); //iframe element aanmaken
        youtubeFrame.className = "interactiveYoutube"; //Klasse voor opmaak
        youtubeFrame.width = (drawWidth / canvasElement.width * 100) + "%";
        youtubeFrame.height = (drawHeight / canvasElement.height * 100) + "%";
        youtubeFrame.style.position = "absolute"; //absolute positionering
        youtubeFrame.style.zIndex = 3; //Bovenste zichtbaarheidsniveau (boven canvas en pagina).
         //Hoogte en breedte berekenen in percentages
        youtubeFrame.style.marginLeft = drawWidth > 0 ? (prevX / canvasElement.width * 100) + "%" : Math.floor((prevX + drawWidth) / canvasElement.width * 100) + "%";
        youtubeFrame.style.marginTop = drawHeight > 0 ? (prevY / canvasElement.height * 100) + "%" : Math.floor((prevY + drawHeight) / canvasElement.height * 100) + "%";
        youtubeFrame.setAttribute("webkitallowfullscreen", '');
        youtubeFrame.setAttribute("mozallowfullscreen", '');
        youtubeFrame.setAttribute("allowfullscreen", ''); //Weergave van youtube clip in volledig scherm toelaten.
        youtubeFrame.src = '//www.youtube.com/embed/' + link.substring(32, link.length); //Youtubelink naar embedded link omzetten voor iframe.
        /*var youtubeFrame = "<iframe class='interactiveYoutube' width='" + drawWidth + "' height='" + drawHeight + "' src='//www.youtube.com/embed/" + video + "' frameborder='0' allowfullscreen " +
        "style='position:absolute;z-index:3;margin-left:" + marginLeft + "px;margin-top:" + marginTop + "px;' webkitallowfullscreen mozallowfullscreen></iframe>";*/
        editingPage.el.childNodes[0].appendChild(youtubeFrame); //iframe toevoegen aan pagina
        //https://www.youtube.com/watch?v=_L9JxYf80Kk
        interactiveElements.push("p"+PDFView.page+"id"+drawWidth+"."+drawHeight, youtubeFrame); //iframe toevoegen aan pagina
    }
    
    /*
     * maakt van het getekende vierhoek een link door een link als block te tonen met padding & marges.
     * De marges worden opgezet in percentage om de juiste positioneren te behouden tijdens het zoomen.
     * @param {string} link
     * @returns {undefined}
     */
    function insertLink(link) {
        if (link.indexOf("http://") === -1 || link.indexOf("https://") === -1) //Als http of https niet gedefinieerd is
                link = "http://" + link; //toevoegen... anders wordt het een link naar een pagina op dit domein.
        var marginLeft = Math.ceil((drawWidth > 0 ? prevX : prevX + drawWidth) / rect.width * 100);
        var marginTop = Math.ceil((drawHeight > 0 ? prevY : prevY + drawHeight) / rect.height * 100);
        var paddingWidth = Math.ceil(drawWidth / 2 / rect.width * 100);
        var paddingHeight = Math.ceil(drawHeight / 2 / rect.height * 100);
        var a = document.createElement("A");
        a.className="interactiveLink";
        a.href = link;
        a.style.display = "inline-block";
        a.style.position = "relative";
        a.style.zIndex = 3;
        a.style.marginLeft = marginLeft + "%";
        a.style.marginTop = marginTop + "%";
        a.style.padding = paddingHeight + "% " + paddingWidth + "%";
        /*var a = "<a class='interactiveLink' href='" + link + "' " + 
                "style='display:inline-block;position:absolute;z-index:3;" +
                "margin-left:"+ marginLeft +"%;margin-top:"+ marginTop +
                "%;padding:"+ paddingHeight +"% " + paddingWidth + "%;' />";*/
        editingPage.el.childNodes[0].appendChild(a);
        interactiveElements[PDFView.page]
    }
    
    function exportToHPUB() {
        pdfObj = { 0 : document.title };
        PDFView.page = 1;
        setTimeout(preparePageExport, 1500);
        //PDFView.renderAll();
    }
    
    function preparePageExport() {
        var container = PDFView.pages[PDFView.page - 1];
        var canvas = currEditingPage.canvas;
    
        if (canvas !== null) {
            var editable = container.cloneNode(true);
            imgSource = canvas.toDataURL();
            var a = "<img src='"+imgSource+"' style='z-index: 2' alt />";
            if (editable.childNodes[0].childNodes[0] !== undefined) {
                editable.childNodes[0].childNodes[0].remove();
                editable.childNodes[0].innerHTML += a;
            } else {
                editable.childNodes[1].childNodes[0].remove();
                editable.childNodes[1].innerHTML += a;
            }
            pdfObj[PDFView.page] = encodeURIComponent(editable.outerHTML);
            if (PDFView.page >= PDFView.pages.length) {
                EXPORTING = false;
                $.ajax({
                    url: 'http://localhost/pdf_js_server/public/',
                    type: 'POST',
                    data: { 'data': pdfObj },
                    async: false,
                    success: function(response){
                        alert("PDF geëxporteerd");
                    },
                    error: function(response) {
                        alert("Exporteren mislukt");
                    }
                });
            } else {
                PDFView.page++;
                setTimeout(preparePageExport, 1500);
            }
        }
    }
    

0 个答案:

没有答案