3 Вопрос: Как мне масштабировать определенные точки, оставляя другие точки в покое?

вопрос создан в Wed, May 8, 2019 12:00 AM

У меня есть SVG, который был создан с одним поли, который используется для границы привязки. Проблема, с которой я сталкиваюсь, заключается в том, что я хочу, чтобы кнопка поддерживала переменное содержимое - позволяя кнопке изменять размер по мере необходимости, чтобы соответствовать размеру, при этом ограничивая угол боковых линий.

Кажется, я не могу понять, нужно ли мне каким-то образом разбивать оригинальный поли, настраивать viewBox или что-то еще. Мы в тупике.

Встроенный SVG, который я использую, довольно прост:

р>

* { box-sizing: border-box; }

.btn {
  width: 198px;
  display: inline-block;
  background: transparent;
  margin: 2px 0;
  padding: 0;
  height: 41px;
  text-align: center;
  font-size: 10px;
  line-height: 41px;
  font-weight: 600;
  font-family: sans-serif;
  text-transform: uppercase;
  color: #FFF;
  position: relative;
  transition: all ease-in-out 0.3s; }
  .btn.btnFluid {
    width: auto; }
    .btn.btnFluid svg {
      width: 100%;
      height: 41px; }
  .btn svg polygon {
    fill: #000;
    transition: fill 0.3s ease;
    stroke: #002b5d;
    stroke-width: 2; }
  .btn:hover {
    color: #000; }
    .btn:hover svg polygon {
      stroke: #000;
      fill: #FFF; }
  .btn span {
    position: absolute;
    z-index: 1;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    display: block;
    padding: 0 25px; }

svg:not(:root) {
  overflow: hidden; }

  
<a href="#" class="btn">
  <svg xmlns="http://www.w3.org/2000/svg" class="btn-svg" viewBox="0 0 386.16 80">
    <polygon points="346.14 78 40.02 78 3.19 2 382.97 2 346.14 78"></polygon>
   </svg>
  <span>Read More</span>
</a>
<br><br>
<a href="#" class="btn btnFluid">
  <svg xmlns="http://www.w3.org/2000/svg" class="btn-svg" viewBox="0 0 386.16 80" preserveAspectRatio="none">
    <polygon points="346.14 78 40.02 78 3.19 2 382.97 2 346.14 78"></polygon>
  </svg>
  <span>A much longer cta button label</span>
</a>

Я создал редактируемую демонстрацию здесь: https://jsfiddle.net/32wcq1zr/1/ - сравнить угол бокового края первой кнопки со второй кнопкой. В идеале я хотел бы иметь функциональность второй кнопки, но с постоянным углом боковых линий.

    
1
3 ответа                              3                         

С этой конкретной формой другие варианты, представленные здесь (с использованием элементов pseudo или masks), являются лучшими решениями. Тем не менее, вот хорошая альтернатива для более сложных форм.

CSS border-image существует довольно давно, имеет достаточно хорошую поддержку , AND допускает 9-фрагментное масштабирование .

9-фрагментное масштабирование позволяет вам решить, «как» масштабируется каждая часть изображения, разбивая изображение на квадранты, представляющие все 4 угла, 4 стороны и усиление; центр.

Вы можете использовать border-image либо с изображением, либо с SVG, но изображение гораздо более прямолинейно. Кирс Койер предлагает хороший обзор .

Вот пример использования вашей фигуры

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

 введите описание изображения здесь (100px x 40px с нижней вставкой 20px)

р>

a {
  display:inline-block;
  text-decoration: none;
  margin: 10px;
  color: #fff;
  padding: 0 10px;
  border: 20px solid black;
  border-image: url(https://i.stack.imgur.com/T8TC6.png);
  border-image-slice: 0 20% fill;
  border-image-width: auto;
}
<a href="#">short</a>

<a href="#">much longer text that causes things to scale</a>

И более сложная форма, чтобы показать, как это работает:

 введите описание изображения здесь

р>

a {
  display:inline-block;
	text-decoration:none;
  margin: 10px;
	color: #fff;
	padding: 0 10px;
	border: 20px solid;
  border-image: url(https://i.stack.imgur.com/pUwi4.png);
	border-image-slice: 15 fill;
	border-image-width: auto;
	border-image-repeat: round;
}
<a href="#">short</a>

<a href="#">much longer text that causes things to scale</a>
    
2
2019-05-08 21: 57: 48Z

Это альтернативное решение вашей проблемы. Вместо использования SVG это может быть сделано с прозрачными границами и текстом в :: before /:: after

р>

.button {
  --h:50;
  width: 198px;
  display: inline-block;
  border: calc(var(--h) * 1px) solid black;
  border-left-color: transparent;
  border-right-color: transparent;
  border-bottom: none;
  position:relative;
}

.button::before {
  content: "Read More";
  color: white;
  display: block;
  width: 100%;
  height:calc(var(--h) * 1px);
  position: absolute;
  top: calc(var(--h) * -1px);
  left: 0;
  text-align: center;
  line-height:calc(var(--h) * 1px);
  font-weight: 600;
  font-family: sans-serif;
  text-transform: uppercase;
}

.button.long{width:300px}

.button.long::before{content:"A much longer cta button label"}
<div class="button"></div>
<div class="button long"></div>
    
1
2019-05-08 18: 37: 22Z

«Эластичные» SVG, подобные тем, которые вам нужны, в общем случае невозможны.

Но при определенных обстоятельствах этого можно добиться, используя некоторые приемы с элементами <use> и <mask>.

Как это работает, мы разбиваем кнопку на две фигуры. Один для левого конца (#left) и один для среднего и правого конца (#right). Правильный сделан очень длинным, так что он может вместить диапазон размеров кнопок. Правая часть расположена напротив правого конца SVG и замаскирована так, чтобы не закрывать левую часть.

р>

* { box-sizing: border-box; }

.btn {
  width: 198px;
  display: inline-block;
  background: transparent;
  margin: 2px 0;
  padding: 0;
  height: 41px;
  text-align: center;
  font-size: 10px;
  line-height: 41px;
  font-weight: 600;
  font-family: sans-serif;
  text-transform: uppercase;
  color: #FFF;
  position: relative;
  transition: all ease-in-out 0.3s; }
  .btn.btnFluid {
    width: auto; }
    .btn.btnFluid svg {
      width: 100%;
      height: 41px; }
  .btn svg .highlight {
    fill: #000;
    transition: fill 0.3s ease;
    stroke: #002b5d;
    stroke-width: 2; }
  .btn:hover {
    color: #000; }
    .btn:hover svg .highlight {
      stroke: #000;
      fill: #FFF; }
  .btn span {
    position: absolute;
    z-index: 1;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    display: block;
    padding: 0 25px; }

svg:not(:root) {
  overflow: hidden; }
<a href="#" class="btn">
  <svg class="btn-svg" width="100%">
    <defs>
      <polyline id="left" points="21,1, 1,1, 20,40, 21,40"/>
      <polyline id="right" points="-1500,1, -1,1, -20,40, -1500,40"/>
      <mask id="mask-right">
        <rect width="100%" height="100%" fill="white"/>
        <rect width="20" height="100%" fill="black"/>
      </mask>
    </defs>
    <g class="highlight" mask="url(#mask-right)">
      <use xlink:href="#right" x="100%"/>
    </g>
    <use class="highlight" xlink:href="#left"/>
  </svg>
  <span>Read More</span>
</a>
<br><br>
<a href="#" class="btn btnFluid">
  <svg class="btn-svg" width="100%">
    <defs>
      <polyline id="left2" points="21,1, 1,1, 20,40, 21,40"/>
      <polyline id="right2" points="-1500,1, -1,1, -20,40, -1500,40"/>
      <mask id="mask-right2">
        <rect width="100%" height="100%" fill="white"/>
        <rect width="20" height="100%" fill="black"/>
      </mask>
    </defs>
    <g class="highlight" mask="url(#mask-right2)">
      <use xlink:href="#right" x="100%"/>
    </g>
    <use class="highlight" xlink:href="#left2"/>
  </svg>
  <span>A much longer cta button label</span>
</a>
    
1
2019-05-09 03: 21: 44Z
источник размещен Вот