В следующем примере блок main
(синезелёный градиент) обрезается при помощи clip-path
и принимает форму сердечка. Однако видно, что он обрезается в масштабе 1:1, а хотелось бы, чтобы форма обрезки растягивалась по размеру блока (по аналогии с тем, как у background-size
работает cover
, contain
или 100% 100%
).
https://jsfiddle.net/a5goLyds/
html, body, main {
margin: 0;
height: 100%;
}
svg {
width: 10em;
float: right;
position: relative;
z-index: 1;
}
main {
background: linear-gradient(to bottom, green, blue);
clip-path: url(#heart-clip);
}
<svg viewBox="0 0 100 100" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path id="heart" fill="orange" stroke="red"
d="M 10,30
A 20,20 0,0,1 50,30
A 20,20 0,0,1 90,30
Q 90,60 50,90
Q 10,60 10,30 z"
/>
<clipPath id="heart-clip">
<use xlink:href="#heart" />
</clipPath>
</svg>
<main></main>
К сожалению я не нашёл clip-path
генераторов, которые позволяли бы рисовать кривыми линиями.
Есть генераторы, которые рисуют прямыми линиями по узловым точкам:
Для многоугольника получаю вот такие значения
clip-path: polygon(50% 0%, 80% 10%, 100% 35%, 100% 70%, 80% 90%, 50% 100%, 20% 90%, 0% 70%, 0% 35%, 20% 10%);
Преобразую для svg clip-path
в доли от единицы:
<polygon points="0.5,0 0.8,0.1 1,0.35 1,0.7 0.8,0.9 0.5,1 0.20,0.9 0,0.7 0,0.35 0.2,0.1" />
Чтобы получить масштабируемый clip-path
, например при наведении курсора, нужно менять размер изображения в сторону увеличения, соответственно увеличится и clip-path
, обрезая это изображение.
svg {}
main {
width: 15%;
height: 15%;
background: linear-gradient(to bottom, green, blue);
clip-path: url(#heart-clip);
transition: 1s;
}
main:hover {
width: 100%;
height: 100%;
}
<main>
<svg viewBox="0 0 1 1" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<clipPath id="heart-clip" clipPathUnits="objectBoundingBox">
<polygon
points="0.5,0 0.8,0.1 1,0.35 1,0.7
0.8,0.9 0.5,1 0.20,0.9 0,0.7 0,0.35 0.2,0.1" />
</clipPath>
</defs>
</svg>
</main>
Ничего не меняя в авторском примере - ввожу туда:
<use xlink:href="#heart" transform="scale(5), translate(-10 -10)"/>
Итог:
html,
body,
main {
margin: 0;
height: 100%;
}
svg {
width: 10em;
float: right;
position: relative;
z-index: 1;
}
main {
background: linear-gradient(to bottom, green, blue);
clip-path: url(#heart-clip);
}
<svg viewBox="0 0 100 100" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path id="heart" fill="orange" stroke="red"
d="M 10,30
A 20,20 0,0,1 50,30
A 20,20 0,0,1 90,30
Q 90,60 50,90
Q 10,60 10,30 z"
/>
<clipPath id="heart-clip">
<use xlink:href="#heart" transform="scale(6), translate(-10 -10)"/>
</clipPath>
</svg>
<main></main>
В результате можно добиться любой пропорции и положения патча, регулируя лишь
transform="scale(what), translate(x y)"
Однако это ещё не всё.
Там, где было <clipPath id="heart-clip">
, добавим clipPathUnits="objectBoundingBox"
, но при этом не забудем подкорректировать scale()
, чтобы результат от "d" всегда был меньше единицы, как у Александра в полигоне.
- И вот оно, долгожданное счастье!
В песочнице будет легче менять размеры рабочей области, чтобы убедиться в искомой "респонсивности" элемента.
Но пробуем описать его и здесь:
html, body {
margin: 0;
background: repeating-linear-gradient(45deg, #666, #222, #666, #ea8, #666, #222, #666, #8ce, #666 4%) fixed;
}
svg {
width: 10rem;
float: right;
position: relative;
z-index: 1;
}
main {
height: 100vw;
clip-path: url(#heart-clip);
background: linear-gradient(to bottom, blue, red, green, transparent 70%);
}
<svg viewBox="0 0 100 100"
xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path id="heart" fill="orange" stroke="red"
d="M 10,30
A 20,20 0,0,1 50,30
A 20,20 0,0,1 90,30
Q 90,60 50,90
Q 10,60 10,30 z" />
<clipPath id="heart-clip" clipPathUnits="objectBoundingBox">
<use xlink:href="#heart" transform="scale(.007,.007), translate(-6 -6)"/>
</clipPath>
</svg>
<main></main>
Я бы реализовал так, а градиент уже реализовал бы в самом SVG
html,
body {
width: 100%;
height: 100%;
background: #242424;
}
main {
width: 100%;
height: 100%;
background-image: url('data:image/svg+xml, <svg xmlns="http://www.w3.org/2000/svg" viewBox=" 0 0 100 100" width="100%" height="100%"><path id="heart" fill="orange" stroke="red" d="M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z"></path>);</svg>');
background-repeat: no-repeat;
background-size: 100% 100%;
}
<main></main>
В IE11 из-за вложенного флексбокса текст не переходит на следующую строку, а растягивается на весь контент, если же поставить дляitem width:100%, блоки...
Не знал, как точно сформировать вопрос, поэтому сразу прошу прощения
Суть в том, что svg фигура в clipPath отрисовывается как есть, по тем самым размерам, с которыми создана
Использую либу highchartsВстал вопрос - как вместо маркеров использовать диаграмму