当我使用canvas上下文的drawImage(img,offsetx,offsety)函数时,我遇到了一个奇怪的问题。这是我的所作所为:
canvasContext.toDataUrl()
new Image()
并使用prevImage.onload
等待图片加载问题是,当我绘制图像时,偏移似乎在x和y上都是关闭的。 这是一个例子。
在:
在:
我在原始图片上绘制原始图片(经过几次操作后,但我认为不相关)。请注意,拉丝后的质量也要降低。
在我的初始化功能中,我有:
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);
}
}
}