new path tools, press alt for illustrator like capabilities
parent
4eaf876945
commit
21b09f88b5
|
@ -42,7 +42,7 @@ var segData = {
|
|||
|
||||
var pathFuncs = [];
|
||||
|
||||
var link_control_pts = true;
|
||||
var link_control_pts = false;
|
||||
|
||||
// Stores references to paths via IDs.
|
||||
// TODO: Make this cross-document happy.
|
||||
|
@ -196,6 +196,9 @@ svgedit.path.addCtrlGrip = function(id) {
|
|||
'display': "none",
|
||||
'r': svgedit.browser.isTouch() ? 15 : 3,
|
||||
'fill': "#4F80FF",
|
||||
'stroke': '#4F80FF',
|
||||
'stroke-opacity': 0,
|
||||
'stroke-width': '3',
|
||||
'cursor': 'move',
|
||||
'style': 'pointer-events:all',
|
||||
'xlink:title': uiStrings.pathCtrlPtTooltip
|
||||
|
@ -237,7 +240,7 @@ svgedit.path.getPointGrip = function(seg, update) {
|
|||
svgedit.path.getControlPoints = function(seg) {
|
||||
var item = seg.item;
|
||||
var index = seg.index;
|
||||
if(!("x1" in item) || !("x2" in item)) return null;
|
||||
if(!item || !("x1" in item) || !("x2" in item)) return null;
|
||||
var cpt = {};
|
||||
var pointGripContainer = svgedit.path.getGripContainer();
|
||||
|
||||
|
@ -468,7 +471,6 @@ svgedit.path.Segment.prototype.update = function(full) {
|
|||
|
||||
svgedit.path.Segment.prototype.move = function(dx, dy) {
|
||||
var item = this.item;
|
||||
|
||||
if(this.ctrlpts) {
|
||||
var cur_pts = [item.x += dx, item.y += dy,
|
||||
item.x1, item.y1, item.x2 += dx, item.y2 += dy];
|
||||
|
@ -512,14 +514,12 @@ svgedit.path.Segment.prototype.setLinked = function(num) {
|
|||
}
|
||||
|
||||
var item = seg.item;
|
||||
|
||||
item['x' + anum] = pt.x + (pt.x - this.item['x' + num]);
|
||||
item['y' + anum] = pt.y + (pt.y - this.item['y' + num]);
|
||||
item['x' + anum] = pt.x + pt.x - this.item['x' + num];
|
||||
item['y' + anum] = pt.y + pt.y - this.item['y' + num];
|
||||
|
||||
var pts = [item.x, item.y,
|
||||
item.x1, item.y1,
|
||||
item.x2, item.y2];
|
||||
|
||||
svgedit.path.replacePathSeg(seg.type, seg.index, pts);
|
||||
seg.update(true);
|
||||
};
|
||||
|
|
|
@ -388,10 +388,12 @@
|
|||
<label id="seg_type_label">Straight</label>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<label class="draginput checkbox" data-title="Link Control Points">
|
||||
<span>Linked Control Points</span>
|
||||
<div class="push_bottom"><input type="checkbox" id="tool_node_link" checked="checked" /></div>
|
||||
</label>
|
||||
-->
|
||||
|
||||
<div class="clearfix"></div>
|
||||
<div class="tool_button" id="tool_node_clone" title="Adds a node">Add Node</div>
|
||||
|
|
|
@ -89,6 +89,7 @@
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
var curPrefs = {}; //$.extend({}, defaultPrefs);
|
||||
var customHandlers = {};
|
||||
Editor.curConfig = curConfig;
|
||||
|
@ -2255,7 +2256,7 @@
|
|||
var convertToPath = function() {
|
||||
if (selectedElement != null) {
|
||||
svgCanvas.convertToPath();
|
||||
elems = svgCanvas.getSelectedElems()
|
||||
var elems = svgCanvas.getSelectedElems()
|
||||
svgCanvas.selectorManager.requestSelector(elems[0]).reset(elems[0])
|
||||
svgCanvas.selectorManager.requestSelector(elems[0]).selectorRect.setAttribute("display", "none");
|
||||
svgCanvas.setMode("pathedit")
|
||||
|
@ -2293,9 +2294,8 @@
|
|||
};
|
||||
|
||||
var linkControlPoints = function() {
|
||||
var linked = document.getElementById('tool_node_link').checked;
|
||||
console.log(linked);
|
||||
path.linkControlPoints(linked);
|
||||
// var linked = document.getElementById('tool_node_link').checked;
|
||||
// path.linkControlPoints(linked);
|
||||
}
|
||||
|
||||
var clonePathNode = function() {
|
||||
|
@ -4136,4 +4136,5 @@
|
|||
// Run init once DOM is loaded
|
||||
$(svgEditor.init);
|
||||
|
||||
|
||||
})();
|
|
@ -3260,7 +3260,6 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
|
|||
cur_properties.stroke_linejoin = selected.getAttribute("stroke-linejoin");
|
||||
cur_properties.stroke_linecap = selected.getAttribute("stroke-linecap");
|
||||
}
|
||||
|
||||
if (selected.tagName == "text") {
|
||||
cur_text.font_size = selected.getAttribute("font-size");
|
||||
cur_text.font_family = selected.getAttribute("font-family");
|
||||
|
@ -3272,8 +3271,16 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
|
|||
}
|
||||
// always recalculate dimensions to strip off stray identity transforms
|
||||
recalculateAllSelectedDimensions();
|
||||
|
||||
// if it was being dragged/resized
|
||||
if (real_x != r_start_x || real_y != r_start_y) {
|
||||
var isBotchedZoom = svgedit.browser.isGecko();
|
||||
r_start_x = isBotchedZoom ? r_start_x * current_zoom : r_start_x;
|
||||
r_start_y = isBotchedZoom ? r_start_y * current_zoom : r_start_y;
|
||||
var difference_x = Math.abs(real_x-r_start_x);
|
||||
var difference_y = Math.abs(real_y-r_start_y);
|
||||
|
||||
console.log(difference_x, difference_y)
|
||||
if (difference_y > 1 || difference_y > 1) {
|
||||
var len = selectedElements.length;
|
||||
for (var i = 0; i < len; ++i) {
|
||||
if (selectedElements[i] == null) break;
|
||||
|
@ -3407,7 +3414,7 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
|
|||
started = true;
|
||||
|
||||
var res = pathActions.mouseUp(evt, element, mouse_x, mouse_y);
|
||||
element = res.element
|
||||
element = res.element;
|
||||
keep = res.keep;
|
||||
break;
|
||||
case "pathedit":
|
||||
|
@ -3523,13 +3530,11 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
|
|||
var dblClick = function(evt) {
|
||||
var evt_target = evt.target;
|
||||
var parent = evt_target.parentNode;
|
||||
|
||||
// Do nothing if already in current group
|
||||
if(parent === current_group) return;
|
||||
|
||||
var mouse_target = getMouseTarget(evt);
|
||||
var tagName = mouse_target.tagName;
|
||||
|
||||
if(parent === current_group) return;
|
||||
|
||||
if(tagName === 'text' && current_mode !== 'textedit') {
|
||||
var pt = transformPoint( evt.pageX, evt.pageY, root_sctm );
|
||||
textActions.select(mouse_target, pt.x, pt.y);
|
||||
|
@ -4064,7 +4069,10 @@ var pathActions = canvas.pathActions = function() {
|
|||
|
||||
var current_path = null,
|
||||
drawn_path = null,
|
||||
hasMoved = false;
|
||||
hasMoved = false,
|
||||
stretchy = null;
|
||||
|
||||
this.lastCtrlPoint = [0, 0];
|
||||
|
||||
// This function converts a polyline (created by the fh_path tool) into
|
||||
// a path element and coverts every three line segments into a single bezier
|
||||
|
@ -4165,6 +4173,8 @@ var pathActions = canvas.pathActions = function() {
|
|||
}
|
||||
stretchy.setAttribute("display", "inline");
|
||||
|
||||
this.stretchy = stretchy;
|
||||
|
||||
var keep = null;
|
||||
|
||||
// if pts array is empty, create path element with M at current point
|
||||
|
@ -4183,6 +4193,7 @@ var pathActions = canvas.pathActions = function() {
|
|||
stretchy.setAttribute('d', ['M', mouse_x, mouse_y, mouse_x, mouse_y].join(' '));
|
||||
var index = subpath ? svgedit.path.path.segs.length : 0;
|
||||
svgedit.path.addPointGrip(index, mouse_x, mouse_y);
|
||||
svgedit.path.first_grip = null;
|
||||
}
|
||||
else {
|
||||
// determine if we clicked on an existing point
|
||||
|
@ -4218,9 +4229,12 @@ var pathActions = canvas.pathActions = function() {
|
|||
// then leave the path open
|
||||
// otherwise, close the path
|
||||
if (i <= 1 && len >= 2) {
|
||||
|
||||
// Create end segment
|
||||
var abs_x = seglist.getItem(0).x;
|
||||
var abs_y = seglist.getItem(0).y;
|
||||
var grip_x = svgedit.path.first_grip ? svgedit.path.first_grip[0]/current_zoom : seglist.getItem(0).x;
|
||||
var grip_y = svgedit.path.first_grip ? svgedit.path.first_grip[1]/current_zoom : seglist.getItem(0).y;
|
||||
|
||||
|
||||
var s_seg = stretchy.pathSegList.getItem(1);
|
||||
|
@ -4232,11 +4246,10 @@ var pathActions = canvas.pathActions = function() {
|
|||
abs_y,
|
||||
s_seg.x1 / current_zoom,
|
||||
s_seg.y1 / current_zoom,
|
||||
abs_x,
|
||||
abs_y
|
||||
grip_x,
|
||||
grip_y
|
||||
);
|
||||
}
|
||||
|
||||
var endseg = drawn_path.createSVGPathSegClosePath();
|
||||
seglist.appendItem(newseg);
|
||||
seglist.appendItem(endseg);
|
||||
|
@ -4250,8 +4263,8 @@ var pathActions = canvas.pathActions = function() {
|
|||
element = newpath;
|
||||
drawn_path = null;
|
||||
started = false;
|
||||
|
||||
if(subpath) {
|
||||
|
||||
if(svgedit.path.path.matrix) {
|
||||
remapElement(newpath, {}, svgedit.path.path.matrix.inverse());
|
||||
}
|
||||
|
@ -4268,6 +4281,7 @@ var pathActions = canvas.pathActions = function() {
|
|||
svgedit.path.path.selectPt();
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
// else, create a new point, update path element
|
||||
else {
|
||||
|
@ -4304,15 +4318,34 @@ var pathActions = canvas.pathActions = function() {
|
|||
x *= current_zoom;
|
||||
y *= current_zoom;
|
||||
|
||||
// set stretchy line to latest point
|
||||
// update everything to the latest point
|
||||
stretchy.setAttribute('d', ['M', x, y, x, y].join(' '));
|
||||
var pointGrip1 = svgedit.path.addCtrlGrip('1c1');
|
||||
var pointGrip2 = svgedit.path.addCtrlGrip('0c2');
|
||||
var ctrlLine = svgedit.path.getCtrlLine(1);
|
||||
var ctrlLine2 = svgedit.path.getCtrlLine(2);
|
||||
|
||||
pointGrip1.setAttribute('cx', x);
|
||||
pointGrip1.setAttribute('cy', y);
|
||||
pointGrip2.setAttribute('cx', x);
|
||||
pointGrip2.setAttribute('cy', y);
|
||||
|
||||
ctrlLine.setAttribute('x1', x);
|
||||
ctrlLine.setAttribute('x2', x);
|
||||
ctrlLine.setAttribute('y1', y);
|
||||
ctrlLine.setAttribute('y2', y);
|
||||
|
||||
ctrlLine2.setAttribute('x1', x);
|
||||
ctrlLine2.setAttribute('x2', x);
|
||||
ctrlLine2.setAttribute('y1', y);
|
||||
ctrlLine2.setAttribute('y2', y);
|
||||
|
||||
var index = num;
|
||||
if(subpath) index += svgedit.path.path.segs.length;
|
||||
svgedit.path.addPointGrip(index, x, y);
|
||||
}
|
||||
// keep = true;
|
||||
keep = true;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4346,7 +4379,82 @@ var pathActions = canvas.pathActions = function() {
|
|||
var parts = id.split('_')[1].split('c');
|
||||
var cur_pt = parts[0]-0;
|
||||
var ctrl_num = parts[1]-0;
|
||||
var num = ctrl_num;
|
||||
var path = svgedit.path.path.segs[cur_pt];
|
||||
|
||||
svgedit.path.path.selectPt(cur_pt, ctrl_num);
|
||||
|
||||
/////////////////
|
||||
//check if linked
|
||||
var seg, anum, pt;
|
||||
if (num == 2) {
|
||||
anum = 1;
|
||||
seg = path.next;
|
||||
if(!seg) return;
|
||||
pt = path.item;
|
||||
} else {
|
||||
anum = 2;
|
||||
seg = path.prev;
|
||||
if(!seg) return;
|
||||
pt = seg.item;
|
||||
}
|
||||
|
||||
var get_distance = function(pt1, pt2) {
|
||||
var a = pt1.x - pt2.x;
|
||||
var b = pt1.y - pt2.y;
|
||||
return Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
|
||||
}
|
||||
|
||||
function get_angle(pt1, pt2)
|
||||
{
|
||||
var dy = pt1.y - pt2.y;
|
||||
var dx = pt1.x - pt2.x;
|
||||
var theta = Math.atan2(dy, dx);
|
||||
return theta *= 180/Math.PI // rads to degs
|
||||
}
|
||||
|
||||
var grip = {
|
||||
x: path.item["x" + num],
|
||||
y: path.item["y" + num]
|
||||
}
|
||||
|
||||
if (num == 2) {
|
||||
var node = {
|
||||
x: path.item["x"],
|
||||
y: path.item["y"]
|
||||
}
|
||||
}
|
||||
else {
|
||||
var node = {
|
||||
x: seg.item["x"],
|
||||
y: seg.item["y"]
|
||||
}
|
||||
}
|
||||
|
||||
var pair = {
|
||||
x: seg.item["x" + anum],
|
||||
y: seg.item["y" + anum]
|
||||
}
|
||||
|
||||
var distance_between_node_grip = get_distance(grip, node);
|
||||
var distance_between_pair_grip = get_distance(pair, node);
|
||||
var angle_grip = Math.round(get_angle(grip, node), 0);
|
||||
var angle_pair = Math.round(get_angle(pair, node), 0);
|
||||
var is_complementary = (Math.abs(angle_grip - angle_pair) == 180);
|
||||
//console.log("distance: " + Math.abs(distance_between_node_grip - distance_between_pair_grip) + " angle = " + (Math.round(Math.abs(get_angle(grip, node)) + Math.abs(get_angle(pair, node)), 0)))
|
||||
if (Math.abs(distance_between_node_grip - distance_between_pair_grip) < 5 && is_complementary) {
|
||||
svgedit.path.setLinkControlPoints(true);
|
||||
svgedit.path.is_linked = true;
|
||||
}
|
||||
else {
|
||||
svgedit.path.setLinkControlPoints(false);
|
||||
svgedit.path.is_linked = false;
|
||||
}
|
||||
|
||||
|
||||
///////
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Start selection box
|
||||
|
@ -4365,20 +4473,21 @@ var pathActions = canvas.pathActions = function() {
|
|||
},
|
||||
mouseMove: function(evt, mouse_x, mouse_y) {
|
||||
hasMoved = true;
|
||||
var is_linked = !evt.altKey;
|
||||
if(current_mode === "path") {
|
||||
if(!drawn_path) return;
|
||||
var seglist = drawn_path.pathSegList;
|
||||
var index = seglist.numberOfItems - 1;
|
||||
var pointGrip1 = svgedit.path.addCtrlGrip('1c1');
|
||||
var pointGrip2 = svgedit.path.addCtrlGrip('0c2');
|
||||
|
||||
if(newPoint) {
|
||||
// First point
|
||||
// if(!index) return;
|
||||
|
||||
// Set control points
|
||||
var pointGrip1 = svgedit.path.addCtrlGrip('1c1');
|
||||
var pointGrip2 = svgedit.path.addCtrlGrip('0c2');
|
||||
var current_pointGrip2_x = pointGrip2.getAttribute('cx') || 0;
|
||||
var current_pointGrip2_y = pointGrip2.getAttribute('cy') || 0;
|
||||
var current_pointGrip2_x = pointGrip2.getAttribute('cx') / current_zoom || 0;
|
||||
var current_pointGrip2_y = pointGrip2.getAttribute('cy') / current_zoom || 0;
|
||||
|
||||
// dragging pointGrip1
|
||||
pointGrip1.setAttribute('cx', mouse_x);
|
||||
pointGrip1.setAttribute('cy', mouse_y);
|
||||
|
@ -4391,8 +4500,8 @@ var pathActions = canvas.pathActions = function() {
|
|||
var seg = seglist.getItem(index);
|
||||
var cur_x = mouse_x / current_zoom;
|
||||
var cur_y = mouse_y / current_zoom;
|
||||
var alt_x = (pt_x + (pt_x - cur_x));
|
||||
var alt_y = (pt_y + (pt_y - cur_y));
|
||||
var alt_x = (is_linked) ? (pt_x + (pt_x - cur_x)) : current_pointGrip2_x;
|
||||
var alt_y = (is_linked) ? (pt_y + (pt_y - cur_y)) : current_pointGrip2_y;
|
||||
|
||||
|
||||
pointGrip2.setAttribute('cx', alt_x * current_zoom);
|
||||
|
@ -4436,16 +4545,26 @@ var pathActions = canvas.pathActions = function() {
|
|||
last_x = firstCtrl[0]/current_zoom;
|
||||
last_y = firstCtrl[1]/current_zoom;
|
||||
}
|
||||
svgedit.path.replacePathSeg(6, index, [pt_x, pt_y, last_x, last_y, alt_x, alt_y], drawn_path);
|
||||
svgedit.path.replacePathSeg(6, index, [pt_x, pt_y, this.lastCtrlPoint[0]/current_zoom, this.lastCtrlPoint[1]/current_zoom, alt_x, alt_y], drawn_path);
|
||||
}
|
||||
} else {
|
||||
var stretchy = getElem("path_stretch_line");
|
||||
var stretchy = this.stretchy;
|
||||
if (stretchy) {
|
||||
var prev = seglist.getItem(index);
|
||||
var lastpoint = (evt.target.id === 'pathpointgrip_0');
|
||||
|
||||
var lastgripx = mouse_x;
|
||||
var lastgripy = mouse_y;
|
||||
|
||||
if (lastpoint && svgedit.path.first_grip) {
|
||||
lastgripx = svgedit.path.first_grip[0];
|
||||
lastgripy = svgedit.path.first_grip[1];
|
||||
}
|
||||
|
||||
if(prev.pathSegType === 6) {
|
||||
var prev_x = prev.x + (prev.x - prev.x2);
|
||||
var prev_y = prev.y + (prev.y - prev.y2);
|
||||
svgedit.path.replacePathSeg(6, 1, [mouse_x, mouse_y, prev_x * current_zoom, prev_y * current_zoom, mouse_x, mouse_y], stretchy);
|
||||
var prev_x = this.lastCtrlPoint[0]/current_zoom || prev.x + (prev.x - prev.x2);
|
||||
var prev_y = this.lastCtrlPoint[1]/current_zoom || prev.y + (prev.y - prev.y2);
|
||||
svgedit.path.replacePathSeg(6, 1, [mouse_x, mouse_y, prev_x * current_zoom, prev_y * current_zoom, lastgripx, lastgripy], stretchy);
|
||||
} else if(firstCtrl) {
|
||||
svgedit.path.replacePathSeg(6, 1, [mouse_x, mouse_y, firstCtrl[0], firstCtrl[1], mouse_x, mouse_y], stretchy);
|
||||
} else {
|
||||
|
@ -4467,7 +4586,10 @@ var pathActions = canvas.pathActions = function() {
|
|||
}, svgedit.path.path);
|
||||
var diff_x = mpt.x - pt.x;
|
||||
var diff_y = mpt.y - pt.y;
|
||||
|
||||
svgedit.path.path.dragging = [mouse_x, mouse_y];
|
||||
if (!is_linked || !svgedit.path.is_linked) svgedit.path.setLinkControlPoints(false);
|
||||
else svgedit.path.setLinkControlPoints(true);
|
||||
|
||||
if(svgedit.path.path.dragctrl) {
|
||||
svgedit.path.path.moveCtrl(diff_x, diff_y);
|
||||
|
@ -4475,11 +4597,11 @@ var pathActions = canvas.pathActions = function() {
|
|||
svgedit.path.path.movePts(diff_x, diff_y);
|
||||
}
|
||||
} else {
|
||||
//select
|
||||
svgedit.path.path.selected_pts = [];
|
||||
svgedit.path.path.eachSeg(function(i) {
|
||||
var seg = this;
|
||||
if(!seg.next && !seg.prev) return;
|
||||
|
||||
var item = seg.item;
|
||||
var rbb = rubberBox.getBBox();
|
||||
|
||||
|
@ -4501,7 +4623,15 @@ var pathActions = canvas.pathActions = function() {
|
|||
}
|
||||
},
|
||||
mouseUp: function(evt, element, mouse_x, mouse_y) {
|
||||
|
||||
var lastpointgrip = getElem('ctrlpointgrip_1c1');
|
||||
var firstpointgrip = getElem('ctrlpointgrip_0c2');
|
||||
if (lastpointgrip)
|
||||
this.lastCtrlPoint = [lastpointgrip.getAttribute('cx'), lastpointgrip.getAttribute('cy')];
|
||||
else
|
||||
this.lastCtrlPoint = [mouse_x, mouse_y]
|
||||
if (!svgedit.path.first_grip && firstpointgrip) {
|
||||
svgedit.path.first_grip = [firstpointgrip.getAttribute('cx'), firstpointgrip.getAttribute('cy')];
|
||||
}
|
||||
// Create mode
|
||||
if(current_mode === "path") {
|
||||
newPoint = null;
|
||||
|
@ -4710,6 +4840,7 @@ var pathActions = canvas.pathActions = function() {
|
|||
nums.push(pt + i);
|
||||
nums.push(pt + i + 1);
|
||||
}
|
||||
|
||||
svgedit.path.path.init().addPtsToSelection(nums);
|
||||
|
||||
svgedit.path.path.endChanges("Clone path node(s)");
|
||||
|
|
Loading…
Reference in New Issue