Как получить путь пересечения двух путей SVG программно?
1,00
р.
р.
Нужно пересечь два SVG-пути и получить путь, представляющий их пересечение. Не важно, будет это работать в браузере или в Node.js. Нужно именно пересечение, использование clip-path не подходит. Если после пересечения вдруг понадобится transform, то не страшно (сам его уберу). Думаю, для этого уже есть какая-нибудь библиотека, но нашёл только svg-intersections - возвращает массив точек пересечения, а мне надо path path-intersection - что-то у меня вообще не взлетела - всегда получается пустой массив snap.svg - вроде даёт то-то полезное, но я не пойму, как это использовать
Например, при пересечении этих путей: M 24.379464,51.504463 23.434524,23.156249 38.742559,12.572916 c 0,0 29.860118,-9.0714281 17.00893,0.755953 -12.851191,9.82738 13.229166,19.465774 13.229166,19.465774 z m 32.883928,0.28869028 c 0,0 -15.686011,1.51190452 -8.504463,7.18154712 7.181546,5.6696426 50.270836,30.0491076 26.458332,42.3333336 -23.8125,12.284226 47.058036,14.174107 47.058036,14.174107 z должно получиться (примерно): M 43.943359 11.123047 C 40.995759 11.900151 38.742188 12.572266 38.742188 12.572266 L 35.236328 14.996094 C 44.091432999999995 21.21816 55.052161 29.822765 57.455078 37.628906 L 66.939453 33.650391 63.632812 30.410156 C 58.77426 27.95814 52.364322 23.85552 52.214844 19.224609 L 43.943359 11.123047 z Вот интерактивный сниппет с путями из примера (на цвета внимание не обращать - они просто для наглядности) - надо получить путь Пересечение из #path1 и #path2:
var p1 = "M 24.379464,51.504463 23.434524,23.156249 38.742559,12.572916 c 0,0 29.860118,-9.0714281 17.00893,0.755953 -12.851191,9.82738 13.229166,19.465774 13.229166,19.465774 z" var p2 = "m 32.883928,0.28869028 c 0,0 -15.686011,1.51190452 -8.504463,7.18154712 7.181546,5.6696426 50.270836,30.0491076 26.458332,42.3333336 -23.8125,12.284226 47.058036,14.174107 47.058036,14.174107 z" var intersection = Snap.path.intersection(p1, p2) console.log(intersection) .as-console-wrapper.as-console-wrapper { max-height: 100vh }
PS: Этот вопрос на английском.
Ответ После многодневных поисков я всё же нашёл решение там, где я его вообще не ожидал увидеть, а именно вот здесь. Этот ответ подтолкнул меня вспомнить то, что давно я это видел на PaperJS в булевых операциях (Boolean Operations). У PaperJS есть 5 различных булевых операций: exclude, subtract, unite, intersect, divide и мы будем использовать одну из них под названием intersect. Эти операции являются также и одноимёнными функциями и все возвращают новый item объект, из которого можно посредством функции exportSVG() получить настоящий SVG Path element, который содержит путь пересечения наших путей. Пример правильного решения
paper.install(window) window.onload = function() { paper.setup('canvas') var p1 = 'M 24.379464,51.504463 23.434524,23.156249 38.742559,12.572916 c 0,0 29.860118,-9.0714281 17.00893,0.755953 -12.851191,9.82738 13.229166,19.465774 13.229166,19.465774 z', p2 = 'm 32.883928,0.28869028 c 0,0 -15.686011,1.51190452 -8.504463,7.18154712 7.181546,5.6696426 50.270836,30.0491076 26.458332,42.3333336 -23.8125,12.284226 47.058036,14.174107 47.058036,14.174107 z', path1 = new Path(p1), path2 = new Path(p2) path1.fillColor = 'rgba(255,0,0,.5)' path1.position = new Point(25, 25) path2.fillColor = 'rgba(0,255,0,.5)' path2.position = new Point(40, 25) var result = path2.intersect(path1) result.selected = true result.fillColor = '#77f' //exportSVG() docu: http://paperjs.org/reference/item/#exportsvg var svgPathElement = result.exportSVG(), dPath = svgPathElement.getAttribute('d') document.querySelector('path').setAttribute('d', dPath) var output = document.querySelector('#output') output.innerHTML = '' + dPath + '' output.innerHTML += '' + svgPathElement.outerHTML + '' } table { margin-left:14px padding-left:14px border-left:1px solid gray display:inline-block }