본문 바로가기
svg

svg symbol tag, use tag

by peach1227 2023. 10. 28.

다음은 SVG 파일의 결과물을 분석을 하는 글입니다.

문서객체모형을 통해 root인 <svg>태그 밑에 <style>태그,<defs>태그 ,몇개의 <g>태그를 둡니다.

여기서 <defs>태그는 정의를 위한 태그로 그 안의 자식들은 참조될때 rendering 됩니다.

<g>태그에는 일부는 정적으로 자식을 두고 나머지는 자바스크립트로 동적으로 생성합니다.

일부러 복잡하게 하여, 차이점을 파악하는 계기가 될 수있습니다.

<g>태그의 자식들인 <use>태그들은 <symbol> 태그의 id 속성을 이용하여 <use>태그의 href 속성으로 참조합니다.

<symbol>태그의 자식인 <path>태그의 fill 속성값을 'inherit'로 둠으로서 <use>태그에서 fill 속성값을 상속으로 사용하는 것에 유의해야 합니다.

<use>태그를 이용해 심벌을 복사를 하되 변형을 하여 마구 재사용하는 것이므로 활용도가 높다고 할 수 있습니다.

자바스크립트로 <use>객체를 생성할 때, namespace를 고려하는 document.createElementNS를 사용하고 있다는 점이

조금 특이하지만, 나머지는 일반적인 1)객체생성, 2)속성부여,3)DOM에 부착하는 방법입니다.

fill 속성값을 다양하게 하기위해 Math.random함수와 Math.floor함수를 활용했습니다.

<svg viewBox="0 0 500 500">
    <style>
        :root {
            --color: gold;
        }

        .use-circle {
            fill: var(--color,"gold");
        }

        #circle-0 {
            fill: inherit;
        }
    </style>
    <defs>
        <symbol id="symbol-0">
            <circle id="circle-0" cx="250" cy="250" r="10"/>
        </symbol>
        <symbol id="symbol-1">
            <path id="star" d="M 248 241.4 L 245.65 248.2 L 238.45 248.35 L 244.2 252.7 L 242.1 259.6 L 248 255.5 L 253.95 259.6 L 251.85 252.7 L 257.6 248.35 L 250.4 248.2 z"/>
        </symbol>
    </defs>
    <g id="g1">
        <use id="use-0" class="use-circle" href="#symbol-0">
    </g>
    <g id="g2"></g>
    <g id="g3">
        <use id="star-1" href="#symbol-1"/>
    </g>
    <script>

        for (let i = 2; i < 10; i++) {

            var randomColor = Math.floor(Math.random() * 16777215).toString(16);
            console.log(randomColor);
            var use = document.createElementNS('http://www.w3.org/2000/svg', "use");
            use.setAttribute('id', 'use' + i);
            use.setAttribute('href', "#symbol-0");
            use.style.setProperty('transform', `translate(${15 * i}px,${15 * i}px)`);
            use.style.setProperty('fill', "#" + randomColor);
            g1.appendChild(use);
        }

        for (let i = 2; i < 10; i++) {

            var randomColor = Math.floor(Math.random() * 16777215).toString(16);
            console.log(randomColor);
            var use = document.createElementNS('http://www.w3.org/2000/svg', "use");
            use.setAttribute('id', 'use' + i + 10);
            use.setAttribute('href', "#symbol-0");
            use.style.setProperty('transform', `translate(${-15 * i}px,${-15 * i}px)`);
            use.style.setProperty('fill', "#" + randomColor);
            g2.appendChild(use);
        }
    </script>
    <script>

        for (let i = 2; i < 10; i++) {

            var randomColor = Math.floor(Math.random() * 16777215).toString(16);
            console.log(randomColor);
            var use = document.createElementNS('http://www.w3.org/2000/svg', "use");
            use.setAttribute('id', 'use' + i);
            use.setAttribute('href', "#symbol-1");
            use.style.setProperty('transform', `translate(${15 * i}px,${-15 * i}px)`);
            use.style.setProperty('fill', "#" + randomColor);
            g3.appendChild(use);
        }

        for (let i = 2; i < 10; i++) {

            var randomColor = Math.floor(Math.random() * 16777215).toString(16);
            console.log(randomColor);
            var use = document.createElementNS('http://www.w3.org/2000/svg', "use");
            use.setAttribute('id', 'use' + i + 10);
            use.setAttribute('href', "#symbol-1");
            use.style.setProperty('transform', `translate(${-15 * i}px,${15 * i}px)`);
            use.style.setProperty('fill', "#" + randomColor);
            g3.appendChild(use);
        }
    </script>
</svg>

자바스크립트 적용후의 결과물(for your reference)

<svg viewBox="0 0 500 500">
    <style>
        :root {
            --color: gold;
        }

        .use-circle {
            fill: var(--color,"gold");
        }

        #circle-0 {
            fill: inherit;
        }
    </style>
    <defs>
        <symbol id="symbol-0">
            <circle id="circle-0" cx="250" cy="250" r="10"></circle>
        </symbol>
        <symbol id="symbol-1">
            <path id="star" d="M 248 241.4 L 245.65 248.2 L 238.45 248.35 L 244.2 252.7 L 242.1 259.6 L 248 255.5 L 253.95 259.6 L 251.85 252.7 L 257.6 248.35 L 250.4 248.2 z"></path>
        </symbol>
    </defs>
    <g id="g1">
        <use id="use-0" class="use-circle" href="#symbol-0"></use>
        <use id="use2" href="#symbol-0" style="transform: translate(30px, 30px); fill: rgb(238, 240, 121);"></use>
        <use id="use3" href="#symbol-0" style="transform: translate(45px, 45px); fill: rgb(100, 210, 54);"></use>
        <use id="use4" href="#symbol-0" style="transform: translate(60px, 60px); fill: rgb(213, 210, 117);"></use>
        <use id="use5" href="#symbol-0" style="transform: translate(75px, 75px); fill: rgb(56, 51, 140);"></use>
        <use id="use6" href="#symbol-0" style="transform: translate(90px, 90px); fill: rgb(196, 84, 129);"></use>
        <use id="use7" href="#symbol-0" style="transform: translate(105px, 105px); fill: rgb(127, 21, 234);"></use>
        <use id="use8" href="#symbol-0" style="transform: translate(120px, 120px); fill: rgb(134, 242, 229);"></use>
        <use id="use9" href="#symbol-0" style="transform: translate(135px, 135px); fill: rgb(211, 52, 141);"></use>
    </g>
    <g id="g2">
        <use id="use210" href="#symbol-0" style="transform: translate(-30px, -30px); fill: rgb(92, 65, 191);"></use>
        <use id="use310" href="#symbol-0" style="transform: translate(-45px, -45px); fill: rgb(148, 85, 53);"></use>
        <use id="use410" href="#symbol-0" style="transform: translate(-60px, -60px); fill: rgb(119, 176, 203);"></use>
        <use id="use510" href="#symbol-0" style="transform: translate(-75px, -75px); fill: rgb(151, 70, 26);"></use>
        <use id="use610" href="#symbol-0" style="transform: translate(-90px, -90px); fill: rgb(38, 229, 31);"></use>
        <use id="use710" href="#symbol-0" style="transform: translate(-105px, -105px); fill: rgb(60, 197, 248);"></use>
        <use id="use810" href="#symbol-0" style="transform: translate(-120px, -120px);"></use>
        <use id="use910" href="#symbol-0" style="transform: translate(-135px, -135px); fill: rgb(58, 241, 253);"></use>
    </g>
    <g id="g3">
        <use id="star-1" href="#symbol-1"></use>
        <use id="use2" href="#symbol-1" style="transform: translate(30px, -30px); fill: rgb(253, 231, 176);"></use>
        <use id="use3" href="#symbol-1" style="transform: translate(45px, -45px); fill: rgb(202, 161, 155);"></use>
        <use id="use4" href="#symbol-1" style="transform: translate(60px, -60px); fill: rgb(28, 27, 138);"></use>
        <use id="use5" href="#symbol-1" style="transform: translate(75px, -75px); fill: rgb(49, 45, 5);"></use>
        <use id="use6" href="#symbol-1" style="transform: translate(90px, -90px); fill: rgb(106, 131, 62);"></use>
        <use id="use7" href="#symbol-1" style="transform: translate(105px, -105px); fill: rgb(228, 244, 140);"></use>
        <use id="use8" href="#symbol-1" style="transform: translate(120px, -120px); fill: rgb(122, 101, 101);"></use>
        <use id="use9" href="#symbol-1" style="transform: translate(135px, -135px); fill: rgb(79, 24, 177);"></use>
        <use id="use210" href="#symbol-1" style="transform: translate(-30px, 30px); fill: rgb(34, 247, 166);"></use>
        <use id="use310" href="#symbol-1" style="transform: translate(-45px, 45px); fill: rgb(134, 155, 55);"></use>
        <use id="use410" href="#symbol-1" style="transform: translate(-60px, 60px); fill: rgb(223, 7, 224);"></use>
        <use id="use510" href="#symbol-1" style="transform: translate(-75px, 75px); fill: rgb(84, 232, 67);"></use>
        <use id="use610" href="#symbol-1" style="transform: translate(-90px, 90px); fill: rgb(254, 77, 53);"></use>
        <use id="use710" href="#symbol-1" style="transform: translate(-105px, 105px); fill: rgb(140, 160, 141);"></use>
        <use id="use810" href="#symbol-1" style="transform: translate(-120px, 120px); fill: rgb(33, 49, 82);"></use>
        <use id="use910" href="#symbol-1" style="transform: translate(-135px, 135px); fill: rgb(183, 221, 15);"></use>
    </g>
</svg>

반응형