Search code examples
csssvgblazorfluent-ui

Scroll bar type controls to pan an SVG


I have an SVG where I want to pan the view box over the image. For example if I have an SVG with elements anywhere over an area 0->1000 by 0->1000 and I set the (square) viewbox to 0 0 500 500 I get the top left quarter; I set the view box to 250 250 500 500 I get the middle all as expected.

I have:

<svg viewbox="@svgViewBox"...... >.....

private string SvgViewBox => $"{PanHorizontal} {PanVertical} {ViewBoxWidth} {ViewBoxHeight}";

I can set values of PanHorizontal and PanVertical etc to show various parts of the SVG

I would really like something like scroll bars to bind to PanHorizontal and PanVertical . I've tried FluentSlider with horizontal and vertical alignment but can't figure out how to position them well around the SVG.

Is this a css problem? If so how do I place the controls to the right and below the svg? Any thoughts?

I've made a few attempts to position the flutentslider's but I'm in the dark.


Solution

  • SVG is xml markup, much like HTML, which means you can parameterize whatever you want, in this case the offset of your view box. You could literally make an entire site with all SVG, I think, including animations, etc. I recommend making a separate .razor component for each shape.

    Home.razor

    @page "/"
    @rendermode InteractiveServer
    
    <div style="width:50vmin; height:50vmin; border: 1px solid black;
                cursor:grab">
        <div style="display:flex; flex-direction:row;">
            <Shape1 Xoffset=OffsetX Yoffset=OffsetY />
        </div>
        <div style="transform:rotate(90deg); padding-right:20px;transform-origin:top right;">
            <input @bind=OffsetY style="width:100%" type="range" min="-1000" max="1000" step="1">
        </div>
        <div style="height:20px; display:relative; margin-top:-40px;padding-right:20px">
            <input @bind=OffsetX style="width:100%" type="range" min="-1000" max="1000" step="1">
        </div>
    </div>
    
    @code {
        float OffsetX = 0.0f;
        float OffsetY = 0.0f;
    }
    

    Shape1.razor

    <svg style="" viewBox="@Xoffset @Yoffset 1000 1000" xml:space="preserve">
    <ellipse fill="#1E3B50" cx="548.8" cy="468.2" rx="363.4" ry="348" />
    <g>
    <g>
    <path fill="#4995D1" d="M382.9,527.1c23.5,12.7,40.4,34,60.5,51.2c10.6,9.1,22.1,16.7,35.1,21.8c13.9,5.5,28.7,8.3,43.5,9.7
                c28.3,2.7,57,0.7,84.8-5c27.6-5.7,54.5-15.4,79.4-28.6c12.4-6.6,24.4-14,35.7-22.3c11.3-8.2,22.9-17.1,31.2-28.4
                c2.1-2.8,3.9-5.8,5.4-9c1.3-2.9-3-5.4-4.3-2.5c-5.9,12.7-17,22-27.9,30.4c-10.9,8.5-22.4,16.2-34.5,23.1c-24.1,13.7-50,24-77,30.5
                c-26.9,6.5-54.7,9.1-82.4,7.7c-14.8-0.8-29.6-2.7-43.7-7.1c-13.3-4.1-25.5-10.7-36.4-19.3c-20.5-16.1-36.8-37.1-58.7-51.5
                c-2.7-1.8-5.4-3.4-8.2-4.9C382.6,521.3,380,525.6,382.9,527.1L382.9,527.1z" />
        </g>
    </g>
    <g>
    <g>
    <path fill="#4995D1" d="M657.6,305c-8,2-13.4,8.4-16.5,15.8c-3.4,8.1-4.7,16.9-5.6,25.6c-0.5,5.4-0.5,11.2,1.5,16.4
                c1.5,4,4,7.5,7.4,10.2c6.8,5.5,15.7,7.8,24.3,8.3c8.3,0.5,16.8-0.9,24.5-3.9c7.6-3,14.7-7.6,19.5-14.3c4.7-6.7,6.1-15.3,3.5-23.1
                c-2.9-8.7-9.9-15.3-17.2-20.5c-3.8-2.7-7.7-5.1-11.7-7.5c-4.7-2.8-9.5-5.6-14.3-8.1c-9.7-5-20-9-31-9.9c-2.6-0.2-5.2-0.2-7.8,0
                c-1.3,0.1-2.5,1.1-2.5,2.5c0,1.3,1.1,2.6,2.5,2.5c20.1-1.5,38.7,9.8,55.2,20c6.9,4.3,14.2,9.2,18.9,16.1
                c4.2,6.2,5.6,13.6,2.9,20.5c-2.4,6.2-8,11.1-13.9,14.4c-6.5,3.6-14,5.8-21.4,6.3c-7.6,0.5-15.7-0.4-22.6-3.7
                c-3.3-1.6-6.3-3.7-8.6-6.6c-2.6-3.3-3.9-7.4-4.1-11.6c-0.3-4.7,0.3-9.6,0.9-14.3c0.5-3.9,1.3-7.7,2.3-11.5
                c1.9-6.5,4.9-13.5,10.8-17c1.5-0.9,2.8-1.4,4.5-1.8C662.1,309.1,660.7,304.3,657.6,305L657.6,305z" />
        </g>
    </g>
    <g>
    <g>
    <path fill="#4995D1" d="M440.5,250.9c-16,11.7-28,28.2-34.6,46.9c-3.2,9.2-5,18.9-5.3,28.7c-0.1,5.1-0.1,10.5,1.8,15.3
                c1.9,4.8,5.6,8.3,10.3,10.3c4.5,1.9,9.4,2.6,14.3,3.1c5,0.5,9.9,0.6,14.9,0.3c9.9-0.6,19.7-2.6,29-6c9.4-3.4,18.3-8.2,26.2-14.2
                c4-3,7.9-6.3,11.3-10c3.6-3.9,6.7-9.3,4.6-14.7c-1.9-5-6.6-8.1-10.8-11c-4.5-3.2-9.1-6.1-13.9-8.8c-9.7-5.4-20-9.8-30.6-13.1
                c-2.6-0.8-5.2-1.5-7.8-2.2c-3.1-0.8-4.5,4-1.3,4.8c10.1,2.5,19.9,6.1,29.2,10.6c4.7,2.3,9.2,4.8,13.6,7.5
                c4.3,2.6,8.7,5.4,12.6,8.7c3.2,2.7,6,6.1,3.9,10.4c-2.1,4.2-6.1,7.5-9.6,10.5c-7,6-15,10.9-23.4,14.6c-8.3,3.7-17.3,6.2-26.3,7.3
                c-9.1,1.2-18.6,1.2-27.6-0.6c-4.1-0.8-8.3-2.1-11.3-5.1c-3.3-3.3-4-8.2-4.1-12.6c-0.3-9.1,0.9-18.2,3.4-26.9
                c5-17.5,15-33.6,28.9-45.4c1.7-1.4,3.4-2.8,5.1-4c1.1-0.8,1.6-2.2,0.9-3.4C443.3,250.7,441.6,250.1,440.5,250.9L440.5,250.9z" />
        </g>
    </g>
    </svg>
    
    @code {
        [Parameter]
        public float Xoffset { get; set; }
    
        [Parameter]
        public float Yoffset { get; set; }
    }