2016-01-24 87 views
2

在Fabric.js中,通過左鍵單擊,按住並移動鼠標,可以在畫布中移動對象。在這種情況下,選中的對象跟隨鼠標的光標,並且被觸發。釋放鼠標左鍵退出此模式。Fabric.js - 不按住鼠標按鈕移動對象

有沒有辦法改變這種行爲,並讓對象進入不同的事件模式?例如,點擊一次讓對象跟隨光標(並且讓object:moving正確觸發),然後再次單擊以釋放對象到最終位置?

我希望避免編寫這個從頭開始聽「鼠標移動」事件,因爲這已經實現,但只是觸發器進入/存在這種模式必須改變。

回答

3

我通過具有稱爲movedObject變量,它是null如果沒有對象被移動,幷包含一個對象,如果一個對象是移動實現這一點。如果在移動對象時單擊,則會將movedObject設置爲null。如果在不移動對象的情況下單擊,則會將movedObject設置爲對象,如果您單擊了一個對象,則爲

我添加聽者mouse:move它設置leftmovedObjecttop鼠標xy(減去movedObjectwidthheight/2)如果movedObjectnull

JSFiddle

代碼:

var canvas = new fabric.Canvas('canvas'); 
canvas.setWidth(300); 
canvas.setHeight(300); 
var circle = new fabric.Circle({ 
    radius: 30, 
    fill: '#f55', 
    top: 100, 
    left: 100 
}); 
canvas.add(circle); 
circle.hasControls = circle.hasBorders = circle.selectable = false; 

var movedObject = null; 
canvas.on({ 
    'mouse:down': function(e) { 
    //If an object is selected already it'll be unselected 
    if (movedObject !== null) { 
     movedObject = null; 
    } else { 
     //If no object was selected and a click occured on an object it'll now be selected 
     if (e.target) { 
     movedObject = e.target; 
     } 
    } 
    }, 
    'mouse:move': function(e) { 
    //Moving the object along with mouse cursor 
    if (movedObject !== null) { 
     movedObject.left = (e.e.clientX - movedObject.width/2); 
     movedObject.top = (e.e.clientY - movedObject.height/2); 
     movedObject.setCoords(); 
     canvas.renderAll(); 
    } 
    } 
}); 
+0

這正是我試圖避免。這將重新實現fabric.js中已有的大部分內容,增加開銷並且不能很好地與事件系統搭配使用。 – jpcgt

+0

@jpcgt嗯,我爲你做了,我不認爲有另一種方式.. – leroydev

+0

這可能是唯一的方法來做到這一點,而無需修改fabric.js中的代碼。我會給你的(因此我是投票)。但這不是問題的答案,而是在問題中明確提出的。爲了進一步闡明,這不會觸發「對象:移動」事件,例如,您必須手動觸發它,從而繼續複製代碼,增加開銷並使其難以維護。 – jpcgt

0

通過Fabric.js代碼去,其中對象被標記要移動的地方是在canvas.__on_mouse_down(e)其中要求在使用這種方法canvas._setupCurrentTransform(e, target)(僅發生)。這構建了一個對象並將其分配給canvas._currentTransform。這個對象反過來在canvas.__onMouseMove(e)中用於使用canvas._transformObject(e)實際移動所選對象。

問題是canvas.__onMouseUp(e)調用canvas._finalizeCurrentTransform(),所以拖動停在那裏。幸運的是,它之後也發射了「鼠標:向上」。因此,我們可以在回調覆蓋此:

var mydragging = false; 
canvas.on('mouse:up', function(o) { 
    if (mydragging) { 
    mydragging = false; 
    canvas.currentTransform = null; 
    } 
    else { 
    canvas._setupCurrentTransform(o.e, o.target); 
    mydragging = true; 
    } 
}); 

這使canvas在完全相同的狀態下按住鼠標按鈕向下拖動時的(之前引入驗證碼),因此所有的內置行爲保持包括射擊「對象:移動」的地方。

不幸的是canvas._currentTransformcanvas._setupCurrentTransform被標記爲私人的,不能被依賴。也許他們願意公開。

+0

以下是公開的請求:https://github.com/kangax/fabric.js/issues/2753 – jpcgt

相關問題