LenovoId
@LenovoId
svg, css,js

Как получить из SVG координаты для css clip-path?

Как верно сформулировать вопрос не знаю но суть такая:
Имеем некий svg => path="M........z".
Я хочу получить из него css => clip-path .

Разумеется что Google и Yandex я загнул но не знаю верные ли я пишу теги для поиска .
Писал так: svg path to clip-path .....

Нашёлся такой плагин в NPM: https://www.npmjs.com/package/clip-svg
Описание там конечно Жесть ... что в READMY что в описание по ссылке

Есть ли какой то способ получить из SVG clip-path css ?
Или опытных в js поясните как пользоваться этой приблудой с NPM

Это js из NPM
#!/usr/bin/env node

var fs = require('fs');
var file = process.argv[2];

function round(x) {
  return parseFloat(x.toFixed(2));
}

function bail(errorMsg) {
  console.log(errorMsg);
  process.exit(1);
}

function descriptor2clipPath(descriptor) {
  // Divide string into coordinate strings
  var points = descriptor.split(' ');
  // Divide these strings into arrays of float pairs ([x1, y1], [x2, y2], ...)
  points = points.map(value => value.split(',').map((string) => {
    return round(parseFloat(string));
  }));

  for (var key in points) {
    if ([0, 1].some((index) => isNaN(points[key][index]))) {
      bail('Error: Malformed descriptor');
    }
  }

  var start = points[0];
  var relativePoints = points.slice(1);
  // Convert relative points to absolute points
  var sum = start.map((value) => round(value));
  var absolutePoints = relativePoints.map(pair => {
    sum = pair.map(function (num, i) {
      return round(num + sum[i]);
    });
    return sum;
  });
  var newPoints = [start].concat(absolutePoints);
  var polygonString = 'clip-path: polygon('
  newPoints.forEach((point) => {
    polygonString += `${point[0]}% ${point[1]}%,`
  });
  polygonString = polygonString.slice(0, -1) + ');'
  console.log(polygonString);
}

if (!file || !fs.existsSync(file)) {
  bail('Usage: clip-path [SVG file]');
}

fs.readFile( file, 'utf8', function (err, buffer) {
  if ( err ) { bail('Error: File I/O'); }

  // Parse for SVG path descriptor
  var descriptors = buffer.match(/ d="m ([^z]*) z"/g);

  if (!descriptors || descriptors.length === 0) {
    bail('Error: no matches');
  }

  descriptors = descriptors.map((descriptor) => descriptor.slice(6, -3));

  descriptors.forEach((descriptor) => {
    descriptor2clipPath(descriptor);
  });
});
  • Вопрос задан
  • 1331 просмотр
Решения вопроса 1
RAX7
@RAX7
Берем картинку, рисуем поверх нее произвольный path (красным), который будем использовать в качестве clip-path
spoiler
5d1c878eacfbb469570535.jpeg

Выделяем все точки которые мы хотим преобразовать в прямые сегменты и применяем к ним Object -> Path -> Add Anchor Points несколько раз
spoiler

5d1c8851bd065963376838.jpeg
5d1c887397475906603386.jpeg

Конвертируем точки: сначала в "to smooth", затем в "to corner"
spoiler
5d1c89fe9e01c670216387.jpeg

На этом этапе должен получиться полигон без скругленных отрезков, только прямые отрезки.
Дорисовываем на фоне прямоугольник (синий) по размерам картинки и группируем наш полигон и прямоугольник.
spoiler
5d1c8ae61153f469451884.jpeg

Отключаем в иллюстраторе выравнивание по пиксельной сетке и задаем группе размер 1px x 1px
spoiler
5d1c8b7f1d61e892849482.jpeg

Экспортируем получившуюся штуку, точность кривых ставим минимум 2 знака после запятой, но лучше чуть больше.
spoiler
5d1c8c2a1f712855868693.jpeg

Открываем полученный SVG:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1 1">
  <defs>
    <style>
      .cls-1 {
        fill: blue;
      }

      .cls-2 {
        fill: red;
        opacity: 0.7;
      }
    </style>
  </defs>
  <title>Asset 3</title>
  <g id="Layer_2" data-name="Layer 2">
    <g id="Layer_1-2" data-name="Layer 1">
      <g>
        <rect class="cls-1" width="1" height="1"/>
        <polygon class="cls-2" points="0.755 0.346 0.763 0.326 0.768 0.304 0.772 0.28 0.773 0.255 0.765 0.191 0.741 0.138 0.706 0.103 0.663 0.09 0.631 0.097 0.602 0.118 0.579 0.149 0.562 0.19 0.551 0.175 0.538 0.164 0.524 0.157 0.508 0.155 0.479 0.164 0.455 0.188 0.439 0.224 0.433 0.267 0.433 0.272 0.434 0.276 0.434 0.281 0.434 0.285 0.346 0.285 0.257 0.285 0.169 0.285 0.08 0.285 0.08 0.422 0.08 0.56 0.08 0.698 0.08 0.835 0.243 0.835 0.407 0.835 0.57 0.835 0.733 0.835 0.733 0.791 0.733 0.747 0.733 0.703 0.733 0.659 0.735 0.66 0.737 0.66 0.74 0.66 0.742 0.66 0.783 0.648 0.816 0.614 0.838 0.564 0.847 0.502 0.84 0.446 0.82 0.398 0.791 0.364 0.755 0.346"/>
      </g>
    </g>
  </g>
</svg>

единственный polygon - это и есть наш clip-path, осталось домножить цифры на 100, дорисовать знак "%" и разбить цифры попарно, вставив между ними запятые.
"0.755 0.346 0.763 0.326 0.768 0.304 0.772 0.28 0.773 0.255 0.765 0.191 0.741 0.138 0.706 0.103 0.663 0.09 0.631 0.097 0.602 0.118 0.579 0.149 0.562 0.19 0.551 0.175 0.538 0.164 0.524 0.157 0.508 0.155 0.479 0.164 0.455 0.188 0.439 0.224 0.433 0.267 0.433 0.272 0.434 0.276 0.434 0.281 0.434 0.285 0.346 0.285 0.257 0.285 0.169 0.285 0.08 0.285 0.08 0.422 0.08 0.56 0.08 0.698 0.08 0.835 0.243 0.835 0.407 0.835 0.57 0.835 0.733 0.835 0.733 0.791 0.733 0.747 0.733 0.703 0.733 0.659 0.735 0.66 0.737 0.66 0.74 0.66 0.742 0.66 0.783 0.648 0.816 0.614 0.838 0.564 0.847 0.502 0.84 0.446 0.82 0.398 0.791 0.364 0.755 0.346"
  .split(' ')
  .map((p, i) => Math.round(Number(p) * 10000) / 100 + '%' + ((i % 2) ? ',' : ''))
  .join(' ')
// '75.5% 34.6%, 76.3% 32.6%, 76.8% 30.4%, 77.2% 28%, 77.3% 25.5%, 76.5% 19.1%, 74.1% 13.8%, 70.6% 10.3%, 66.3% 9%, 63.1% 9.7%, 60.2% 11.8%, 57.9% 14.9%, 56.2% 19%, 55.1% 17.5%, 53.8% 16.4%, 52.4% 15.7%, 50.8% 15.5%, 47.9% 16.4%, 45.5% 18.8%, 43.9% 22.4%, 43.3% 26.7%, 43.3% 27.2%, 43.4% 27.6%, 43.4% 28.1%, 43.4% 28.5%, 34.6% 28.5%, 25.7% 28.5%, 16.9% 28.5%, 8% 28.5%, 8% 42.2%, 8% 56%, 8% 69.8%, 8% 83.5%, 24.3% 83.5%, 40.7% 83.5%, 57% 83.5%, 73.3% 83.5%, 73.3% 79.1%, 73.3% 74.7%, 73.3% 70.3%, 73.3% 65.9%, 73.5% 66%, 73.7% 66%, 74% 66%, 74.2% 66%, 78.3% 64.8%, 81.6% 61.4%, 83.8% 56.4%, 84.7% 50.2%, 84% 44.6%, 82% 39.8%, 79.1% 36.4%, 75.5% 34.6%,'

Убираем лишнюю запятую в конце, и вставляем эту строчку в CSS clip-path
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы