马黑黑 发表于 2023-9-28 20:37

svg 三次贝塞尔曲线演示

<style>
#stage { border: 1px solid gray; }
#stage > path { fill: none; stroke: steelblue; }
#stage > circle { fill: red; cursor: pointer; }
#stage > circle:nth-of-type(2) { fill: purple; }
</style>

<svg id="stage" width="400" height="400">
        <path id="cPath" d="M10 200 C10 10, 390 10, 390 200"></path>
        <circle id="c1" cx="10" cy="10" r="5"></circle>
        <circle id="c2" cx="390" cy="10" r="5"></circle>
</svg>
<div id="pathMsg"></div>

<script>

let movAr = ;
let setAttr = (ar) => ar.forEach((item) => item.setAttribute(item,item));

c1.onmousedown = () => movAr = ;
c2.onmousedown = () => movAr = ;
document.onmouseup = () => movAr = ;

pathMsg.innerText = '路径:' + cPath.getAttribute('d');

stage.onmousemove = (e) => {
        if (movAr)
        setAttr([
                ,
                ,
                ,
        ]);

        if (movAr)
        setAttr([
                ,
                ,
                ,
        ]);
       
        if(movAr || movAr) pathMsg.innerText = '路径:' + cPath.getAttribute('d');
};

</script>

马黑黑 发表于 2023-9-28 20:43

本帖最后由 马黑黑 于 2023-9-28 23:43 编辑

说明:

曲线开始于 {10,200},终止于 {390,200}(画布尺寸 400*400)。

两个控制点:

    ① 第一个控制点 :红色圆点,初始位置是 {10,10}
    ② 第二个控制点 :紫色圆点,初始位置是 {390,10}

    两个控制点可以依次挪动,挪动方法是在相应控制点按下鼠标左键不放,拖曳其到预设地点,然后松开鼠标左键。任意控制点的每一个移动均能影响曲线的样式。

    理论上,控制点不受画布尺寸或坐标系影响,详情请看后续回复。

马黑黑 发表于 2023-9-28 20:44

一楼示例代码:

<style>
#stage { border: 1px solid gray; }
#stage > path { fill: none; stroke: steelblue; }
#stage > circle { fill: red; cursor: pointer; }
#stage > circle:nth-of-type(2) { fill: purple; }
</style>

<svg id="stage" width="400" height="400">
        <path id="cPath" d="M10 200 C10 10, 390 10, 390 200"></path>
        <circle id="c1" cx="10" cy="10" r="5"></circle>
        <circle id="c2" cx="390" cy="10" r="5"></circle>
</svg>
<div id="pathMsg"></div>

<script>

let movAr = ;
let setAttr = (ar) => ar.forEach((item) => item.setAttribute(item,item));

c1.onmousedown = () => movAr = ;
c2.onmousedown = () => movAr = ;
document.onmouseup = () => movAr = ;

pathMsg.innerText = '路径:' + cPath.getAttribute('d');

stage.onmousemove = (e) => {
        if (movAr)
        setAttr([
                ,
                ,
                ,
        ]);

        if (movAr)
        setAttr([
                ,
                ,
                ,
        ]);
       
        if(movAr || movAr) pathMsg.innerText = '路径:' + cPath.getAttribute('d');
};

</script>

马黑黑 发表于 2023-9-28 20:49

附: 三次贝塞尔曲线语句结构

{x0,y0} {x1,y1} {x2,y2} {xy}

其中:

    x0 y0 : 曲线起点
    x1,y1 : 曲线第一控制点
    x2,y2 : 曲线第二控制点
    x,y : 曲线终点

svg路径中,x0 y0 对应于M x y;第一、二控制点和终点对应于 Cx1 y1, x2 y2, x y

马黑黑 发表于 2023-9-28 20:58

重要:

两个控制点可以突破画布的坐标系,即,控制点不受画布尺寸限制。一楼演示的,受限于svg画布,xy坐标值均在 0 - 画布宽高 之间或略有超越。

红影 发表于 2023-9-28 21:21

② 第二个控制点 :紫色圆点,初始位置是 {390,200}
这个应该是390 10吧?

红影 发表于 2023-9-28 21:22

这个感觉很复杂,想弄懂挺难的,还是算了,有二次贝塞尔曲线应该够用了吧{:4_173:}

红影 发表于 2023-9-28 21:25

这个这么麻烦还能弄成可调节的,真不容易。黑黑辛苦了{:4_199:}

小辣椒 发表于 2023-9-28 21:31

增加难度了,小辣椒漂过{:4_170:}

马黑黑 发表于 2023-9-28 23:41

小辣椒 发表于 2023-9-28 21:31
增加难度了,小辣椒漂过

两个控制点,挺好的

马黑黑 发表于 2023-9-28 23:42

红影 发表于 2023-9-28 21:21
② 第二个控制点 :紫色圆点,初始位置是 {390,200}
这个应该是390 10吧?

嗯,故意写错,看看谁能看得出来

马黑黑 发表于 2023-9-28 23:42

红影 发表于 2023-9-28 21:25
这个这么麻烦还能弄成可调节的,真不容易。黑黑辛苦了

这个不麻烦呀,就两个控制点。

小辣椒 发表于 2023-9-28 23:43

马黑黑 发表于 2023-9-28 23:41
两个控制点,挺好的
黑黑上来了,辛苦哦,这么迟的

马黑黑 发表于 2023-9-28 23:44

红影 发表于 2023-9-28 21:22
这个感觉很复杂,想弄懂挺难的,还是算了,有二次贝塞尔曲线应该够用了吧

不是这样说的。三次贝塞尔曲线的存在,不同于二次的,它可以做出更复杂的曲线

马黑黑 发表于 2023-9-28 23:45

小辣椒 发表于 2023-9-28 23:43
黑黑上来了,辛苦哦,这么迟的

喝酒{:4_191:}

红影 发表于 2023-9-29 09:01

马黑黑 发表于 2023-9-28 23:42
嗯,故意写错,看看谁能看得出来

耶,还好我通过考验了{:4_205:}

红影 发表于 2023-9-29 09:02

马黑黑 发表于 2023-9-28 23:42
这个不麻烦呀,就两个控制点。

一个控制点还没彻底弄明白呢{:4_173:}

红影 发表于 2023-9-29 09:03

马黑黑 发表于 2023-9-28 23:44
不是这样说的。三次贝塞尔曲线的存在,不同于二次的,它可以做出更复杂的曲线

知道它的能力更大,只是我脑容量不够了{:4_173:}

马黑黑 发表于 2023-9-29 11:09

红影 发表于 2023-9-29 09:03
知道它的能力更大,只是我脑容量不够了

多吃猪脑

马黑黑 发表于 2023-9-29 11:09

红影 发表于 2023-9-29 09:02
一个控制点还没彻底弄明白呢

一个控制点是最简单的
页: [1] 2 3 4 5
查看完整版本: svg 三次贝塞尔曲线演示