Элементы управления типа полосы прокрутки для панорамирования SVG

У меня есть SVG, в котором я хочу панорамировать окно просмотра над изображением. Например, если у меня есть SVG с элементами в любом месте в области 0->1000 на 0->1000 и я установил (квадратное) поле просмотра на 0 0 500 500, я получаю верхнюю левую четверть; Я установил поле просмотра на 250 250 500 500 и получил середину, как и ожидалось.

У меня есть:

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

частная строка SvgViewBox => $"{PanHorizontal} {PanVertical} {ViewBoxWidth} {ViewBoxHeight}";

Я могу установить значения PanHorizontal, PanVertical и т. д., чтобы отображать различные части SVG.

Мне бы очень хотелось, чтобы что-то вроде полос прокрутки было привязано к PanHorizontal и PanVertical . Я пробовал FluentSlider с горизонтальным и вертикальным выравниванием, но не смог понять, как правильно расположить их вокруг SVG.

Это проблема css? Если да, то как разместить элементы управления справа и под SVG? Есть предположения?

Я сделал несколько попыток расположить слайдер флютенца, но я в неведении.

Я бы не использовал полосы прокрутки. Я бы использовал перетаскивание с помощью значка руки, чтобы вы могли перемещать его, как карту.

Bennyboy1973 16.06.2024 04:04

@Bennyboy1973 У меня двоякое мнение по этому поводу. С одной стороны, это легко (в данном случае для меня) реализовать, с другой стороны, в SVG могут быть элементы, которые пользователь перетаскивает... поэтому пользователю либо нужно будет найти место в "фоновом режиме", или переключитесь между перетаскиванием всего изображения или только элемента. Я не знаю, как решить, полосы прокрутки лучше или хуже.

Jamie_M_ 16.06.2024 08:23

Я не знаю, что вы пытаетесь сделать, поэтому не могу ничего сказать. Все эти варианты жизнеспособны. Я не уверен, как SVG взаимодействует с метриками javascript/html. Я подозреваю, что вам придется выполнить «перетаскивание» с помощью JavaScript, а затем вычислить, сколько объектов (или всего представления) переместилось на основе переменной масштаба. Но вы не хотите, чтобы текущие обновления позиции вычислялись на C# на основе событий перетаскивания на интерактивном сервере, потому что это не удастся, если вы добавите реальную веб-задержку. Возможно, придется сделать эту часть WASM?

Bennyboy1973 16.06.2024 10:50

кстати, я дал демо с использованием слайдера. Это связано с тем, что слайдер может иметь дискретные шаги, что значительно снижает задержку из-за простого перетаскивания в JavaScript.

Bennyboy1973 16.06.2024 10:53

Привет @Bennyboy1973, перетаскивание на самом деле не так уж и сложно. События мыши в svg в blazor работают хорошо. В начале операции перетаскивания требуется только один вызов JSinterop, чтобы получить размер элемента svg на экране, а функция, основанная на размере на экране, поле просмотра и координатах клиента мыши, дает мне координаты в пространстве svg. В моем случае элементы в SVG объединены в группы, поэтому можно быстро и легко перемещаться по иерархии групп, чтобы добраться до элемента, содержащего координаты указателя. Панорамирование всего SVG выполняется быстро (без мерцания) за счет изменения поля просмотра SVG.

Jamie_M_ 16.06.2024 12:22

Просто помните: убедитесь, что вы не выполняете взаимодействие между интерактивным сервером и JavaScript для событий, которые могут срабатывать очень часто, например событий перетаскивания. Когда вы развернете их онлайн, возникнут проблемы, которых нет на вашей машине разработки. Если вам нужна быстрая обратная связь, вам нужно, чтобы она была только на стороне клиента.

Bennyboy1973 16.06.2024 13:51

@Bennyboy1973 WASM полностью

Jamie_M_ 16.06.2024 14:12
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
0
7
64
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Родительский элемент SVG может обрабатывать полосы прокрутки:

div.box {
  width: 300px;
  height: 300px;
  overflow: scroll;
}
<div class = "box">
  <svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 100 100"
    width = "1000" height = "1000">
    <circle cx = "50" cy = "50" r = "50" fill = "orange"  />
  </svg>
</div>

Спасибо за ответ, я больше занимаюсь программированием, чем дизайном пользовательского интерфейса, поэтому думаю, что не уверен в некоторых вещах. Ваш ответ: как код приложения «знает», какая часть SVG видна? Как код приложения может контролировать, какая часть SVG отображается? Как числовые значения, которые вы включили в свой ответ, сопоставляются со значениями, которые я упоминаю в своем вопросе?

Jamie_M_ 15.06.2024 09:43

У меня есть еще одна мысль по поводу вашего ответа: я вижу, что полосы прокрутки будут отображаться для панорамирования содержимого поля просмотра, но не вижу, как это помогает перемещать поле просмотра по SVG.

Jamie_M_ 15.06.2024 10:17
Ответ принят как подходящий

SVG — это разметка XML, очень похожая на HTML, что означает, что вы можете параметризовать все, что захотите, в данном случае смещение вашего поля просмотра. Я думаю, вы могли бы буквально создать целый сайт со всем SVG, включая анимацию и т. д. Я рекомендую создать отдельный компонент .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;
}

Форма1.бритва

<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; }
}

Привет, это помогло мне понять, как разместить ползунки Fluent-UI там, где я хотел. Спасибо

Jamie_M_ 16.06.2024 12:13

Другие вопросы по теме