fabric.js/test/demo/centering_guidelines.js
kangax 33278ae20b Reorganize fabric.Element in such way so that centering and aligning guidelines could work together.
`fabric.Element#onObjectMove` callback is gone, replaced by "object:moved" event (which allows subscription to the event by multiple parties).
Similarly, `fabric.Element#onMouseUp` is replaced with "mouse:up" event, and `fabric.Element#afterRender` with "after:render" one.
The drawback of these events, as of now, is that it's not possible to determine which canvas instance fired which event --
in case of multiple canvas instances in a document, this could get hairy. Will probably fix it by introducing some kind of `Observable` mixin,
which would add "observe" and "fire" methods to `fabric.Element` itself.
2010-10-31 22:42:20 -04:00

79 lines
No EOL
2.4 KiB
JavaScript

/**
* Augments canvas by assigning to `onObjectMove` and `onAfterRender`.
* This kind of sucks because other code using those methods will stop functioning.
* Need to fix it by replacing callbacks with pub/sub kind of subscription model.
* (or maybe use existing fabric.util.fireEvent/observeEvent (if it won't be too slow))
*/
function initCenteringGuidelines(canvas) {
var canvasWidth = canvas.getWidth(),
canvasHeight = canvas.getHeight(),
canvasWidthCenter = canvasWidth / 2,
canvasHeightCenter = canvasHeight / 2,
canvasWidthCenterMap = { },
canvasHeightCenterMap = { },
centerLineMargin = 4,
centerLineColor = 'rgba(255,0,241,0.5)',
centerLineWidth = 1,
ctx = canvas.getContext();
for (var i = canvasWidthCenter - centerLineMargin, len = canvasWidthCenter + centerLineMargin; i <= len; i++) {
canvasWidthCenterMap[i] = true;
}
for (var i = canvasHeightCenter - centerLineMargin, len = canvasHeightCenter + centerLineMargin; i <= len; i++) {
canvasHeightCenterMap[i] = true;
}
function showVerticalCenterLine() {
showCenterLine(canvasWidthCenter + 0.5, 0, canvasWidthCenter + 0.5, canvasHeight);
}
function showHorizontalCenterLine() {
showCenterLine(0, canvasHeightCenter + 0.5, canvasWidth, canvasHeightCenter + 0.5);
}
function showCenterLine(x1, y1, x2, y2) {
ctx.save();
ctx.strokeStyle = centerLineColor;
ctx.lineWidth = centerLineWidth;
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
ctx.restore();
}
var observeEvent = fabric.util.observeEvent,
afterRenderActions = [ ],
isInVerticalCenter,
isInHorizontalCenter;
observeEvent('object:moved', function(e) {
object = e.memo.target;
isInVerticalCenter = object.get('left') in canvasWidthCenterMap,
isInHorizontalCenter = object.get('top') in canvasHeightCenterMap;
if (isInHorizontalCenter) {
object.set('top', canvasHeightCenter);
}
if (isInVerticalCenter) {
object.set('left', canvasWidthCenter);
}
});
observeEvent('after:render', function() {
if (isInVerticalCenter) {
showVerticalCenterLine();
}
if (isInHorizontalCenter) {
showHorizontalCenterLine();
}
});
observeEvent('mouse:up', function() {
// clear these values, to stop drawing guidelines once mouse is up
isInVerticalCenter = isInHorizontalCenter = null;
canvas.renderAll();
});
}