#svg
Вопрос:
Ожидайте, что встроенный фрагмент кода ниже создаст экран, подобный изображению в Firefox, и т. Д. Два отсоединенных изображения показаны внизу для справки — одно пейзажное и одно портретное. Выше приведены четыре демонстрационные формы, которые я хочу покрыть изображениями, на самом деле ничего не зная об изображении — в идеале я мог бы заменить только URL-адреса и получить все «правильные» изображения, избегая какой-либо математики или условий.
Шаблоны и изображения должны быть идентичными, а не соответствовать демонстрационным сценариям. В конечном итоге мне нужна всего ОДНА такая форма в шаблоне svg, удовлетворяющая любому введенному изображению.
Я думаю, что я определенно хочу xMidYMid
и рисунка, и изображения. Я перепробовал множество перестановок атрибутов viewBox, heights, width, slice
/ meet
, patternContentUnits и patternUnits.
Я даже не могу понять, до чего масштабируются «неправильные» изображения. Похоже, что две демо-версии каждого изображения имеют точно такой же масштаб (потому что все демонстрационные прямоугольники имеют длину 490 в длинном направлении, и это похоже на то, что короткая сторона изображения сопоставляется с длинной стороной прямой или что-то в этом роде??)
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg viewBox="0 0 1020 1220" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<pattern
id="patternA"
height="1"
width="1"
viewBox="0 0 1 1"
patternContentUnits="objectBoundingBox"
preserveAspectRatio="xMidYMid slice">
<image
id="imageA"
width="1" height="1"
preserveAspectRatio="xMidYMid slice"
transform=""
xlink:href="https://images.unsplash.com/photo-1625507371147-797709a083a6?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8amp;amp;ixlib=rb-1.2.1amp;amp;auto=formatamp;amp;fit=cropamp;amp;w=334amp;amp;q=80" />
</pattern>
<pattern
id="patternB"
height="1"
width="1"
viewBox="0 0 1 1"
patternContentUnits="objectBoundingBox"
preserveAspectRatio="xMidYMid slice">
<image
id="imageB"
width="1" height="1"
preserveAspectRatio="xMidYMid slice"
transform=""
xlink:href="https://images.unsplash.com/photo-1625508200971-f63b282addb8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8amp;amp;ixlib=rb-1.2.1amp;amp;auto=formatamp;amp;fit=cropamp;amp;w=1189amp;amp;q=80" />
</pattern>
<pattern
id="patternC"
height="1"
width="1"
viewBox="0 0 1 1"
patternContentUnits="objectBoundingBox"
preserveAspectRatio="xMidYMid meet">
<image
id="imageC"
width="1" height="1"
preserveAspectRatio="xMidYMid meet"
transform=""
xlink:href="https://images.unsplash.com/photo-1625507371147-797709a083a6?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8amp;amp;ixlib=rb-1.2.1amp;amp;auto=formatamp;amp;fit=cropamp;amp;w=334amp;amp;q=80" />
</pattern>
<pattern
id="patternD"
height="1"
width="1"
viewBox="0 0 1 1"
patternContentUnits="objectBoundingBox"
preserveAspectRatio="xMidYMid meet">
<image
id="imageD"
width="1" height="1"
preserveAspectRatio="xMidYMid meet"
transform=""
xlink:href="https://images.unsplash.com/photo-1625508200971-f63b282addb8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8amp;amp;ixlib=rb-1.2.1amp;amp;auto=formatamp;amp;fit=cropamp;amp;w=1189amp;amp;q=80" />
</pattern>
</defs>
<rect
style="fill:url(#patternA);stroke:black;"
x="10"
y="10"
width="490"
height="200" />
<rect
style="fill:url(#patternB);stroke:blue;"
x="510"
y="10"
width="500"
height="200" />
<rect
style="fill:url(#patternA);stroke:red;"
x="160"
y="220"
width="200"
height="490" />
<rect
style="fill:url(#patternB);stroke:green;"
x="670"
y="220"
width="200"
height="490" />
<rect
style="fill:url(#patternC);stroke:black;"
x="10"
y="720"
width="490"
height="490" />
<rect
style="fill:url(#patternD);stroke:black;"
x="510"
y="720"
width="490"
height="490" />
</svg>
Вместо этого «неправильные» демонстрации должны быть такими, чтобы изображение в основном начиналось с 0x0 в центре и увеличивалось только до тех пор, пока изображение точно не покроет прямоугольник, но не далее:
Здесь есть похожие вопросы, так что я уже использовал их, чтобы зайти так далеко.
Комментарии:
1. И вы должны использовать шаблон, верно? Он будет использоваться поверх непрямоугольных фигур?
2. да, он будет использоваться на произвольном пути с помощью ограничивающего прямоугольника — я предполагал, что ответ будет легко применить, но об этом было бы проще спросить.
3. Конечно, просто подтвердите, что вернуться к простому делу <изображение> невозможно.
Ответ №1:
Я не думаю, что то, чего ты хочешь, невозможно сделать. Для того чтобы изображение было правильно масштабировано в соответствии с формой с помощью meet
или slice
, необходимо знать размер изображения.
В ваших первоначальных попытках там нет ничего, что дало бы визуализатору какое-либо представление о фактических размерах изображений. Или даже каковы их пропорции.
Например
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg viewBox="0 0 1020 1220" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<pattern
id="patternA"
height="1"
width="1"
viewBox="0 0 3977 5965"
patternContentUnits="objectBoundingBox"
preserveAspectRatio="xMidYMid slice">
<image
id="imageA"
width="3977" height="5965"
xlink:href="https://images.unsplash.com/photo-1625507371147-797709a083a6?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8amp;amp;ixlib=rb-1.2.1amp;amp;auto=formatamp;amp;fit=cropamp;amp;w=334amp;amp;q=80" />
</pattern>
<pattern
id="patternB"
height="1"
width="1"
viewBox="0 0 3941 2217"
patternContentUnits="objectBoundingBox"
preserveAspectRatio="xMidYMid slice">
<image
id="imageB"
width="3941" height="2217"
xlink:href="https://images.unsplash.com/photo-1625508200971-f63b282addb8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8amp;amp;ixlib=rb-1.2.1amp;amp;auto=formatamp;amp;fit=cropamp;amp;w=1189amp;amp;q=80" />
</pattern>
</defs>
<rect
style="fill:url(#patternA);stroke:black;"
x="10"
y="10"
width="490"
height="200" />
<rect
style="fill:url(#patternB);stroke:blue;"
x="510"
y="10"
width="500"
height="200" />
<rect
style="fill:url(#patternA);stroke:red;"
x="160"
y="220"
width="200"
height="490" />
<rect
style="fill:url(#patternB);stroke:green;"
x="670"
y="220"
width="200"
height="490" />
<rect
style="fill:url(#patternA);stroke:black;"
x="10"
y="720"
width="490"
height="490" />
<rect
style="fill:url(#patternB);stroke:black;"
x="510"
y="720"
width="490"
height="490" />
</svg>
Комментарии:
1. «размер изображения должен быть известен», браузер, безусловно, знает это, иначе как бы
preserveAspectRatio
он работал с <изображением>? Дело в том, что размер целевого элемента должен передаваться <изображению> через <изображение><шаблон>, и я не уверен, что это можно сделать…2. Я имел в виду, что если операция использует функцию сохранения на изображении, то информация об исходных границах изображения будет потеряна, и они не получат правильный/желаемый результат в шаблоне. Это потому, что в этот момент изображение фактически представляет собой «квадрат 1×1 с изображением где-то внутри».
3. Но почему это квадрат 1×1, а не прямая 490×200, которую сейчас должен определять шаблон? Они установили элементы Patterncontent для сопоставления с целевым элементом (ну, на самом деле они сделали это с помощью viewBox, но в любом случае все заканчивается одинаково), поэтому, в моем понимании, width=»1″ должна быть полной шириной целевого элемента (490 единиц), а height=»1″ должна быть полной высотой (200 единорогов). Что заставляет распространение размера останавливаться где-то посередине?
4. Спасибо. Если я установлю высоту и ширину изображения рисунка прямой кишки и поле просмотра рисунка прямой кишки на значения, соответствующие соотношению сторон прямой кишки, то я получу желаемое поведение. Это неоптимально, потому что это означает предварительное вычисление ограничивающей рамки моей цели, но в моем случае это может сработать. До сих пор вы помогали мне видеть, что квадрат 1×1 изображения эффективно обрезает его до покрывающего квадрата, затем шаблон масштабирует этот квадрат, чтобы покрыть прямую линию, объясняя эффект масштабирования, который мне не понравился.
5. Но почему это квадрат ? При
objectBoundingBox
этом единица измерения должна быть относительно размера цели, так что 1-это как CSS 100%, если хотите. Так почему же в контексте неквадратичной цели 1×1 (т. е. 100% х 100%) является квадратом?