음 아마 비둘기보단 똑똑할꺼야
준돌 Jundol / 2018.02.27 13:49 / HTML5

Facebook 공유하기 했을때 이미지 or 제목 or 설명 새로고침 하는법

clear facebook debugger cache data

 

Facebook 을 제외한 여타 다른 SNS에는 별도의 페이지 meta 태그 데이터를 캐시하는 서버가 존재하지않는것같다.

매번 공유를 할 때마다 새로운 데이터를 읽어들이는것 같은데

페이스북만 페이지 메타 태그의 데이터를 캐시해서 공유할때 이미지나 설명 제목을 불러들이는 속도를 빠르게 유지하는것 같다.

 

페이스북에서는 디버거를 통해 새로고침을 하라고 하지만 디버거를 이용해도 같은 도메인에서는 페이지가 즉각 새로고침 되지 않는 문제가 있다.

 

https://developers.facebook.com/tools/debug/

페이스북 디버거 페이지

페이스북에서는 여기를 통해 새로고침 하라고 나오지만 내가봤을땐 분석툴 이상이하도 아닌것같다...

정보를 새로 가져오긴 하지만 캐시서버에는 바뀌지 않는다.

메타태그를 수정하고 공유를 다시 해봐도 새로운 메타태그 정보를 가져오지 못한다.

 

그래서 내가 찾은 방법은

1. 게시물을 공유한다.

2. 공유한 게시글의 우측 상단에 있는 점 3개를 누른다.

 

 

 

3. 공유 첨부 파일 새로 고침 클릭

 

 

4. 새로운 메타태그를 가진 게시글을 가지고 온다.(바로 뜨지않고 몇초간(2~3초?)의 시간이 걸린다.)

5. 저장을 누른다.

이렇게 하면 해당 게시글의 새로운 메타태그 정보가 캐시서버에 새로고침되는것같다.

 

* 추가로 페이스북에 공유할때 가져오는 메타 이미지 및 설명은 meta og:url 태그의 content 속성에 바인딩되어있는 페이지를 가져온다.

다른 SNS(트위터,카카오스토리등)는 공유할때 url의 페이지에서 메타태그를 뽑아온다.

페이스북만 meta og:url 을 제대로 바인딩해줘야한다.

준돌 Jundol / 2015.11.23 11:35 / HTML5/SVG

본 포스팅은 MDN에 있는 변역되지 않은 문서를 번역 봉사에 참여한 후 블로그에 옮겨놓는 포스팅 입니다.

SVG matrix interfaceEDIT

수많은 SVG 그래픽 오퍼레이션은 아래와 같은 2X3 행열을 활용하고있다.

[a c e]
[b d f]

아래와같이 3x3 행렬은 행렬간의 계산을 위한 목적으로 확장되어 만들어졌다.

[a c e]
[b d f]
[0 0 1]

SVGMatrix 수정하기위해 시도하면 예외를 던지도록 읽기전용으로만 설계되었다. 

인터페이스 개요

Also implementNone
Methods
Properties
  • float a
  • float b
  • float c
  • float d
  • float e
  • float f
Normative documentSVG 1.1 (2nd Edition)

프로퍼티EDIT

NameTypeDescription
afloatThe a component of the matrix.
bfloatThe b component of the matrix.
cfloatThe c component of the matrix.
dfloatThe d component of the matrix.
efloatThe e component of the matrix.
ffloatThe f component of the matrix.

 DOMException 와 코드 NO_MODIFICATION_ALLOWED_ERR 는 읽기전용 attribute 나 객체 자신이 읽기전용인 것들을 수정하려할 때 발생한다.

메소드EDIT

Name & ArgumentsReturnDescription
multiply(inSVGMatrixsecondMatrix)SVGMatrix행렬간 곱셈을 한다. 이 행렬은 다른 행렬과 곱셈을 하여 새로운 행렬을 반환합니다.
inverse()SVGMatrix

거꾸로 반전이 된 행렬을 반환합니다.

예외:

  • DOMException 와 코드  SVG_MATRIX_NOT_INVERTABLE 는 행렬이 거꾸로 되지 않을때 발생합니다.
translate(in floatx, in float y)SVGMatrix
행렬에 위치를 이동시키고 행렬을 반환합니다.
scale(in floatscaleFactor)SVGMatrix
인자값에 따라 동일한 비율로 변환한 후 행렬을 반환합니다.
scaleNonUniform(in float scaleFactorX, in floatscaleFactorY)SVGMatrix
인자값에 따라 동일하지않은 비율로 변환한 후 행렬을 반환합니다.
rotate(in floatangle)SVGMatrix
인자값에 따라 회전하여 행렬을 반환합니다.
(angle 은 각도입니다.)
rotateFromVector(in float x, in floaty)SVGMatrix

인자값에 따라 회전하여 행렬을 반환합니다.
회전각은 탄젠트(y/x) 에 (+, -) 되도록 되어있다. 방향을 벡터 (x,y) 로 되도록 하고싶다면 상수 혹은 음수를 사용하면 된다.(정확하지 않은 해석인 것 같습니다. 다른분의 해석을 기다리겠습니다.)

원문 : Post-multiplies a rotation transformation on the current matrix and returns the resulting matrix. The rotation angle is determined by taking (+/-) atan(y/x). The direction of the vector (x, y) determines whether the positive or negative angle value is used.

예외:

  •  DOMException 와 코드 SVG_INVALID_VALUE_ERR 전달인자 중 하나라도 유효하지 않은 값일경우 발생한다.
flipX()SVGMatrix
[-1 0 0 1 0 0] 으로 곱하여 변환한 행렬을 반환한다.
flipY()SVGMatrix
[1 0 0 -1 0 0] 으로 곱하여 변환한 행렬을 반환한다.
skewX(in floatangle)SVGMatrixx값으로 비스듬하게(왜곡하는) 움직인 행렬을 반환한다.
skewY(in floatangle)SVGMatrix
y값으로 비스듬하게(왜곡하는) 움직인 행렬을 반환한다.

브라우저 지원EDIT

FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support??9??

 

문서 태그 및 공헌자

 최종 변경: Hmmim


'HTML5 > SVG' 카테고리의 다른 글

[SVG] SVG matrix interface  (0) 2015.11.23
[SVG] preserveAspectRatio 고정종횡비  (0) 2015.10.19
[SVG] document.createElementNS  (0) 2015.10.05
SVG Editor 분석-3 Path 포인트 정의하기  (0) 2015.06.15
SVG pathsegType  (0) 2015.06.15
SVG Editor 분석-2 객체 추가  (0) 2015.06.12
준돌 Jundol / 2015.10.19 11:56 / HTML5/SVG





preserveAspectRatio 고정종횡비

고정종횡비란?

종횡비란 화면의 가로대 세로의 크기비율이라고 합니다. 고정종횡비는 가로세로비율의 크기를 고정시키는걸 고정종횡비라고 합니다.


SVG의 경우 이미지의 가로세로 사이즈변경 작업을 진행할때 고정종횡비로 인해 원하는 풀사이즈로의 가로세로 크기변경이 되지 않습니다.

width 속성과 height 속성을 분명히 변경하였는데 width 속성만 먹힌다거나 height 속성만 먹혀서 원하는 사이즈가 나오지않는다면 곤란하죠.

그런 문제를 해결하기위해 나온 속성이 preserveAspectRatio 속성 입니다.

MDN에 SVG 속성 명세에 따르면 preserveAspectRatio는 10개의 align 속성과 2개의 meetOrSlice 속성을 제공하고있습니다.

<align>

none : 고정종횡비를 해제하여 image의 width ,height 속성에 꽉 들어차게 합니다.

xMinYMin : x 최소값 y 최소값

xMidYMin : x 중간값 y 최소값

xMaxYMin : x 최대값 y 최소값

xMinYMid : x 최소값 y 중간값

xMidYMid : x 중간값 y 중간값

xMaxYMid : x 최대값 y 중간값

xMinYMax : x 최소값 y 최대값

xMidYMax : x 중간값 y 최대값

xMaxYMax : x 최대값 y 최대값


<meetOrSlice>

align 속성에 추가되는 속성으로 x y 가 만나거나 자르는 데 사용합니다.


만약 xMinYMax의 경우 width 의 맨왼쪽 과 height 의 맨 아래쪽 즉, x의 최소값과 y의 최대값이 만나는 지점까지 meet 속성을 사용하면 해당위치로 지정되게하고 slice 속성을 사용하면 해당 영역에서부터 잘라냅니다.


위 속성은 예제를 사용하여 보면 더욱 이해하기가 쉽습니다. 보통 고정종횡비를 해제하기위해 none 속성을 가장 많이 사용합니다.



See the Pen OyOBqv by Kang Jun (@shokio) on CodePen.


'HTML5 > SVG' 카테고리의 다른 글

[SVG] SVG matrix interface  (0) 2015.11.23
[SVG] preserveAspectRatio 고정종횡비  (0) 2015.10.19
[SVG] document.createElementNS  (0) 2015.10.05
SVG Editor 분석-3 Path 포인트 정의하기  (0) 2015.06.15
SVG pathsegType  (0) 2015.06.15
SVG Editor 분석-2 객체 추가  (0) 2015.06.12
준돌 Jundol / 2015.10.05 16:21 / HTML5/SVG



document.createElementNS

네임스페이스를 사용하여 새 Element 노드를 생성한다. SVG는 XHTML 언어이므로 동적으로 생성할때는 createElement 를 사용하면 안되고 createElementNS 를 사용해야 한다.

createElement 를 사용해서 동적 삽입할 경우 개발자도구의 태그에는 추가된것으로 보이지만, 실제로 화면에 그려지진 않는다.


element = document.createElementNS(namespaceURI, qualifiedName);

parameter

namespaceURI : 새 element 에 대한 네임스페이스를 가리키는 유일한 식별자다. 네임스페이스가 없다면 null이 할당된다.

qualifiedName: 새 element에 대한 완결된 이름. 


return 값

element : 지정된 name 과 namespace를 갖는 새로 생성된 Element 노드.


사용 예

 - 동적생성으로 SVG 를 삽입하고싶을때 사용할 수 있는 함수를 만들어보자

 - 동적으로 SVG 태그를 만들고 rect 를 svg에 붙이는 소스코드.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
(function(){
	NS = {
		HTML: 'http://www.w3.org/1999/xhtml',
        MATH: 'http://www.w3.org/1998/Math/MathML',
        SE: 'http://svg-edit.googlecode.com',
        SVG: 'http://www.w3.org/2000/svg',
        XLINK: 'http://www.w3.org/1999/xlink',
        XML: 'http://www.w3.org/XML/1998/namespace',
        XMLNS: 'http://www.w3.org/2000/xmlns/' // see http://www.w3.org/TR/REC-xml-names/#xmlReserved
	};

	SVG = document.createElementNS(NS.SVG, "svg");

	browser = {
		isOpera : function(){
			return !!window.opera;
		},
		supportsSelectors: function(){
			return !!SVG.querySelector;
		},
		supportsXpath: function(){
			return !!document.evaluate;
		}
	};

	if(browser.supportsSelectors()){
		getElem = function(id){
			return SVG.querySelector("#" + id);
		};
	} else if (browser.supportsXpath()){
		getElem = function (id) {
            // xpath lookup
            return domdoc_.evaluate(
                'svg:svg[@id="svgroot"]//svg:*[@id="' + id + '"]',
                domcontainer_,
                function () { return WPod.svgedit.NS.SVG; },
                9,
                null).singleNodeValue;
        };
	} else {
		getElem = function(id){
			return $(SVG).find('[id=' + id + ']')[0];
		};
	};

	assignAttributes = function(node, attrs, suspendLength){
		if(!suspendLength){
			suspendLength = 0;
		}

		var handle = null;

		if(!browser.isOpera()){
			SVG.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 {
				node.setAttribute(i, attrs[i]);
			}
		}

		if(browser.isOpera()) {
			SVG.unsuspendRedraw(handle);
		}
	}

	addSvgElementFromJson = function(data){
		var shape = getElem(data.attr.id);

		if(shape && data.element != shape.tagName){
			shape = null;
		}

		if(!shape){
			shape = document.createElementNS(NS.SVG, data.element);
		}
		assignAttributes(shape, data.attr, 100);
		return shape;
	}

	var svg = addSvgElementFromJson({
		"element":"svg",
		"attr":{
			"width": 500,
			"height": 500,
			"border": "solid 1px #000000"
		}
	});

	document.body.appendChild(svg);

	// 사용법
	var rect = addSvgElementFromJson({
		"element": "rect",
		"attr": {
			"id": "svg_rect",
			"x": 10,
			"y": 10,
			"width": 100,
			"height": 100,
			"fill": "red",
			"stroke": "solid"
		}
	});

	svg.appendChild(rect);
})();




'HTML5 > SVG' 카테고리의 다른 글

[SVG] SVG matrix interface  (0) 2015.11.23
[SVG] preserveAspectRatio 고정종횡비  (0) 2015.10.19
[SVG] document.createElementNS  (0) 2015.10.05
SVG Editor 분석-3 Path 포인트 정의하기  (0) 2015.06.15
SVG pathsegType  (0) 2015.06.15
SVG Editor 분석-2 객체 추가  (0) 2015.06.12
준돌 Jundol / 2015.06.15 12:01 / HTML5/SVG



SVG Editor 에서는 SVG 에디터 답게 SVG의 패스포인트를 직접 수정할 수 있다. path 의 경우 객체에 마우스를 두번 클릭하면 자동적으로 path 포인트를 따낸다. 하지만 rect나 polyline , ellipse같은 경우 상단 메뉴에서 convert to path 로 변경하면 type 을 path로 변경하면서 중요 포인트 (각) 를 path 포인트로 짚어낸다.

태그 자체를 path 로 변경하고 d 를 attribute 로 추가하여 d의 path 포인트를 따내니 정말 훌륭하다.

새삼 이세상에는 진짜 외계인을 옆에 두고 고문하면서 개발하는 개발자들이 많다는걸 느낀다.

각설하고, path 로 변경되면서 각 path 포인트를 직접 수정할 수 있도록 하는데 그 과정의 로직을 정리해본다.

convert to path 버튼을 눌러 path로 변경된 이후 다시 클릭하면 mousedown 이벤트가 발생한다.


var mouseUp = function(evt) { if (evt.button === 2) {return;} var tempJustSelected = justSelected; justSelected = null; if (!started) {return;} var pt = svgedit.math.transformPoint(evt.pageX, evt.pageY, root_sctm), mouse_x = pt.x * current_zoom, mouse_y = pt.y * current_zoom, x = mouse_x / current_zoom, y = mouse_y / current_zoom, element = svgedit.utilities.getElem(getId()), keep = false; var real_x = x; var real_y = y; // TODO: Make true when in multi-unit mode var useUnit = false; // (curConfig.baseUnit !== 'px'); started = false; var attrs, t; switch (current_mode) { // intentionally fall-through to select here case "resize": case "multiselect": if (rubberBox != null) { rubberBox.setAttribute("display", "none"); curBBoxes = []; } current_mode = "select"; case "select": if (selectedElements[0] != null) { // if we only have one selected element if (selectedElements[1] == null) { // set our current stroke/fill properties to the element's var selected = selectedElements[0]; switch ( selected.tagName ) { case "g": case "use": case "image": case "foreignObject": break; default: cur_properties.fill = selected.getAttribute("fill"); cur_properties.fill_opacity = selected.getAttribute("fill-opacity"); cur_properties.stroke = selected.getAttribute("stroke"); cur_properties.stroke_opacity = selected.getAttribute("stroke-opacity"); cur_properties.stroke_width = selected.getAttribute("stroke-width"); cur_properties.stroke_dasharray = selected.getAttribute("stroke-dasharray"); 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"); } selectorManager.requestSelector(selected).showGrips(true); // This shouldn't be necessary as it was done on mouseDown... // call("selected", [selected]); } // 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 i, len = selectedElements.length; for (i = 0; i < len; ++i) { if (selectedElements[i] == null) {break;} if (!selectedElements[i].firstChild) { // Not needed for groups (incorrectly resizes elems), possibly not needed at all? selectorManager.requestSelector(selectedElements[i]).resize(); } } } // no change in position/size, so maybe we should move to pathedit else { t = evt.target; if (selectedElements[0].nodeName === "path" && selectedElements[1] == null) {                          // 아래 pathActions.select로 넘어간다. pathActions.select(selectedElements[0]); } // if it was a path // else, if it was selected and this is a shift-click, remove it from selection else if (evt.shiftKey) { if (tempJustSelected != t) { canvas.removeFromSelection([t]); } } } // no change in mouse position // Remove non-scaling stroke if (svgedit.browser.supportsNonScalingStroke()) { var elem = selectedElements[0]; if (elem) { elem.removeAttribute('style'); svgedit.utilities.walkTree(elem, function(elem) { elem.removeAttribute('style'); }); } } } return;

selectedElements 가 사용자가 미리 selete 해놓았던 path 객체가 된다.

해당 path 객체를 가지고 select 를 거친 후 toEditMode 로 target을 가지고 들어간다.


		select: function(target) {
			if (current_path === target) {
				pathActions.toEditMode(target);
				current_mode = "pathedit";
			} // going into pathedit mode
			else {
				current_path = target;
			}	
		},


그다음 current_path 가 target 즉 최근에 선택한 path 가 가져온 target 과 맞는 요소인지 검사한다. 즉, 미리 선택된 요소가 path 이고 그 path 요소가 지금 선택해서 가지고 들어온 target과 동일한 요소라는게 판명되면 pathActions.toEditMode로 간다.


toEditMode: function(element) {
			svgedit.path.path = svgedit.path.getPath_(element);
			current_mode = "pathedit";
			clearSelection();
			svgedit.path.path.show(true).update();
			svgedit.path.path.oldbbox = svgedit.utilities.getBBox(svgedit.path.path.elem);
			subpath = false;
		},


처음 path값을 가져오므로 path를 init(초기화) 해야한다. getPath_ 메소드로 이동하는데 element 파라미터는 아직 target 이다.

path.js 에서 path를 init 한다.

파라미터 elem은 넘겨받은 target이다

svgedit.path.getPath_ = function(elem) {
	var p = pathData[elem.id];
	if (!p) {
		p = pathData[elem.id] = new svgedit.path.Path(elem);
	}
	return p;
};


svgedit.path.Path = function(elem) {
	if (!elem || elem.tagName !== 'path') {
		throw 'svgedit.path.Path constructed without a  element';
	}

	this.elem = elem;
	this.segs = [];
	this.selected_pts = [];
	svgedit.path.path = this;

	this.init();
};

// Reset path data
svgedit.path.Path.prototype.init = function() {
	// Hide all grips, etc
	$(svgedit.path.getGripContainer()).find('*').attr('display', 'none');
	var segList = this.elem.pathSegList;
	var len = segList.numberOfItems;
	this.segs = [];
	this.selected_pts = [];
	this.first_seg = null;

	// Set up segs array
	var i;
	for (i = 0; i < len; i++) {
		var item = segList.getItem(i);
		var segment = new svgedit.path.Segment(i, item);
		segment.path = this;
		this.segs.push(segment);
	}

	var segs = this.segs;
	var start_i = null;

	for (i = 0; i < len; i++) {
		var seg = segs[i];
		var next_seg = (i+1) >= len ? null : segs[i+1];
		var prev_seg = (i-1) < 0 ? null : segs[i-1];
		var start_seg;
		if (seg.type === 2) {
			if (prev_seg && prev_seg.type !== 1) {
				// New sub-path, last one is open,
				// so add a grip to last sub-path's first point
				start_seg = segs[start_i];
				start_seg.next = segs[start_i+1];
				start_seg.next.prev = start_seg;
				start_seg.addGrip();
			}
			// Remember that this is a starter seg
			start_i = i;
		} else if (next_seg && next_seg.type === 1) {
			// This is the last real segment of a closed sub-path
			// Next is first seg after "M"
			seg.next = segs[start_i+1];

			// First seg after "M"'s prev is this
			seg.next.prev = seg;
			seg.mate = segs[start_i];
			seg.addGrip();
			if (this.first_seg == null) {
				this.first_seg = seg;
			}
		} else if (!next_seg) {
			if (seg.type !== 1) {
				// Last seg, doesn't close so add a grip
				// to last sub-path's first point
				start_seg = segs[start_i];
				start_seg.next = segs[start_i+1];
				start_seg.next.prev = start_seg;
				start_seg.addGrip();
				seg.addGrip();

				if (!this.first_seg) {
					// Open path, so set first as real first and add grip
					this.first_seg = segs[start_i];
				}
			}
		} else if (seg.type !== 1){
			// Regular segment, so add grip and its "next"
			seg.addGrip();

			// Don't set its "next" if it's an "M"
			if (next_seg && next_seg.type !== 2) {
				seg.next = next_seg;
				seg.next.prev = seg;
			}
		}
	}
	return this;
};


init 메소드를 거치면서 seg 를 정의한다. seg 는 path point 이다. seglist 는 path point를 모아놓은 list가 된다. 하단 for 문의 if else if 문을 거치면서 각 path point 를 직접 객체에 포인트를 그리게 된다. segtype 과 next segtype 을 구분하면서 객체의 path point 사이의 line 색상 을 추가하고 마지막으로 초기 default 로 지정될 path point 사이의 path line 을 제외한 나머지 line들을 display none 상태로 처리하여 마무리한다. clearSelection 은 selection point 진한 파란색 포인트를 안보이는 상태로 바꾼다.



addGrip() 부분

잡는 부분 즉, pathpoint를 잡아서 끌어당길 수 있는 포인트를 정의한다.

getPointGrip 와 getControlPoints 는 각각 포인트를 정의한다.

getSegSelector 는 라인을 지정 정의한다. (segLine)

HTML DOM 구조에서는 g태그의 id는 pathpointgrip_container 이다.
svgedit.path.Segment.prototype.addGrip = function() {
	this.ptgrip = svgedit.path.getPointGrip(this, true);
	this.ctrlpts = svgedit.path.getControlPoints(this, true);
	this.segsel = svgedit.path.getSegSelector(this, true);
};

svgedit.path.getPointGrip = function(seg, update) {
	var index = seg.index;
	var pointGrip = svgedit.path.addPointGrip(index);

	if (update) {
		var pt = svgedit.path.getGripPt(seg);
		svgedit.utilities.assignAttributes(pointGrip, {
			'cx': pt.x,
			'cy': pt.y,
			'display': 'inline'
		});
	}

	return pointGrip;
};


svgedit.path.getControlPoints = function(seg) {
	var item = seg.item;
	var index = seg.index;
	if (!('x1' in item) || !('x2' in item)) {return null;}
	var cpt = {};
	var pointGripContainer = svgedit.path.getGripContainer();

	// Note that this is intentionally not seg.prev.item
	var prev = svgedit.path.path.segs[index-1].item;

	var seg_items = [prev, item];

	var i;
	for (i = 1; i < 3; i++) {
		var id = index + 'c' + i;

		var ctrlLine = cpt['c' + i + '_line'] = svgedit.path.getCtrlLine(id);

		var pt = svgedit.path.getGripPt(seg, {x:item['x' + i], y:item['y' + i]});
		var gpt = svgedit.path.getGripPt(seg, {x:seg_items[i-1].x, y:seg_items[i-1].y});

		svgedit.utilities.assignAttributes(ctrlLine, {
			'x1': pt.x,
			'y1': pt.y,
			'x2': gpt.x,
			'y2': gpt.y,
			'display': 'inline'
		});

		cpt['c' + i + '_line'] = ctrlLine;

		// create it
		var pointGrip = cpt['c' + i] = svgedit.path.addCtrlGrip(id);

		svgedit.utilities.assignAttributes(pointGrip, {
			'cx': pt.x,
			'cy': pt.y,
			'display': 'inline'
		});
		cpt['c' + i] = pointGrip;
	}
	return cpt;
};


svgedit.path.getSegSelector = function(seg, update) {
	var index = seg.index;
	var segLine = svgedit.utilities.getElem('segline_' + index);
	if (!segLine) {
		var pointGripContainer = svgedit.path.getGripContainer();
		// create segline
		segLine = document.createElementNS(NS.SVG, 'path');
		svgedit.utilities.assignAttributes(segLine, {
			'id': 'segline_' + index,
			'display': 'none',
			'fill': 'none',
			'stroke': '#0FF',
			'stroke-width': 2,
			'style':'pointer-events:none',
			'd': 'M0,0 0,0'
		});
		pointGripContainer.appendChild(segLine);
	}

	if (update) {
		var prev = seg.prev;
		if (!prev) {
			segLine.setAttribute('display', 'none');
			return segLine;
		}

		var pt = svgedit.path.getGripPt(prev);
		// Set start point
		svgedit.path.replacePathSeg(2, 0, [pt.x, pt.y], segLine);

		var pts = svgedit.path.ptObjToArr(seg.type, seg.item, true);
		var i;
		for (i = 0; i < pts.length; i += 2) {
			pt = svgedit.path.getGripPt(seg, {x:pts[i], y:pts[i+1]});
			pts[i] = pt.x;
			pts[i+1] = pt.y;
		}

		svgedit.path.replacePathSeg(seg.type, 1, pts, segLine);
	}
	return segLine;
};


'HTML5 > SVG' 카테고리의 다른 글

[SVG] preserveAspectRatio 고정종횡비  (0) 2015.10.19
[SVG] document.createElementNS  (0) 2015.10.05
SVG Editor 분석-3 Path 포인트 정의하기  (0) 2015.06.15
SVG pathsegType  (0) 2015.06.15
SVG Editor 분석-2 객체 추가  (0) 2015.06.12
SVG Editor 분석-1 [DOM 구조파악]  (0) 2015.06.10
준돌 Jundol / 2015.06.15 11:25 / HTML5/SVG



SVG DOM 의 pathsegType 을 이용하면 각 path 의 attribute 에 따라 실행을 정의할 수 있다.

SVG Editor 에서 path point 정의를 내릴 때 pathsegType 을 이용해서 각 포인트 타입 별로 실행은 제어한다.

M , L , Z 등등 타입을 숫자로 분류해서 구분한다.

Interface SVGPathSeg

single segment 는 하나의 path data 의 설명에 부합한다.

IDL Definition


interface SVGPathSeg {
  // Path Segment Types
  const unsigned short kSVG_PATHSEG_UNKNOWN                      = 0;  // ?
  const unsigned short kSVG_PATHSEG_CLOSEPATH                    = 1;  // z
  const unsigned short kSVG_PATHSEG_MOVETO_ABS                   = 2;  // M
  const unsigned short kSVG_PATHSEG_MOVETO_REL                   = 3;  // m
  const unsigned short kSVG_PATHSEG_LINETO_ABS                   = 4;  // L
  const unsigned short kSVG_PATHSEG_LINETO_REL                   = 5;  // l
  const unsigned short kSVG_PATHSEG_CURVETO_CUBIC_ABS            = 6;  // C
  const unsigned short kSVG_PATHSEG_CURVETO_CUBIC_REL            = 7;  // c
  const unsigned short kSVG_PATHSEG_CURVETO_QUADRATIC_ABS        = 8;  // Q
  const unsigned short kSVG_PATHSEG_CURVETO_QUADRATIC_REL        = 9;  // q
  const unsigned short kSVG_PATHSEG_ARC_SWEEP_ABS                = 10; // A
  const unsigned short kSVG_PATHSEG_ARC_SWEEP_REL                = 11; // a
  const unsigned short kSVG_PATHSEG_ARC_VECTOR_ABS               = 12; // B
  const unsigned short kSVG_PATHSEG_ARC_VECTOR_REL               = 13; // b
  const unsigned short kSVG_PATHSEG_LINETO_HORIZONTAL_ABS        = 14; // H
  const unsigned short kSVG_PATHSEG_LINETO_HORIZONTAL_REL        = 15; // h
  const unsigned short kSVG_PATHSEG_LINETO_VERTICAL_ABS          = 16; // V
  const unsigned short kSVG_PATHSEG_LINETO_VERTICAL_REL          = 17; // v
  const unsigned short kSVG_PATHSEG_CURVETO_CUBIC_SMOOTH_ABS     = 18; // S
  const unsigned short kSVG_PATHSEG_CURVETO_CUBIC_SMOOTH_REL     = 19; // s
  const unsigned short kSVG_PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 20; // T
  const unsigned short kSVG_PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 21; // t

  readonly attribute  unsigned short pathsegType;
  readonly attribute  DOMString      pathsegTypeAsLetter;

  // Attribute values for a path segment.
  // Each pathseg has slots for any possible path seg type.
  // (We don't want to define 20 different subclasses to PathSeg -
      our document is long enough already.)
  attribute  double       x;   // end point for pathseg (or center for A/a/B/b)
  attribute  double       y;   // end point for pathseg (or center for A/a/B/b)
  attribute  double       x0,y0;    // for control points (start point for B/b)
  attribute  double       x1,y1;    // for control points (end point for B/b)
  attribute  double       r1,r2;    // radii for A/a/B/b
  attribute  double       a1,a2,a3; // angles for A/a

  readonly attribute  Path parentPath;
  readonly attribute  SVGDocument ownerSVGDocument;
  readonly attribute  SVGPathSeg previousSibling;
  readonly attribute  SVGPathSeg nextSibling;
};


pathsegType 이 cpp의 const(상수)로 지정되어있다.

이것은 SVG의 attribute 의 키는 pathsegType 이고 값은 각 pathType(M , L , Z ...) 에 따른 상수값으로 지정되어있다.

path 포인트 설정 혹은 path 포인트 수정시에 사용하면 될 것으로 생각된다.


참조 : w3.org

http://www.w3.org/1999/07/30/WD-SVG-19990730/svgdom.html


'HTML5 > SVG' 카테고리의 다른 글

[SVG] document.createElementNS  (0) 2015.10.05
SVG Editor 분석-3 Path 포인트 정의하기  (0) 2015.06.15
SVG pathsegType  (0) 2015.06.15
SVG Editor 분석-2 객체 추가  (0) 2015.06.12
SVG Editor 분석-1 [DOM 구조파악]  (0) 2015.06.10
SVG Radial  (0) 2015.06.09
준돌 Jundol / 2015.06.12 14:35 / HTML5/SVG



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;



'HTML5 > SVG' 카테고리의 다른 글

SVG Editor 분석-3 Path 포인트 정의하기  (0) 2015.06.15
SVG pathsegType  (0) 2015.06.15
SVG Editor 분석-2 객체 추가  (0) 2015.06.12
SVG Editor 분석-1 [DOM 구조파악]  (0) 2015.06.10
SVG Radial  (0) 2015.06.09
SVG Linear Gradients  (0) 2015.06.09
준돌 Jundol / 2015.06.10 12:00 / HTML5/SVG



DOM 구조

<div> 태그를 이용해서 큰 틀을 잡았다.

큰 틀 전부 div 요소로 이루어져있고 1번을 제외한 나머지는 display : none 상태

때에 따라 보이는 방법은 inline 과 block 속성값으로 처리됨.

  1. svg_editor : svg 에디터부분
  2. svg_source_editor : 소스로 볼 팝업 창
  3. svg_docprops : 왼쪽 상단 메뉴창의 document property 팝업창
  4. svg_prefs : 왼쪽 상단 메뉴창의 editor option 팝업창 [Editor Preferences]
  5. dialog_box : 왼쪽 상단 메뉴창의 export 팝업창
  6. cmenu_canvas : 캔버스에 우클릭시 나타나는 메뉴창
  7. cmenu_layers : 오른쪽 사이드바 레이어 우클릭시 나타나는 메뉴창


1. SVG 에디터 부분

  1. rulers : 에디터의 가늠자 구분선
  2. workarea : 작업공간 , 실질적 편집공간
  3. sidepanels : 우측 사이드바 , 초기에 접혀있는 상태의 레이어 버튼을 누르면 width 속성값이 150으로 늘어나면서 확장되는 형식.
  4. main_button : 왼쪽 상단 SVG-Edit 라는 메인 메뉴 버튼
  5. tools_top : 상단 속성메뉴
  6. cur_context_panel : 뭔지모르겠음...
  7. tools_left : 좌측 툴 선택메뉴
  8. tools_bottom : 하단 속성메뉴
  9. option_lists : 상단 속성메뉴에서 드롭다운 리스트가 가능한 요소들의 드롭다운 메뉴 집합소
  10. color_picker : 색상 선택 팝업 창
  11. tools_rect : 좌측 사각형 선택 툴을 길게 눌러서 다른 사각형 선택 툴을 선택할 수 있는 요소
  12. tools_ellipse : 원형 선택 확장메뉴 위 사각형과 같음
  13. tools_line : 선 선택 확장메뉴
  14. tools_shapelib : shape 선택 확장 라이브러리 (너무 많은것같아 lib로 만든것 같군요)

1-1 : workarea 

  1. style 태그 styleoverrides : 동적으로 스타일 추가
    #svgcanvas svg *{cursor:move;pointer-events:all}, #svgcanvas svg{cursor:default}
    마우스 커서의 포인터를 지정. 삭제할 경우 객체에 마우스 오버시 이동 커서 나타나지 않음
  2. svgcanvas : svg 그리는 캔버스
    ㄴsvgroot : svg의 root DOM 요소
1-1-1 : svgroot
  1. <defs> 
    ㄴ 필터와 그리드패턴이 정의되어있음.
  2. <svg> canvasBackground : 흰색 바탕 캔버스를 rect로 그려냈고, canvasGrid 를 이용 grid DOM 요소가 있음. 상단 메뉴의 그리드를 on/off 선택시 diplay 속성값이 변경되면서 나타남.
  3. <animate> opacity
  4. <svg> svgcontent : 객체가 위치하는 곳
  5. <g> selectorParentGroup : 객체를 선택할때 그룹핑하는 요소


'HTML5 > SVG' 카테고리의 다른 글

SVG pathsegType  (0) 2015.06.15
SVG Editor 분석-2 객체 추가  (0) 2015.06.12
SVG Editor 분석-1 [DOM 구조파악]  (0) 2015.06.10
SVG Radial  (0) 2015.06.09
SVG Linear Gradients  (0) 2015.06.09
SVG Drop Shadows  (0) 2015.06.09
준돌 Jundol / 2015.06.09 12:33 / HTML5/SVG

* 본 글은 W3SCHOOL.COM 의 SVG 편을 해석 공부한 포스팅입니다.

* 필자의 기준이 절대적인 진리는 아닙니다.



SVG Radial Gradient - <radialGradient>

<radialGradient>태그는 radial 그라디언트를 정의할 때 사용한다.

<radialGradient>태그는 반드시 <defs>태그 내에 위치해야한다. <defs>태그는 정의를 생략하거나 그라디언트와 같이 특별한 요소를 정의할 때 사용한다.


예제 1

방사형(radial) 그라디언트를 원형에 그린다. 색상은 흰색에서 파란색으로 바뀐다.

SVG 코드

<svg height="150" width="500">
  <defs>
    <radialGradient id="grad1" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
      <stop offset="0%" style="stop-color:rgb(255,255,255);
      stop-opacity:0"
 />
      <stop offset="100%" style="stop-color:rgb(0,0,255);stop-opacity:1" />
    </radialGradient>
  </defs>
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" />
</svg>

코드 설명
  • cx , cy , r 속성은 가장 바깥쪽 원형을 정의한다. fx , fy 는 가장 안쪽의 원형을 정의한다.

예제 2
다른 원형을 정의한다.

SVG 코드

<svg height="150" width="500">
  <defs>
    <radialGradient id="grad2" cx="20%" cy="30%" r="30%" fx="50%" fy="50%">
      <stop offset="0%" style="stop-color:rgb(255,255,255);
      stop-opacity:0"
 />
      <stop offset="100%" style="stop-color:rgb(0,0,255);stop-opacity:1" />
    </radialGradient>
  </defs>
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad2)" />
</svg>


출처 W3School.com - SVG - SVG Radial

http://www.w3schools.com/svg/svg_grad_radial.asp

'HTML5 > SVG' 카테고리의 다른 글

SVG Editor 분석-2 객체 추가  (0) 2015.06.12
SVG Editor 분석-1 [DOM 구조파악]  (0) 2015.06.10
SVG Radial  (0) 2015.06.09
SVG Linear Gradients  (0) 2015.06.09
SVG Drop Shadows  (0) 2015.06.09
SVG Blur Effects  (0) 2015.06.09
준돌 Jundol / 2015.06.09 12:23 / HTML5/SVG

* 본 글은 W3SCHOOL.COM 의 SVG 편을 해석 공부한 포스팅입니다.

* 필자의 기준이 절대적인 진리는 아닙니다.


SVG Gradients

그라디언트란 하나의 색상에서 또 다른 하나의 색상으로 자연스럽게 변화가 가능한 기능이다. 게다가 몇몇의 색상의 변화는 같은 요소에 적용이 가능하다.

SVG의 그라디언트 타입은 두 가지가 있다.

  • Linear
  • Radial

SVG Linear Gradient - <linearGradient>

<linearGradient> 태그는 linear gradient 를 정의할때 사용한다.
<linearGradient> 태그는 반드시 <defs>태그와 중첩되어야한다. <defs>태그는 그라디언트와같은 특별한 속성을 정의하거나 정의를 생략할때 사용한다.

Linear 그라디언트는 세로 혹은 가로로 적용이 가능 하다.
  • 가로 그라디언트는 y1 과 y2 가 동일하고 x1 과 x2가 다르다.
  • 세로 그라디언트는 x1과 x2 가 동일하고 y1 과 y2가 다르다.
  • 기울어진 그라디언트는 네 점 모두 다르다.

예제 1
원에 가로 linear 그라디언트를 적용한다. 색상은 노란색에서 빨간색으로 바뀐다.

SVG 코드

<svg height="150" width="400">
  <defs>
    <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
  </defs>
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" />
</svg>


코드 설명

  • <linearGradient> 태그 내의 x1 , x2 , y1 , y2 속성은 그라디언트의 시작점과 끝점을 정의한다.
  • 그라디언트의 색상 유효갯수는 두가지 이상이다. 각 색상은 <stop> 태그로 정의된다. offset속성은 그라디언트 색상의 시작과 끝을 정의한다.
  • <ellipse>태그 내의 fill 속성은 그라디언트의 id와 연결한다.

예제 2
원에 세로 linear 그라디언트를 적용한다. 색상은 노란색에서 빨간색으로 바뀐다.

SVG 코드

<svg height="150" width="400">
  <defs>
    <linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%">
      <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
  </defs>
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad2)" />
</svg>


예제 3

예제 1번에 원형안에 텍스트를 추가해보자.

SVG

SVG 코드

<svg height="150" width="400">
  <defs>
    <linearGradient id="grad3" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
  </defs>
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad3)" />
  <text fill="#ffffff" font-size="45" font-family="Verdana" x="150" y="86">
  SVG</text>
</svg>


코드 설명

  • <text>태그는 텍스트를 추가 할 수 있다.

출처 W3School.com - SVG - SVG Linear


'HTML5 > SVG' 카테고리의 다른 글

SVG Editor 분석-1 [DOM 구조파악]  (0) 2015.06.10
SVG Radial  (0) 2015.06.09
SVG Linear Gradients  (0) 2015.06.09
SVG Drop Shadows  (0) 2015.06.09
SVG Blur Effects  (0) 2015.06.09
SVG Filters  (0) 2015.06.09
© 2015 Jundol in 음 아마 비둘기보단 똑똑할꺼야
Designed by DH / Powered by Tistory
147 / 14 / 114,041