SVG의 획 너비를 그리는 방법을 제어 할 수 있습니까? 삽입. 특히 사각형의 바깥 쪽 너비와

현재 브라우저 기반 SVG 응용 프로그램을 구축 중입니다. 이 응용 프로그램 내에서 사각형을 포함하여 다양한 모양을 사용자가 스타일을 지정하고 배치 할 수 있습니다.

나는를 적용하면 stroke-widthSVG의에 rect말의 요소 1px, 스트로크가 적용됩니다 rect의 오프셋 및 다른 브라우저로 다른 방법으로 삽입. 특히 사각형의 바깥 쪽 너비와 시각적 위치를 계산하고 다른 요소 옆에 배치하려고 할 때 문제가되는 것으로 입증되었습니다 .

예를 들면 다음과 같습니다.

  • Firefox는 1px 삽입 (아래와 왼쪽)과 1px 오프셋 (상하와 오른쪽)을 추가합니다
  • Chrome은 1px 삽입 (상단 및 왼쪽)과 1px 오프셋 (하단 및 오른쪽)을 추가합니다

지금까지 내 유일한 해결책은 실제 테두리를 직접 (아마도 path도구를 사용하여 ) 그려서 테두리를 획 요소 뒤에 배치하는 것입니다. 그러나이 솔루션은 불쾌한 해결 방법이며 가능한 경우이 길을 따르지 않는 것이 좋습니다.

내 질문은 SVG stroke-width에 요소를 그리는 방법을 제어 할 수 있습니까?



답변

아니요, 획을 요소 내부 또는 외부에 그릴 지 여부를 지정할 수 없습니다. 내가 만든 제안 2003 년에이 기능에 대한 SVG의 작업 그룹을하지만, 어떤 지원 (또는 토론)을 수신하지.

SVG가 제안한 스트로크 위치 예 (phrogz.net/SVG/stroke-location.svg)

제안서에서 언급했듯이

  • 스트로크 너비를 두 배로 늘리고 클리핑 패스를 사용하여 객체를 자체적으로 자르면 “내부”와 동일한 시각적 결과를 얻을 수 있습니다.
  • 획 너비를 두 배로 늘리고 획없는 객체 사본 위에 오버레이하여 ‘외부’와 동일한 시각적 결과를 얻을 수 있습니다.

편집 :이 답변은 나중에 틀릴 수 있습니다. 사용하여 이러한 결과를 달성 할 수 있어야한다 SVG 벡터 효과를 조합함으로써, veStrokePathveIntersect( ‘내부’) 또는과 veExclude(외부 ‘의 경우). 그러나 Vector Effects는 아직 구현되지 않은 초안 모듈입니다.

편집 2 : SVG 2 드래프트 사양에 stroke-alignment속성이있다 (중앙값 이상으로). 이 속성은 결국 UA로 만들 수 있습니다.

편집 3 : 재미 있고 엉망인 SVG 작업 그룹이 stroke-alignmentSVG 2에서 제거되었습니다 . 여기서 산문 후에 설명 된 문제 중 일부를 볼 수 있습니다 .


답변

UPDATE :stroke-alignment 속성은 4 월 1 일, SVG 스트로크라는 완전히 새로운 스펙으로 이동 2015 년이었다 .

2015 년 2 월 26 일 ( 2 월 13 일 이후 ) SVG 2.0 에디터 초안 에서stroke-alignment속성이 존재 값으로 inner , center (기본)outer.

그것은 같은 방식으로 작동하는 것 같습니다 stroke-location @Phrogz하고 나중에 의해 제안 된 재산 stroke-position제안을 . 이 숙박 시설은 최소 2011 년부터 계획되었지만

SVG 2는 스트로크 위치를 지정하는 방법을 포함해야합니다

, 그것은 지금까지 연기되었던 스펙에 상세하게 설명 된 적이 없다 .

브라우저가이 속성을 지원하지 않거나 새로운 SVG 2 기능을 아직 지원하지 않지만 사양이 성숙 해지 자마자 기능이 향상 될 것입니다. 이것은 내가 개인적으로 갖고 싶었던 재산이었고, 그것이 그것이 사양에 마침내 들어서서 정말 기쁩니다.

루프뿐만 아니라 열린 경로에서 속성이 어떻게 동작해야하는지에 대한 몇 가지 문제가있는 것 같습니다. 이러한 문제는 대부분 브라우저에서 구현을 연장 할 것입니다. 그러나 브라우저 가이 속성을 지원하기 시작하면이 정보를 새로운 정보로 업데이트 할 것입니다.


답변

몇 가지 제한 사항이 있지만 쉬운 방법을 찾았습니다.

  • 형태를 defs로 정의
  • 모양을 참조하는 클립 경로 정의
  • 그것을 사용하고 외부가 잘릴 때 스트로크를 두 배로하십시오

다음은 실제 예입니다.

<svg width="240" height="240" viewBox="0 0 1024 1024">
<defs>
	<path id="ld" d="M256,0 L0,512 L384,512 L128,1024 L1024,384 L640,384 L896,0 L256,0 Z"/>
	<clipPath id="clip">
		<use xlink:href="#ld"/>
	</clipPath>
</defs>
<g>
	<use xlink:href="#ld" stroke="#0081C6" stroke-width="160" fill="#00D2B8" clip-path="url(#clip)"/>
</g>
</svg>


답변

CSS를 사용하여 획 및 채우기 순서를 지정할 수 있습니다. 즉, 먼저 스트로크 한 다음 두 번째로 채우고 원하는 효과를 얻습니다.

MDN paint-order: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/paint-order

CSS 코드 :

paint-order: stroke;


답변

주어진 스트로크를 사용하여 브라우저를 기준으로 상단, 오른쪽, 하단 및 왼쪽에 추가해야 할 픽셀 수를 계산하는 함수는 다음과 같습니다.

var getStrokeOffsets = function(stroke){

        var strokeFloor =       Math.floor(stroke / 2),                                                                 // max offset
            strokeCeil =        Math.ceil(stroke / 2);                                                                  // min offset

        if($.browser.mozilla){                                                                                          // Mozilla offsets

            return {
                bottom:     strokeFloor,
                left:       strokeFloor,
                top:        strokeCeil,
                right:      strokeCeil
            };

        }else if($.browser.webkit){                                                                                     // WebKit offsets

            return {
                bottom:     strokeCeil,
                left:       strokeFloor,
                top:        strokeFloor,
                right:      strokeCeil
            };

        }else{                                                                                                          // default offsets

            return {
                bottom:     strokeCeil,
                left:       strokeCeil,
                top:        strokeCeil,
                right:      strokeCeil
            };

        }

    };


답변

위의 사람들이 언급했듯이 SVG는 기본적으로 Illustrator의 획 정렬을 지원하지 않을뿐만 아니라 PostScript는 획의 경로 좌표에 대한 오프셋을 다시 계산하거나 너비를 두 배로 늘린 다음 한쪽을 마스크해야합니다. .

어도비의 포스트 스크립트 매뉴얼 2 판 상태에서 스트로크 사양은 ” 4.5.1 쓰 다듬어 : 스트로크 운영자는 현재의 경로를 따라 몇 가지 두께의 선을 그립니다 경로의 각 직선 또는 곡선 세그먼트를 들어,. 스트로크가 되어 줄립니다 중심 에를 측면이 평행 한 세그먼트 을 가진 세그먼트” (강조)

사양의 나머지 부분에는 선의 위치를 ​​상쇄하기위한 속성이 없습니다. Illustrator에서 내부 또는 외부를 정렬 할 수있는 경우 실제 경로의 오프셋을 다시 계산합니다 (여전히 인쇄 한 후 마스킹하는 것보다 계산 비용이 저렴하기 때문입니다). .ai 문서의 경로 좌표는 참조 형식이며 래스터 화되거나 최종 형식으로 내보내지는 것은 아닙니다.

Inkscape의 기본 형식은 사양 SVG이므로 사양에없는 기능을 제공 할 수 없습니다.


답변

다음은 and를 사용하여 내부 경계 에 대한 해결 방법입니다 .rectsymboluse

: https://jsbin.com/yopemiwame/edit?html,output

SVG :

<svg>
  <symbol id="inner-border-rect">
    <rect class="inner-border" width="100%" height="100%" style="fill:rgb(0,255,255);stroke-width:10;stroke:rgb(0,0,0)">
  </symbol>
  ...
  <use xlink:href="#inner-border-rect" x="?" y="?" width="?" height="?">
</svg>

참고 : 교체해야합니다 ?use실제 값.

배경 : 기호로 대체하여 새 뷰포트 설정 때문에이 작품 이유는 symbolsvg와 그림자 DOM의 요소를 생성합니다. 그러면 svg그림자 DOM이 현재 SVG요소에 연결됩니다 . 주의 svg의는 중첩 될 수 있습니다 모든이 svg새로운 뷰포트를 생성하는 클립 중복이 중첩 경계부를 포함하여 모든 것이. 무슨 일이 일어나고 있는지에 대한 더 자세한 개요는 Sara Soueidan 의이 환상적인 기사 를 읽으 십시오.