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.
В цигулката искам маската на елипса да е вътре в червения правоъгълник (видим zzz's area), но вместо това е вътре в зелен правоъгълник (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
mmh, мислех по линия на използването на userSpaceOnUse в комбинация с процентни стойности вътре в маската. Доколкото разбирам, процентите трябва да са относителни към потребителската координатна система за елемента, препращащ към елемента ‹mask›, който за съжаление не е реализиран по този начин :-( - person Holger Will; 19.09.2015
comment
Да, може да се мисли, според помощта, че вътре в маската е използвана координатна система от елемента, препращащ към маската, използвайки атрибута mask. За съжаление или английският ми е твърде лош и не мога да разбера правилно помощта, или помощта е по някакъв начин грешна. Съдържание на маската, използвайки координатна система от мястото, дефинирано от маската. Може лесно да се тества: jsfiddle.net/lazyeugene/wq1gg29j Така че, за да приложите една маска към много различни елементи, трябва да го клонирам вътре в тези елементи, така че маската да използва координатната система на елемента за процентни стойности. - person lazyeugene; 20.09.2015