美文网首页那些年 程序员的样子
模拟贝塞尔曲线(isPointInPath)

模拟贝塞尔曲线(isPointInPath)

作者: bo_bo_bo_la | 来源:发表于2017-12-26 22:35 被阅读17次

    贝塞尔曲线

    bezierCurveTo(cpx,cpy,cpx2,cpx2,dx,dy);创建一条表示贝塞尔曲线的路径.

    该函数接受六个参数,分别代表三个点.

    (cpx,cpy),(cpx2,cpx2)代表控制点,决定曲线的形状

    (dx,dy)代表终点

    模拟贝塞尔曲线(isPointInPath)

    isPointInPath方法
    isPointInPath

    是 Canvas 2D API 用于检测某点是否在路径的描边线上的方法。返回值是一个布尔值,当这个点在路径的描边线上,则返回true,否则返回false。
    首先强调isPointInPath(x,y)方法是针对路径的,比如canvas中的rect、arc方法都可以用,但是fillRect不可以用,因为它不是路径;而且仅对当前的路径有效,而且如果当前路径有多个子路径(currentPath可以有多个subPath:比如进行了rect()之后,再进行arc(),最后关闭路径,进行stroke,那么rect()和arc()所绘制的就是当前路径的两个子路径),只对第一个子路径有效
    所以要在每次判断之前要创建要移动的元素

    <script type="text/javascript">
            var canvas = document.getElementById("myCanvas");
            var context = canvas.getContext("2d");
            var redX1 = 100;
            var redY1 = 200;
            var blueX1 = 400;
            var blueY1 = 200;
            function createLine(moveTo1,moveTo2,lineTo1,lineTo2,lineWidth,color){
                context.beginPath();
                context.moveTo(moveTo1,moveTo2);
                context.lineTo(lineTo1,lineTo2);
                context.lineWidth = lineWidth;
                context.strokeStyle = color;
                context.stroke();
            }
            drawLine(redX1,redY1,blueX1,blueY1);
            function drawLine(redX1,redY1,blueX1,blueY1){
                //半透明的粗线
                createLine(0,500,500,0,10,"rgba(0,0,0,0.2)");
                //连接到红色小球的黑线
                createLine(0,500,redX1,redY1,5,"black");
                //连接到蓝球的黑线
                createLine(500,0,blueX1,blueY1,5,"black");
                //绘制贝塞尔曲线
                context.beginPath();
                context.moveTo(0,500);
                context.bezierCurveTo(redX1,redY1,blueX1,blueY1,500,0);
                context.stroke();
                function createBall(color,x,y){
                    console.log(x,y)
                    context.beginPath();
                    context.fillStyle = color;
                    context.arc(x,y,10,0,Math.PI*2);
                    context.fill();
                }
                function createBallB(color,x,y){
                    console.log(x,y)
                    context.beginPath();
                    context.fillStyle = color;
                    context.arc(x,y,10,0,Math.PI*2);
                    context.fill();
                }
                //蓝球
                createBallB("blue",blueX1,blueY1);
                //红球
                createBall("red",redX1,redY1);
                
                canvas.onmousedown = function(e){
                    var ev = window.event || e;
                    var x = ev.clientX - canvas.offsetLeft;
                    var y = ev.clientY - canvas.offsetTop;
                    createBallB("blue",blueX1,blueY1);
                    if(context.isPointInPath(x,y)){
                        canvas.onmousemove = function(e){
                            var ev = window.event || e;
                            var xx = ev.clientX - canvas.offsetLeft;
                            var yy = ev.clientY - canvas.offsetTop;
                            blueX1 = xx;
                            blueY1 = yy;
                            context.clearRect(0,0,canvas.offsetWidth,canvas.offsetHeight);
                            drawLine(redX1,redY1,blueX1,blueY1);
                        }
                    }
                    createBall("red",redX1,redY1);
                    if(context.isPointInPath(x,y)){
                        canvas.onmousemove = function(e){
                            var ev = window.event || e;
                            var xx = ev.clientX - canvas.offsetLeft;
                            var yy = ev.clientY - canvas.offsetTop;
                            redX1 = xx;
                            redY1 = yy;
                            context.clearRect(0,0,canvas.offsetWidth,canvas.offsetHeight);
                            drawLine(redX1,redY1,blueX1,blueY1);
                        }
                    }
                }
            }
            document.onmouseup = function(){
                canvas.onmousemove = "";
            }
        </script>
    

    原生方法

    利用点击该点的位置到圆心的距离与半径相比,如果大于半径,则表明点击的位置不在小球内部,反之,则在小球内部

    <script type="text/javascript">
            var canvas = document.getElementById("myCanvas");
            var context = canvas.getContext("2d");
            var x1 = 100;
            var y1 = 100;
            var x2 = 400;
            var y2 = 400;
            draw(x1,y1,x2,y2);
            function draw(x1,y1,x2,y2){
                //画半透明的线
                context.beginPath();
                context.moveTo(500,0);
                context.lineTo(0,500);
                context.lineWidth = 10;
                context.strokeStyle = "rgba(0,0,0,0.2)";
                context.stroke();
                
                //画连接线
                context.beginPath();
                context.moveTo(0,500);
                context.lineTo(x1,y1);
                context.lineWidth = 4;
                context.strokeStyle = "#000000";
                context.stroke()
                
                //画连接线
                context.beginPath();
                context.moveTo(500,0);
                context.lineTo(x2,y2);
                context.lineWidth = 4;
                context.strokeStyle = "#000000";
                context.stroke()
                
                //花红球
                context.beginPath();
                context.arc(x1,y1,10,0,Math.PI*2);
                context.fillStyle = "#FF0000";
                context.fill();
                //花蓝球
                context.beginPath();
                context.arc(x2,y2,10,0,Math.PI*2);
                context.fillStyle = "blue";
                context.fill();
                
                //画贝塞尔曲线
                context.beginPath();
                context.moveTo(0,500);
                context.bezierCurveTo(x1,y1,x2,y2,500,0);
                context.lineWidth = 10;
                context.stroke();
                //拖动小球 做动画
                //判断是否拖动小球
                //如果在小球上就做动画
                canvas.onmousedown = function(e){
                    var ev = e || window.event;
                    var x= ev.clientX - canvas.offsetLeft;
                    var y = ev.clientY - canvas.offsetTop;
                    //判断是否在红球上
                    var disRed = Math.pow((x - x1),2) + Math.pow((y - y1),2);
                    if(disRed < 100){
                        console.log("鼠标在红球上");
                        canvas.onmousemove = function(e){
                            var ev = window.event || e;
                            var xx = ev.clientX - canvas.offsetLeft;
                            var yy = ev.clientY - canvas.offsetTop;
                            //清除画布
                            context.clearRect(0,0,canvas.width,canvas.height);
                            //重绘
                            x1 = xx;
                            y1 = yy;
                            draw(x1,y1,x2,y2);
                        }
                    }
                    //判断是否在蓝球上
                    var disBlue = Math.pow((x - x2),2) + Math.pow((y - y2),2);
                    if(disBlue < 100){
                        console.log("鼠标在红球上");
                        canvas.onmousemove = function(e){
                            var ev = window.event || e;
                            var xx = ev.clientX - canvas.offsetLeft;
                            var yy = ev.clientY - canvas.offsetTop;
                            //清除画布
                            context.clearRect(0,0,canvas.width,canvas.height);
                            //重绘
                            x2 = xx;
                            y2 = yy;
                            draw(x1,y1,x2,y2);
                        }
                    }
                }
            }
            document.onmouseup = function(){
                canvas.onmousemove = "";
            }
        </script>
    

    相关文章

      网友评论

        本文标题:模拟贝塞尔曲线(isPointInPath)

        本文链接:https://www.haomeiwen.com/subject/lyzegxtx.html