HTML SVG는 <use>와 함께 <g> 그룹을 재사용하고 각 인스턴스에 대해 개별적으로 내부 요소의 속성을 변경합니다.
따라서 그룹화 된 svg 모양을 재사용하고 각 인스턴스에 대해 그룹 내부 요소 중 하나의 속성 하나를 개별적으로 변경하고 싶습니다. 다음 간단한 예제는 내부에 사각형이있는 두 번째 원을 만듭니다. 이제 자바 스크립트를 사용하여 각 도형에 대해 "my-rect"사각형의 "너비"속성을 개별적으로 변경하고 싶습니다. ID "my-rect"를 사용하면 두 사각형의 너비가 변경되지만 하나만 변경하고 싶습니다.
내 목표 (내 접근 방식이 말도 안되는 경우) : 이러한 모양을 여러 개 그려야하고 다른 점은 직사각형의 위치와 너비뿐입니다.
<svg height="1000" width="1000">
<a transform="translate(110,110)">
<g id="my-group">
<g>
<circle r="100" fill="#0000BF" stroke="black" stroke-width="2" fill-opacity="0.8"></circle>
</g>
<g>
<rect id="my-rect" y="-50" height="100" x="-50" width="50">
</rect>
</g>
</g>
</a>
<use xlink:href="#my-group" x="340" y="110"/>
</svg>
답변
약간의 속임수로 가능합니다. 그림자 요소 내에서 일부 속성 값을 얻으려면 CSS 상속을 활용해야합니다. 이 경우 사각형의 크기를 조정하고 위치를 지정하는 데 사용되는 사용자 지정 변수가됩니다.
이를 위해 마크 업을 약간 다시 작성해야합니다. 먼저, <defs>
요소 안에 그룹을 작성하여 재사용을위한 템플릿으로 만들지 만 자체적으로 렌더링하지는 않습니다. 둘째, 직사각형은 중첩 된 <svg overflow="visible">
요소 내부에 배치됩니다 . 이 요소에 x / y 좌표를 부여하고 요소에 대해 0으로두면 <rect>
변형 작업 후 직사각형의 왼쪽이 끝나는 위치를 쉽게 추적 할 수 있습니다.
이제 rect의 너비 변경은 위치에 대한 scaleX()
변환과 a translate()
로 이루어집니다 . 이것은 CSS의 구문을 변환해야합니다 . transform
속성을 사용하면 (아직) 작동하지 않습니다. 따라서 transform-origin
둘러싸는 <svg>
요소 의 왼쪽에 설정된 속성 도 필요합니다 .
스케일링에 대한 구체적인 값을 작성하는 대신 값은 기본값이 1 인 변수로 표현됩니다. var(--scale, 1)
; 위치 값에 대해서도 동일합니다. 변수 값은 style
각 <use>
요소 의 속성에 개별적으로 설정됩니다 style="--scale:2;--posX:20px; --posY:-10px"
. px
단위 쓰기가 필요합니다 !
#my-rect {
transform-origin: left top;
transform: translate(var(--posX, 0), var(--posY, 0)) scaleX(var(--scale, 1));
}
<svg height="1000" width="1000">
<defs>
<g id="my-group">
<g>
<circle r="100" fill="#0000BF" stroke="black" stroke-width="2" fill-opacity="0.8"></circle>
</g>
<svg x="-50" y="-50" overflow="visible">
<rect id="my-rect" height="100" width="50">
</rect>
</svg>
</g>
</defs>
<use xlink:href="#my-group" x="110" y="110" style="--scale:1"/>
<use xlink:href="#my-group" x="340" y="110" style="--scale:2;--posX:20px; --posY:-10px"/>
</svg>
Sean은 다음과 같이 말했습니다.
Web Components Custom Elements가 SVG 네임 스페이스로 확장되면
더 복잡한 재사용이 가능합니다.
사실, 사용자 정의 SVG 요소를 아직 만들 수 없습니다 .
그러나 SVG 를 생성 하는 사용자 정의 요소를 만들 수 있습니다 .
customElements.define("rect-in-circle", class extends HTMLElement{
connectedCallback(){
const a = x => this.getAttribute(x);
this.innerHTML=`<svg viewBox="-100 -100 100 100">`+
`<g transform="translate(-50 -50)">`+
`<circle r="50" fill="#123456AB"/>`+
`<rect y="${a("y")}" height="${a("height")}"`+
`x="${a("x")}" width="${a("width" )}"/>`+
`</g></svg>`
}
});
svg{
width:100px;
height:100px;
background:grey;
fill:green;
}
<rect-in-circle x=-10 y=-10 width=20 height=20></rect-in-circle>
<rect-in-circle x=-40 y=-20 width=10 height=40></rect-in-circle>
<rect-in-circle x= 10 y= 20 width=30 height= 5></rect-in-circle>
SVG 용 Custom Elements는 많은 oldskool SVG 해킹에 대한 최신 솔루션입니다.
최신 정보
OP가 원이있는 SVG 하나를 원하면 shadowDOM을 사용할 수 있으며 lightDOM 내부의 요소가 표시되지 않는다는 사실을 사용할 수 있습니다. 우리는 심지어 사용할 수있는 정의되지 않은 <rect>
SVG 문자열에 쉽게 분사합니다 (HTML 네임 스페이스) 요소 우리가 할 수있는 정도.
<script>
customElements.define("rects-in-circles", class extends HTMLElement {
connectedCallback() {
setTimeout(() => {
const rects = [...this.children];
const width = rects.length * 100;
this.attachShadow({
mode: "open"
}).innerHTML = `<svg viewBox='0 0 ${width} 100'>` + rects.map((rect, idx) => `<g transform='translate(${50+100*idx} 50)'>` +
`<circle r='50' fill='green'/>` +
rect.outerHTML +
`</g>`) + "</svg>";
})
}
});
</script>
<rects-in-circles>
<rect x=-10 y=-10 width=20 height=20></rect>
<rect x=-40 y=-20 width=10 height=40></rect>
<rect x=10 y=20 width=30 height=5></rect>
<rect x=-40 y=-40 width=50 height=50></rect>
</rects-in-circles>
(my)
관련 StackOverflow 답변 : 사용자 지정 요소 및 SVG
이것은 불가능합니다. 이 use
요소는을 생성합니다 closed shadow root. 이는 해당 콘텐츠가 JS에 액세스 할 수 없음을 의미합니다. 재사용 된 요소의 인스턴스 속성을 개별적으로 설정할 수 있지만 (원래 요소에 설정되지 않은 경우) 재사용 된 요소의 하위 요소에 영향을 미칠 수 없습니다.
다른 방법은 직사각형 및 원 요소를 직접 재사용하여 새 그룹에 배치하는 것입니다.
이 getAttribute
방법은 저에게 효과가 없었지만 효과가 있습니다.
customElements.define("source-link", class extends HTMLElement {
static get observedAttributes() {
return ['href'];
}
get href() {
return this.getAttribute('href');
}
set href(val) {
if (val) {
this.setAttribute('href', val);
} else {
this.removeAttribute('href');
}
}
connectedCallback(){
this.innerHTML= '<a href="' + this.href + '" target="_blank" title="source"><svg fill="#37f" viewBox="0 0 512 512" width="16"><g><path d="M488.727,0H302.545c-12.853,0-23.273,10.42-23.273,23.273c0,12.853,10.42,23.273,23.273,23.273h129.997L192.999,286.09 c-9.089,9.089-9.089,23.823,0,32.912c4.543,4.544,10.499,6.816,16.455,6.816c5.956,0,11.913-2.271,16.457-6.817L465.455,79.458 v129.997c0,12.853,10.42,23.273,23.273,23.273c12.853,0,23.273-10.42,23.273-23.273V23.273C512,10.42,501.58,0,488.727,0z"/></g><g><path d="M395.636,232.727c-12.853,0-23.273,10.42-23.273,23.273v209.455H46.545V139.636H256c12.853,0,23.273-10.42,23.273-23.273 S268.853,93.091,256,93.091H23.273C10.42,93.091,0,103.511,0,116.364v372.364C0,501.58,10.42,512,23.273,512h372.364 c12.853,0,23.273-10.42,23.273-23.273V256C418.909,243.147,408.489,232.727,395.636,232.727z"/></g></svg></a>';
}
});
사용법 :
<source-link href="//google.com"></source-link>
출처 : D