HTML5/SVG

SVG Editor 분석-2 객체 추가

Jundol 2015. 6. 12. 14:35



SVG Editor 에서 svg 영역 내에 그리기를 하면 하나의 요소가 추가되는게 가장 기본이자 첫걸음이다.
svgcanvas.js 의 상단영역에 구현이 되어있다.
초기 객체 클릭 시 svgEditor.js 파일에서 var mousedown = function 으로 구현되어있는 switch/case 문을 거치게되는데 각 case는 사용자가 어떤 타입의 요소를 그리려고 하는지에 대해 case로 나누어져 있으며 해당 case문에서 사용자가 선택한 타입에 대한 옵션값을 설정한 후 가상 이미지 즉, 드래그하는 영역을 짚어내게 된다. var mouseup = function 으로 구현되어있는 이벤트가 발동되면 똑같이 타입이 어떤건지 걸러낸 후 mousedown 에서의 영역을 가져와서 addSvgElementFromJson 에서 요소를 추가하게된다.

소스 코드
// Function: addSvgElementFromJson
// Create a new SVG element based on the given object keys/values and add it to the current layer
// The element will be ran through cleanupElement before being returned 
//
// Parameters:
// data - Object with the following keys/values:
// * element - tag name of the SVG element to create
// * attr - Object with attributes key-values to assign to the new element
// * curStyles - Boolean indicating that current style attributes should be applied first
//
// Returns: The new element
var addSvgElementFromJson = this.addSvgElementFromJson = function(data) {
	var shape = svgedit.utilities.getElem(data.attr.id);
	// if shape is a path but we need to create a rect/ellipse, then remove the path
	var current_layer = getCurrentDrawing().getCurrentLayer();
	if (shape && data.element != shape.tagName) {
		current_layer.removeChild(shape);
		shape = null;
	}
	if (!shape) {
		shape = svgdoc.createElementNS(NS.SVG, data.element);
		if (current_layer) {
			(current_group || current_layer).appendChild(shape);
		}
	}
	if (data.curStyles) {
		svgedit.utilities.assignAttributes(shape, {
			"fill": cur_shape.fill,
			"stroke": cur_shape.stroke,
			"stroke-width": cur_shape.stroke_width,
			"stroke-dasharray": cur_shape.stroke_dasharray,
			"stroke-linejoin": cur_shape.stroke_linejoin,
			"stroke-linecap": cur_shape.stroke_linecap,
			"stroke-opacity": cur_shape.stroke_opacity,
			"fill-opacity": cur_shape.fill_opacity,
			"opacity": cur_shape.opacity / 2,
			"style": "pointer-events:inherit"
		}, 100);
	}
	svgedit.utilities.assignAttributes(shape, data.attr, 100);
	svgedit.utilities.cleanupElement(shape);
	return shape;
};


위 소스코드에서 보면 svgedit.utilities.assinAttributes 에서 전달인자로 shape, 옵션객체, 100을 넘기게 되는데 옵션객체에서 fill , stroke , stroke-width 등등... 이 옵션 값들이 모두 객체 추가요소에 필요한 모음들이다. stroke 는 테두리와 추가 한 후 나오는 select 했다는 영역을 표시하는 것 같다.



svgedit.utilities.assignAttributes = function(node, attrs, suspendLength, unitCheck) {
	if(!suspendLength) {suspendLength = 0;}
	// Opera has a problem with suspendRedraw() apparently
	var handle = null;
	if (!svgedit.browser.isOpera()) {svgroot_.suspendRedraw(suspendLength);}

	var i;
	for (i in attrs) {
		var ns = (i.substr(0,4) === 'xml:' ? NS.XML :
			i.substr(0,6) === 'xlink:' ? NS.XLINK : null);

		if(ns) {
			node.setAttributeNS(ns, i, attrs[i]);
		} else if(!unitCheck) {
			node.setAttribute(i, attrs[i]);
		} else {
			svgedit.units.setUnitAttr(node, i, attrs[i]);
		}
	}
	if (!svgedit.browser.isOpera()) {svgroot_.unsuspendRedraw(handle);}
};

옵션객체로 넘긴 설정값들을 노드 요소에 attrbutes 로 추가한다. 여기서 node 는 그리기한 객체를 의미하고 그 객체에 attr 을 추가하는 형식으로 svg element 요소를 만들어낸다.
최종 결과물로 shpae 을 반환한다. ==> return shape;