2016-10-25 38 views
7

我想創建的是一個小的畫布小部件,它允許用戶動態地在圖像上創建一個形狀,然後將其放置在引起他們興趣的區域之上,實際上它是一個熒光筆。在包含區域內移動動態創建的分組對象? (html5canvas - fabric.js)

問題是與添加縮放功能,因爲當我放大圖像,我想確保;

  1. 將動態創建的形狀拖動到圖像區域外的任何位置都沒有可能。 (完成 - ish,依靠第二步)
  2. 您不能將圖像拖出頁面視圖,畫布區域不能顯示空白區域。必須始終顯示圖像的一部分,並填充整個畫布區域。 (問題)

這裏有兩個例子,我已經制定了,這兩者都不正常工作;

First example - getBoundingRect does not update and is bound to the image

Second example - getBoundingRect does update and is bound to the grouped object

從鏈接的描述,你可以看到,我想我已經縮小了問題了,或者至少注意到與getBoundingRect如何運行腳本之間的關鍵區別。

第一個plunk似乎工作正常,直到您嘗試多次放大並以更大的縮放級別,然後它似乎開始竊聽(可能需要點擊幾下,有點亂,這是非常不一致)。第二個龐然大物非常緊張,並且效果不佳。

我一直在這個問題上停留了一個星期左右,而且我處於突破點!所以真的希望有人能指出我做錯了什麼?

下面的代碼段代表第一個plunk;

// creates group 

    var objs = canvas.getObjects(); 


    var group = new fabric.Group(objs, { 
    status: 'moving' 
    }); 

    // sets grouped object position 

    var originalX = active.left, 
    originalY = active.top, 
    mouseX = evt.e.pageX, 
    mouseY = evt.e.pageY; 

    active.on('moving', function(evt) { 
    group.left += evt.e.pageX - mouseX; 
    group.top += evt.e.pageY - mouseY; 
    active.left = originalX; 
    active.top = originalY; 
    originalX = active.left; 
    originalY = active.top; 
    mouseX = evt.e.pageX; 
    mouseY = evt.e.pageY; 


    // sets boundary area for image when zoomed 
    // THIS IS THE PART THAT DOESN'T WORK 

    active.setCoords(); 

    // SET BOUNDING RECT TO 'active' 

    var boundingRect = active.getBoundingRect(); 

    var zoom = canvas.getZoom(); 
    var viewportMatrix = canvas.viewportTransform; 

    // scales bounding rect when zoomed 

    boundingRect.top = (boundingRect.top - viewportMatrix[5])/zoom; 
    boundingRect.left = (boundingRect.left - viewportMatrix[4])/zoom; 
    boundingRect.width /= zoom; 
    boundingRect.height /= zoom; 

    var canvasHeight = canvas.height/zoom, 
     canvasWidth = canvas.width/zoom, 
     rTop = boundingRect.top + boundingRect.height, 
     rLeft = boundingRect.left + boundingRect.width; 

    // checks top left 

    if (rTop < canvasHeight || rLeft < canvasWidth) { 
     group.top = Math.max(group.top, canvasHeight - boundingRect.height); 
     group.left = Math.max(group.left, canvasWidth - boundingRect.width); 
    } 

    // checks bottom right 

    if (rTop > 0 || rLeft > 0) { 
     group.top = Math.min(group.top, canvas.height - boundingRect.height + active.top - boundingRect.top); 
     group.left = Math.min(group.left, canvas.width - boundingRect.width + active.left - boundingRect.left); 
    } 


    }); 

    // deactivates all objects on mouseup 

    active.on('mouseup', function() { 
    active.off('moving'); 
    canvas.deactivateAll().renderAll(); 

    }) 

    // sets group 

    canvas.setActiveGroup(group.setCoords()).renderAll(); 


} 

編輯:

我添加註釋,並試圖簡化在plunks代碼。

相關代碼在if (active.id == "img") {代碼塊內開始。

我已經把不相關的代碼作爲函數放在底部,它們很大程度上可以忽略。 (createNewRect() + preventRectFromLeaving()

爲了避免混淆,我已經移除了其中一個小塊。

讓我知道它是否有幫助,或者如果我應該嘗試進一步簡化。

謝謝!

+0

這是每個例子中的一噸代碼。有什麼方法可以將它簡化爲更簡單的代碼少的代碼?很難分辨每個人發生了什麼。 – StefanHayden

+2

@StefanHayden完成!代碼不會少,但是我已經移動了一些東西,並添加了評論以使其更容易,請讓我知道它是否易於閱讀? (也添加編輯部分提問)謝謝! – alexc

回答

4

我認爲這個分組與背景圖像的位置混亂。所以,我嘗試在圖像移動時移除組,然後手動更新矩形的位置。

它設置圖像的最後一個位置移動

var lastLeft = active.left, 
    lastTop = active.top; 

前,然後更新這些和矩形的位置,每一個圖像移動

rect.left += active.left - lastLeft; 
rect.top += active.top - lastTop; 
// I think this is needed so the rectangle can be re-selected 
rect.setCoords(); 
lastLeft = active.left; 
lastTop = active.top; 

由於圖像已經留時間在畫布內部,當圖像移動時,矩形也會留在畫布內。您編寫的其他代碼似乎工作正常。

http://plnkr.co/edit/6GGcUxGC7CjcyQzExMoK?p=preview