>웹 프론트엔드 >HTML 튜토리얼 >캔버스는 고차 베지어 곡선을 구현합니다.

캔버스는 고차 베지어 곡선을 구현합니다.

小云云
小云云원래의
2018-01-13 09:40:132814검색

이 글에서는 주로 캔버스에서의 고차 베지어 곡선(N-차 베지어 곡선 생성기) 구현을 소개합니다. 편집자는 이것이 꽤 좋다고 생각합니다. 이제 여러분과 공유하고 참고용으로 제공하겠습니다. 편집자를 따라 살펴보겠습니다. 모두에게 도움이 되기를 바랍니다.

먼저 작성하세요

네이티브 캔버스는 3차 베지어 곡선까지만 지원하는데, 제어점을 여러 개 추가하려면 어떻게 해야 하나요? (가장 복잡한 곡선도 3차 베지어를 사용하여 시뮬레이션할 수 있습니다.) 동시에 베지어 제어점의 위치를 ​​매우 직관적으로 명확하게 이해하고 곡선을 형성하기 위해 제어점을 얼마나 설정해야 하는지를 명확하게 이해하기 어렵습니다. 원하다. . 위의 두 가지 문제점을 해결하기 위해 커뮤니티에 N레벨 솔루션(js 버전)이 없는 것 같아서, 이번에는 저자가 오픈소스 bezierMaker.js에 대해 매우 진지하게 생각하고 있습니다!

bezierMaker.js는 이론적으로 N차 베지어 곡선 생성을 지원하며 개발자가 제어점을 추가하고 드래그하여 궁극적으로 일련의 그리기 애니메이션을 생성할 수 있는 테스트 기반도 제공합니다. 개발자가 다양한 위치의 제어점에 해당하는 다양한 생성 곡선을 아는 것은 매우 직관적입니다.

이 작품이 마음에 드셨다면 스타에 오신 것을 환영합니다. 결국 스타는 힘들게 얻은 것입니다. .

프로젝트 주소: 여기✨✨✨

테스트 사이트가 왜 필요한가요?

복잡한 고차 베지어 곡선을 그릴 때 필요한 곡선의 제어점의 정확한 위치를 알 수 없습니다. 테스트 필드에서 시뮬레이션하면 제어점의 좌표 값을 실시간으로 얻을 수 있습니다. 획득한 점 좌표를 객체 배열로 변환하고 BezierMaker 클래스에 전달하여 대상 곡선을 생성할 수 있습니다. [x] 테스트 필드에 제어점을 원하는 만큼 추가할 수 있습니다

[x] 테스트 필드는 곡선 그리기 애니메이션 표시를 지원합니다

[x] 제어점을 자유롭게 끌 수 있습니다

[ x ] 베지어 곡선 형성 프로세스의 접선 표시 지원

  1. [x] 차수 3 이하의 베지어 곡선 그리기는 기본 API를 채택합니다

  2. 도입

  3. <script src="./bezierMaker.js"></script>
  4. raw

  5. 위의 렌더링은 테스트 사이트를 통해 제어점의 정확한 좌표를 얻은 후 bezierMaker.js를 호출하여 직접 곡선을 그릴 수 있습니다.
  6. /**
     * canvas canvas的dom对象
     * bezierCtrlNodesArr 控制点数组,包含x,y坐标
     * color 曲线颜色
     */
    var canvas = document.getElementById(&#39;canvas&#39;)
    //3阶之前采用原生方法实现
    var arr0 = [{x:70,y:25},{x:24,y:51}]
    var arr1 = [{x:233,y:225},{x:170,y:279},{x:240,y:51}]
    var arr2 = [{x:23,y:225},{x:70,y:79},{x:40,y:51},{x:300, y:44}]
    var arr3 = [{x:333,y:15},{x:70,y:79},{x:40,y:551},{x:170,y:279},{x:17,y:239}]
    var arr4 = [{x:53,y:85},{x:170,y:279},{x:240,y:551},{x:70,y:79},{x:40,y:551},{x:170,y:279}]
    var bezier0 = new BezierMaker(canvas, arr0, &#39;black&#39;)
    var bezier1 = new BezierMaker(canvas, arr1, &#39;red&#39;)
    var bezier2 = new BezierMaker(canvas, arr2, &#39;blue&#39;)
    var bezier3 = new BezierMaker(canvas, arr3, &#39;yellow&#39;)
    var bezier4 = new BezierMaker(canvas, arr4, &#39;green&#39;)
    bezier0.drawBezier()
    bezier1.drawBezier()
    bezier2.drawBezier()
    bezier3.drawBezier()
    bezier4.drawBezier()
결과 그리기

제어점이 3개 미만인 경우 기본 API 인터페이스가 적용됩니다. 제어점이 2개 이상일 경우 구현한 기능을 사용하여 점을 그립니다.

핵심 원리

베지어 곡선 그리기

베지어 곡선 그리기의 핵심은 베지어 공식의 적용에 있습니다.


이 공식에서 P0-Pn은 시작점에서 다양한 지점까지의 거리를 나타냅니다. 각 제어점에서 끝점의 각 지점까지의 전력 연산과 비율 t.

BezierMaker.prototype.bezier = function(t) { //贝塞尔公式调用
    var x = 0,
        y = 0,
        bezierCtrlNodesArr = this.bezierCtrlNodesArr,
        //控制点数组
        n = bezierCtrlNodesArr.length - 1,
        self = this
    bezierCtrlNodesArr.forEach(function(item, index) {
        if(!index) {
            x += item.x * Math.pow(( 1 - t ), n - index) * Math.pow(t, index) 
            y += item.y * Math.pow(( 1 - t ), n - index) * Math.pow(t, index) 
        } else {
        //factorial为阶乘函数
            x += self.factorial(n) / self.factorial(index) / self.factorial(n - index) * item.x * Math.pow(( 1 - t ), n - index) * Math.pow(t, index) 
            y += self.factorial(n) / self.factorial(index) / self.factorial(n - index) * item.y * Math.pow(( 1 - t ), n - index) * Math.pow(t, index) 
        }
    })
    return {
        x: x,
        y: y
    }
}
모든 점을 탐색하고 현재 비율 t(0<=t<=1)의 값을 기준으로 베지어 곡선의 현재 점 좌표 x, y를 계산합니다. 저자는 t의 값을 1000개의 부분으로 나눕니다. 즉, 각 연산마다 t+=0.01입니다. 이때 계산된 x, y는 베지어 곡선을 1000개 부분으로 나눈 후의 지점이다. t 값이 0에서 1,1000번까지 횡단하면 1000개의 x, y 대응 좌표가 생성되고 점과 선을 순차적으로 그려서 고차 베지어 곡선을 시뮬레이션할 수 있습니다.

저자는 이후 기사에서 베셀 공식의 파생에 대해 구체적으로 설명할 것입니다. 이제 실제 베지어 곡선이 1000개의 점으로 나누어지고 각각 직선으로 연결된다는 것을 베셀 공식을 사용한다는 것만 알면 됩니다. 포인트, 클래스 곡선을 시뮬레이션할 수 있습니다.

시뮬레이션 분야 베지어 곡선 생성 애니메이션 구현을 위해


관련 코드의 이 부분은 여기에서 참조할 수 있습니다

전체 아이디어는 제어점의 각 레이어를 1차 베셀 함수로 처리하는 재귀적 방법을 사용하는 것입니다. 다음 레이어 제어점과 해당 연결을 계산합니다. 저자는 테스트 사이트의 애니메이션 생성 원리를 정리하기 위해 베지어 곡선 수식 원리에 대한 심층 설명까지 구체적인 논리를 남겨두겠습니다~
관련 권장 사항:

CSS를 사용하여 베지어 곡선 만들기


베지에 curve 자세한 응용 설명

캔버스 베지어 곡선 효과 구현을 위한 코드 데모

위 내용은 캔버스는 고차 베지어 곡선을 구현합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.