on
재료 각도가 있는 반올림된 재료
재료 각도가 있는 반올림된 재료
반응형
올해 구글 I/O에서 안드로이드와 다른 구글 제품들을 위한 새로운 개인화되고 화려한 디자인 시스템이 공개되었다. 그것은 "Material You"라고 불리고 가장 먼저 눈에 띈 것 중 하나는 UI 요소에 사용되는 다양한 둥근 다각형이었다.
어떤 원소에 대해서도 이런 별 모양의 모양을 유연하게 사용하는 것이 좋을 것이다. 그래서 저는 그렇게 하기 위해 각도 지시문을 개발했습니다. 따라서 지시문은 둥근 다각형의 SVG 클립 경로를 만들고 CSS 클립 경로 속성을 통해 이를 호스트 요소에 적용합니다.
GitHub의 간단한 테스트 애플리케이션을 따라 지침의 구현을 찾을 수 있습니다.
이 기사의 다음 절에서는 이 지침 개발에 관련된 몇 가지 주요 개념을 설명합니다.
구성 설정 정의
지시사항 골격이 초기화된 후, 저는 지시사항의 기본 구성 속성과 값 범위를 확정하고 싶었습니다. 다음은 지침의 공용 API를 설명합니다.
모서리 수: 최소 3개 이상이어야 합니다. 귀퉁이는 별 모양의 모양이 가질 수 있는 "선"의 수를 정의합니다.
외부 반지름: 0과 1 사이의 이 숫자는 사용 가능한 총 크기에 비례하여 폴리곤의 크기를 백분율로 정의합니다(1로 설정하면 폴리곤의 반지름이 svg 뷰포트의 가장자리에 도달함).
내부 반지름 비율: 형상의 외부 반지름에 대한 내부 반지름의 비율을 나타내는 0과 1 사이의 숫자(1로 설정되면 내부 반지름은 외부 반지름과 동일해진다.
코너 반지름: 가능한 최대 코너 반지름을 기준으로 코너 반지름의 크기를 정의하는 0과 1 사이의 숫자. 이 속성은 정확한 값을 사용하여 모서리 반지름을 설명하지 않기 때문에 다소 신기한 정의로 보일 수 있습니다. 그것의 이면에 있는 생각은 정확한 정의에 대한 것이 아니라 우아한 모양을 찾는 것에 대한 것이었다.
기울기: 도형 회전 각도(도)입니다.
이러한 구성 속성은 단일 인터페이스에 캡슐화되어 하나의 입력 속성 바인딩을 통해 모든 구성 설정을 적용할 수 있습니다. 이것은 단순함을 위해 그리고 애니메이션이 아직 고려되지 않았기 때문에 행해졌다. 속성 바인딩은 제공된 매개 변수에 관계없이 구성의 유효성을 보장하는 세터 함수를 사용하여 구현됩니다.
기본 도형 구성
둥근 폴리곤 모양을 그리는 첫 번째 단계는 기본 폴리곤의 모서리를 구성하는 것입니다. 둥근 모서리는 두 번째 패스 내에 정의된다.
다각형의 기본 모양은 외부 반지름과 내부 반지름을 번갈아 가며 몇 가지 간단한 삼각법을 사용하여 구성되었다. 편의를 위해 모든 정점은 원점을 중심으로 배치되며 그리기 프로세스가 끝날 때 최종 위치로 변환됩니다.
형상 구성을 더 쉽게 설명하기 위해 응용 프로그램에는 도면 프로세스의 다음 단계에 점점 더 많이 사용되는 벗겨낸 2D 벡터 클래스(Vector2)가 포함되어 있습니다.
const vertices: Vector2[] = []; const numPoints = corners * 2; const gamma = (2 * Math.PI) / numPoints; // the tilt angle form the configuration in radians let angle = tilt; for (let i = 0; i < numPoints; i++) { // switch between the outer and inner radius from the configuration const radius = i % 2 ? innerRadius : outerRadius; const rx = Math.cos(angle) * radius; const ry = Math.sin(angle) * radius; vertices.push(new Vector2(rx, ry)); angle += gamma; }
둥근 모서리 추가
기본 모양의 꼭지점을 배치한 후 다음 단계는 둥근 모서리를 추가하는 것입니다. 마티유 조에가 둥근 모서리를 어떻게 만드는지에 대한 훌륭한 기사가 있다. 하지만, 이 기사에서처럼 다르게 만들고 싶은 문제들이 있습니다. 주로 아치를 사용한 최대 모서리 반지름 및 구조의 결정.
최대 모서리 반지름 결정
Mathieu Jouhetts 기사에 기술된 알고리즘은 최대 모서리 반경을 최단 가장자리의 길이의 절반으로 제한한다. 그러나 Illustator나 Figma를 사용하여 원하는 모양을 그릴 때 최대 모서리 반경이 이 한계를 벗어난다는 것을 알게 되었습니다. 그래서 저는 이 임계값을 결정하기 위한 다른 방법이 필요했습니다.
내 접근법은 관련된 점에 대한 호의 두 접점이 만나는 점을 계산하여 최대 반지름을 찾는 것이었다. 알려진 것은 가장자리 길이(A와 B 사이의 s)와 점 A와 B의 반각(α와 β)이다.
알려지지 않은 호 중심점 Q와 함께 이러한 알려진 특성은 한 변과 그것에 인접한 두 각도가 알려진 임의의 삼각형을 형성한다. Sines의 법칙을 사용하여 최대 반지름을 정의하는 r의 길이에 도달할 때까지 결측각과 길이를 계산할 수 있다. 이 작업은 최대 반경이 계산되는 점에 인접한 두 가장자리 모두에 대해 수행됩니다. 마지막으로, 더 작은 반경이 선택됩니다.
이 접근 방식이 모든 임의의 다각형에 방탄이 되지는 않을 수 있지만 이 특정 사용 사례에서는 상당히 잘 작동합니다.
private getMaxCornerRadius(A: PolygonPoint, B: PolygonPoint): number { const s = Vector2.subtract(A.vertex, B.vertex).length(); const alpha = A.angle / 2; const beta = B.angle / 2; const gamma = Math.PI - alpha - beta; return (s * Math.sin(alpha) * Math.sin(beta)) / Math.sin(gamma); }
아치를 이용한 시공
아치 건설에 필요한 모든 요점을 찾는 것은 이미 Mathieu Jouhetts에 의해 기사에 자세히 설명되어 있다. 그러나 실제 SVG 아크 요소를 그릴 때 내 솔루션에는 스위프 플래그라는 파라미터가 하나 누락되었습니다. 이 플래그는 호를 시계 방향으로 그릴지 또는 시계 반대 방향으로 그릴지를 나타냅니다(추가 정보는 MDN 문서 참조).
다각형의 권선(시계방향 또는 시계 반대방향)을 결정하는 것은 컴퓨터 그래픽에서 일반적인 작업이며 교차곱을 사용하여 해결할 수 있습니다. 이 경우 교차 곱은 폴리곤의 모서리 점을 형성하는 삼각형에 대해 계산됩니다(코드 내 편의상 호의 접점을 사용하여 계산되었습니다). 따라서 교차곱 부호는 스위프 플래그 파라미터의 값을 결정합니다.
호스트 요소에 스타일 적용
반올림된 폴리곤 경로를 구성한 후에는 호스트 요소에 클립 경로로 적용해야 합니다. 이 작업은 클립 경로를 포함하는 SVG 요소를 만들어 호스트 요소에 추가함으로써 수행되었습니다. 전체 SVG 트리가 문자열로 생성될 때 ContextualFragment를 사용하여 SVG 노드를 만들었습니다.
const frag = document.createRange().createContextualFragment(svg); this.renderer.appendChild(this.hostElementRef.nativeElement, frag); // apply the clip path to the host element (the id is a static counter) this.renderer.setStyle(this.hostElementRef.nativeElement, 'clip-path', `url(#${id})`);
from http://it-ground.tistory.com/233 by ccl(A) rewrite - 2021-09-25 05:00:30