маска SVG и ограничивающая рамка

Мне нужно применить маску к другим объектам.
Маска должна покрывать весь объект (видимую его часть). Я поместил маску в одно конкретное место, вверху страницы, изменил maskContentUnits на objectBoundingBox, так что она работала отлично.

Но тут возникла проблема.

Я сделал скрипку, чтобы проиллюстрировать проблему: http://jsfiddle.net/8qdt7vjr/1/

<body>
    <svg width="0" height="0">
        <defs>
            <mask id="mask1" maskContentUnits="objectBoundingBox">
                <ellipse cx=".5" cy=".5" rx=".5" ry=".5" fill="white" />
            </mask>
        </defs>
    </svg>
    <svg class="svg" width="200" height="150" overflow="visible">
        <rect x="-50" y="-50" width="350" height="250" fill="none" stroke="green" stroke-width="2" />
        <svg id="zzz" x="0" y="0" width="100%" height="100%" overflow="visible" mask="url(#mask1)">
            <rect x="-50" y="-50" width="350" height="250" fill="blue" fill-opacity=".3" />
        </svg>
        <rect width="100%" height="100%" fill="red" fill-opacity=".1" stroke="red" stroke-width="1" />
    </svg>
</body>

В этой скрипке я хочу применить маску к элементу svg с id="zzz". Но внутри этого элемента есть элемент rect, увеличивающий ограничивающую рамку zzz. В скрипте это rect, но в моем проекте это тег image. zzz имеет значение скрытого переполнения (в скрипте я изменил его на видимый, чтобы было легче увидеть проблему), поэтому у меня есть определенная часть изображения, видимая внутри zzz .

Настоящая проблема заключается в том, что внутреннее содержимое zzz увеличивает ограничивающую рамку zzz.
В скрипте я хочу, чтобы маска эллипса находилась внутри красного прямоугольника (visible zzz), но вместо этого он находится внутри зеленого прямоугольника (ограничивающая рамка zzz).

Итак, главный вопрос: есть ли способ достичь этой цели? Маска будет использоваться многими элементами с разными размерами и содержимым, и я не хочу ее клонировать.

Есть ли способ сделать это без клонирования маски внутри каждого элемента?
Есть ли способ уменьшить ограничивающую рамку до видимой области?
Есть ли способ показать часть изображения, не расширяя ограничивающую рамку родителя? < br> Есть ли другой способ сделать это?


person lazyeugene    schedule 19.09.2015    source источник
comment
Ответ на вторую и третью части - нет. Это затрудняет ответ на первый и четвертый случаи.   -  person Robert Longson    schedule 19.09.2015


Ответы (1)


Вы пытаетесь достичь чего-то подобного?

<body>
    <svg width="0" height="0">
        <defs>
            <mask id="mask1" maskContentUnits="userSpaceOnUse">
                <ellipse cx="100" cy="75" rx="100" ry="75" fill="white" />
            </mask>
        </defs>
    </svg>
    <svg class="svg" width="200" height="150" overflow="visible">
        <rect x="-50" y="-50" width="350" height="250" fill="none" stroke="green" stroke-width="2" />
        <svg id="zzz" x="0" y="0" width="100%" height="100%" overflow="visible" mask="url(#mask1)">
            <rect x="-50" y="-50" width="350" height="250" fill="blue" fill-opacity=".3" />
        </svg>
        <rect width="100%" height="100%" fill="red" fill-opacity=".1" stroke="red" stroke-width="1" />
    </svg>
</body>

Возможно, использование userSpaceOnUse вместо objectBoundingBox может помочь достичь того, чего вы хотите ... В сочетании с вложенными элементами svg вы можете определить используемое пользовательское пространство и с этой частью маска применяется к ...

person Holger Will    schedule 19.09.2015
comment
Вот как я использую сейчас. Но в моем случае я не знаю размеров svg с тегом mask. Фактически существует несколько разных элементов с одинаковой маской. Сейчас я использую клон исходной маски для каждого элемента, и я хочу избежать клонирования. - person lazyeugene; 19.09.2015
comment
userSpaceOnUse - это система координат элемента, к которому применяется маска, а не откуда она берется. В вашем случае это будет родительский элемент svg zzz. Может быть, вы можете опубликовать пример, где использование userSpaceOn не работает? - person Holger Will; 19.09.2015
comment
Пример: jsfiddle.net/04nz92d9 Маску нельзя правильно применить к обоим элементам: zzz1 и zzz2. С maskContentUnits="objectBoundingBox" это можно сделать легко, но есть проблема с ограничивающей рамкой, расширенной содержимым блока. - person lazyeugene; 19.09.2015
comment
Ммм, я думал об использовании userSpaceOnUse в сочетании с процентными значениями внутри маски. Насколько я понимаю, проценты должны быть относительно пользовательской системы координат для элемента, ссылающегося на элемент ‹mask›, который, к сожалению, не реализован таким образом :-( - person Holger Will; 19.09.2015
comment
Да, можно подумать, судя по справке, что внутри маски использовалась система координат от элемента, ссылающегося на маску с помощью атрибута mask. К сожалению, либо мой английский слишком плох, и я не могу правильно понять помощь, либо помощь как-то не так. Маска содержимого с использованием системы координат с того места, где задана маска. Это легко проверить: jsfiddle.net/lazyeugene/wq1gg29j Итак, чтобы применить одну маску ко многим разные элементы, мне нужно клонировать его внутри этих элементов, чтобы маска использовала систему координат элемента для процентных значений. - person lazyeugene; 20.09.2015