Javascript 具有控制点的画布形状

Javascript 具有控制点的画布形状,javascript,jquery,html,kineticjs,Javascript,Jquery,Html,Kineticjs,我在kinetic js中制作了一个Bezier形状,上面有控制点。该代码允许用户拖动起点、终点和控制点,从而修改曲线的形状,如下图所示 包含上述代码的jsfiddle链接如下 锚点的代码为 var room = new Kinetic.Shape({ x: 0, y: 0, width: 100, height: 100, stroke: "black", fill: 'ivory', drawFunc: function (context) { var x = this.x();

我在kinetic js中制作了一个Bezier形状,上面有控制点。该代码允许用户拖动起点、终点和控制点,从而修改曲线的形状,如下图所示

包含上述代码的jsfiddle链接如下

锚点的代码为

 var room = new Kinetic.Shape({
x: 0,
y: 0,
width: 100,
height: 100,
stroke: "black",
fill: 'ivory',
drawFunc: function (context) {
    var x = this.x();
    var y = this.y();
    var w = this.width();
    var h = this.height();
    var trX = anchorTR.x();
    var trY = anchorTR.y();
    var brX = anchorBR.x();
    var brY = anchorBR.y();
    var blX = anchorBL.x();
    var blY = anchorBL.y();
    var tlX = anchorTL.x();
    var tlY = anchorTL.y();
    context.beginPath();
    context.moveTo(tlX, tlY);
    // top
    context.bezierCurveTo(x + w / 3, y, x + w * 2 / 3, y, trX, trY);
    // right
    context.bezierCurveTo(x + w, y + h / 3, x + w, y + h * 2 / 3, brX, brY);
    // bottom
    context.bezierCurveTo(x + w * 2 / 3, y + h, x + w / 3, y + h, blX, blY);
    // left
    context.bezierCurveTo(x, y + h * 2 / 3, x, y + h / 3, tlX, tlY);

    context.closePath();
    context.fillStrokeShape(this);
    }
    });

    g.add(room);


   var anchorTR = new Kinetic.Circle({
   x: 100,
   y: 0,
   radius: 8,
   fill: "green",
   stroke: 'black',
   strokeWidth: 1,
   draggable: true
   });
   g.add(anchorTR);

 var anchorBR = new Kinetic.Circle({
x: 100,
y: 100,
radius: 8,
fill: "green",
stroke: 'black',
strokeWidth: 1,
draggable: true
});
g.add(anchorBR);

var anchorBL = new Kinetic.Circle({
x: 0,
y: 100,
radius: 8,
fill: "green",
stroke: 'black',
strokeWidth: 1,
draggable: true
});
g.add(anchorBL);

var anchorTL = new Kinetic.Circle({
x: 0,
y: 0,
radius: 8,
fill: "green",
stroke: 'black',
strokeWidth: 1,
draggable: true
});
g.add(anchorTL);

layer.draw();

目前,我正在为锚定点定义多个动力学圆,并为定位锚定点定义多个变量。我正在尝试优化代码,使其能够在不使用循环的情况下多次重用代码,但无法..请帮助..

将代码封装到函数和添加一些引用。

  • 将创建组和房间的代码放入函数中,并从该函数返回新房间

  • 将创建锚定的代码放入函数中,并从该函数返回新锚定

  • 将对房间定位的引用附着到房间节点本身

下面是代码重构和演示:


原型
正文{padding:20px;}
#容器{
边框:实心1px#ccc;
边缘顶部:10px;
宽度:350px;
高度:350px;
}
$(函数(){
var阶段=新的动力学阶段({
容器:'容器',
宽度:350,
身高:350
});
var layer=新的动能层();
阶段。添加(层);
var room1=厨房(50,50,50,50);
var room2=厨房(150150,50,50);
功能制作室(x、y、w、h){
var g=新的动力学群({x:x,y:y,draggable:true});
层。添加(g);
var房间=新的动能形状({
x:0,,
y:0,
宽度:w,
高度:h,,
笔画:“蓝色”,
填充:“红色”,
drawFunc:函数(上下文){
var x=this.x();
var y=this.y();
var w=this.width();
var h=这个.height();
var tlX=this.anchorTL.x();
var tlY=this.anchorTL.y();
context.beginPath();
context.moveTo(tlX,tlY);
//顶
context.bezierCurveTo(x+w/3,y,x+w*2/3,y,this.anchorTR.x(),this.anchorTR.y());
//对
context.bezierCurveTo(x+w,y+h/3,x+w,y+h*2/3,this.anchorBR.x(),this.anchorBR.y());
//底部
context.bezierCurveTo(x+w*2/3,y+h,x+w/3,y+h,this.anchorBL.x(),this.anchorBL.y());
//左
贝塞尔曲线(x,y+h*2/3,x,y+h/3,tlX,tlY);
closePath();
context.fillStrokeShape(本);
}
});
g、 增加(房间);
room.anchorTR=makeAnchor(w,0,g);
room.anchorBR=makeAnchor(w,h,g);
room.anchorBL=makeAnchor(0,h,g);
room.anchorTL=makeAnchor(0,0,g);
layer.draw();
}
函数makeAnchor(x、y、组){
var anchor=新的动力学圆({
x:x,
y:y,
半径:8,
填充:“绿色”,
笔画:“黑色”,
冲程宽度:1,
德拉格布尔:是的
});
组。添加(锚定);
anchor.moveToTop();
返回(锚);
}
}); // end$(函数(){});
拖动绿色圆圈以更改红色矩形

如果我需要添加更多对象或将现有对象的形状从正方形更改为任意n边多边形,我需要做哪些更改?在哪里?更多对象:只需根据需要多次调用makeRoom()。其他正多边形:使用相同的技术将多边形的角点与三次贝塞尔曲线连接起来。下面是一个计算和绘制n边正多边形角点的示例:祝您的项目好运!
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Prototype</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.0.1.min.js"></script>
<style>
body{padding:20px;}
#container{
  border:solid 1px #ccc;
  margin-top: 10px;
  width:350px;
  height:350px;
}
</style>        
<script>
$(function(){

    var stage = new Kinetic.Stage({
        container: 'container',
        width: 350,
        height: 350
    });
    var layer = new Kinetic.Layer();
    stage.add(layer);


    var room1=makeRoom(50,50,50,50);
    var room2=makeRoom(150,150,50,50);


    function makeRoom(x,y,w,h){

        var g=new Kinetic.Group({x:x,y:y,draggable:true});
        layer.add(g);

        var room=new Kinetic.Shape({
          x:0,
          y:0,
          width:w,
          height:h,
          stroke:"blue",
          fill: 'red',
          drawFunc: function(context) {
            var x=this.x();
            var y=this.y();
            var w=this.width();
            var h=this.height();
            var tlX=this.anchorTL.x();
            var tlY=this.anchorTL.y();
            context.beginPath();
            context.moveTo(tlX,tlY);
            // top
            context.bezierCurveTo(x+w/3,y, x+w*2/3,y, this.anchorTR.x(),this.anchorTR.y());
            // right
            context.bezierCurveTo(x+w,y+h/3, x+w,y+h*2/3, this.anchorBR.x(),this.anchorBR.y());
            // bottom
            context.bezierCurveTo(x+w*2/3,y+h, x+w/3,y+h, this.anchorBL.x(),this.anchorBL.y());
            // left
            context.bezierCurveTo(x,y+h*2/3, x,y+h/3, tlX,tlY);

            context.closePath();
            context.fillStrokeShape(this);
          }
        });

        g.add(room);

        room.anchorTR=makeAnchor(w,0,g);
        room.anchorBR=makeAnchor(w,h,g);
        room.anchorBL=makeAnchor(0,h,g);
        room.anchorTL=makeAnchor(0,0,g);

        layer.draw();
    }

    function makeAnchor(x,y,group){
        var anchor=new Kinetic.Circle({
            x:x,
            y:y,
            radius:8,
            fill:"green",
            stroke: 'black',
            strokeWidth: 1,
            draggable: true
        });
        group.add(anchor);
        anchor.moveToTop();
        return(anchor);
    }

}); // end $(function(){});
</script>       
</head>
<body>
    <h4>Drag green circle to change red rect</h4>
    <div id="container"></div>
</body>
</html>