-->

KineticJS dynamically change the position of an ob

2019-05-29 09:46发布

问题:

I have a vertical and a horizontal lines and a circle on my stage, trying to keep the circle centered on the corssoing of the two lines when I move either line, here is my script that does not work:

        var cy = 512;
        var cx = 512;
        var gy = 0;
        var gx = 0;
        var stage1 = new Kinetic.Stage({
            container: 'container',
            width: 1024,
            height: 1024
        });
        var layer = new Kinetic.Layer();
        var circle = new Kinetic.Layer();
        var circle1 = new Kinetic.Circle({
            x: cx + gx,
            y: cy + gy,
            radius: 140,
            stroke: '#00ffff',
            strokeWidth: 4,
            opacity: 0.5
        });
        circle.add(circle1);

        var GreenLine1 = new Kinetic.Line({
            points: [0, 512, 1024, 512],
            stroke: 'green',
            strokeWidth: 4,
            lineCap: 'round',
            lineJoin: 'round',
            opacity: 0.3
        });

        var BlueLine1 = new Kinetic.Line({
            points: [512, 0, 512, 1024],
            stroke: '#0080c0',
            strokeWidth: 4,
            lineCap: 'round',
            lineJoin: 'round',
            opacity: 0.5
        });

        var bgroup1 = new Kinetic.Group({
            draggable: true,
            dragBoundFunc: function (pos) {
                return {
                    x: pos.x,
                    y: this.getAbsolutePosition().y
                }
            }
        });
        var ggroup1 = new Kinetic.Group({
            draggable: true,
            dragBoundFunc: function (pos) {
                return {
                    x: this.getAbsolutePosition().x,
                    y: pos.y
                }
            }
        });
        bgroup1.add(BlueLine1);
        ggroup1.add(GreenLine1);
        layer.add(bgroup1);
        layer.add(ggroup1);
        stage1.add(circle);
        stage1.add(layer);
        BlueLine1.on('mouseover', function () {
            document.body.style.cursor = 'e-resize';
        });
        BlueLine1.on('mouseout', function () {
            document.body.style.cursor = 'default';
        });
        GreenLine1.on('mouseover', function () {
            document.body.style.cursor = 'n-resize';
        });
        GreenLine1.on('mouseout', function () {
            document.body.style.cursor = 'default';
        });

        ggroup1.on('dragend', function (event) {
        var gy = ggroup1.getPosition().y;
        circle.draw();
        });
        ggroup1.on('dragstart', function (event) {
        circle1.moveTo(ggroup1);

        });
        bgroup1.on('dragstart', function (event) {
        circle1.moveTo(bgroup1);
        });
        bgroup1.on('dragend', function (event) {
         var gx = bgroup1.getPosition().x;
         circle.draw();
        });

I would appreciate your suggetions, thanks in advance

回答1:

Keeping your circle in your crosshairs

May I suggest a simpler version of your code?

Instead of maintaining 2 groups and moving the circle between the 2 groups, how about just coding the circle to automatically redraw itself at the intersection of the 2 lines.

So when the user moves your GreenLine1 or BlueLine1, just move your circle1 to the intersection of your “crosshairs”.

First, add a custom drawFunc to your circle1 that causes it to always draw in the crosshairs:

    drawFunc: function(canvas) {
      var context = canvas.getContext();
      var centerX=BlueLine1.getPosition().x;
      var centerY=GreenLine1.getPosition().y;
      context.beginPath();
      context.arc(centerX, centerY, this.getRadius(), 0, 2 * Math.PI, false);
      context.lineWidth = this.getStrokeWidth();
      context.strokeStyle = this.getStroke();
      context.stroke();
    },

Then, whenever the user drags either line, just trigger circle1 to redraw itself:

    // keep circle in center of crosshairs
    stage1.getDragLayer().afterDraw(function() {
      layer.draw();
    });

Here is code and a Fiddle: http://jsfiddle.net/m1erickson/cgF8y/

<!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://www.html5canvastutorials.com/libraries/kinetic-v4.3.3-beta.js"></script>

<style>
#container{
  border:solid 1px #ccc;
  margin-top: 10px;
}
</style>        
<script>
$(function(){

    function init(){

        var cy = 512/2;
        var cx = 512/2;
        var gy = 0;
        var gx = 0;
        var stage1 = new Kinetic.Stage({
            container: 'container',
            width: 1024/2,
            height: 1024/2
        });
        var layer = new Kinetic.Layer();
        stage1.add(layer);

        var circle1 = new Kinetic.Circle({
            drawFunc: function(canvas) {
              var context = canvas.getContext();
              var centerX=BlueLine1.getPosition().x;
              var centerY=GreenLine1.getPosition().y;
              context.beginPath();
              context.arc(centerX, centerY, this.getRadius(), 0, 2 * Math.PI, false);
              context.lineWidth = this.getStrokeWidth();
              context.strokeStyle = this.getStroke();
              context.stroke();
            },
            x: cx + gx,
            y: cy + gy,
            radius: 140/2,
            stroke: '#00ffff',
            strokeWidth: 4,
            opacity: 0.5
        });
        layer.add(circle1);

        var GreenLine1 = new Kinetic.Line({
            points: [0, 512/2, 1024/2, 512/2],
            stroke: 'green',
            strokeWidth: 4,
            lineCap: 'round',
            lineJoin: 'round',
            opacity: 0.3,
            draggable:true
        });
        layer.add(GreenLine1);

        var BlueLine1 = new Kinetic.Line({
            points: [512/2, 0, 512/2, 1024/2],
            stroke: '#0080c0',
            strokeWidth: 4,
            lineCap: 'round',
            lineJoin: 'round',
            opacity: 0.5,
            draggable:true
        });
        layer.add(BlueLine1);

        // keep circle in center of crosshairs
        stage1.getDragLayer().afterDraw(function() {
          layer.draw();
        });



        BlueLine1.on('mouseover', function () {
            document.body.style.cursor = 'e-resize';
        });
        BlueLine1.on('mouseout', function () {
            document.body.style.cursor = 'default';
        });
        GreenLine1.on('mouseover', function () {
            document.body.style.cursor = 'n-resize';
        });
        GreenLine1.on('mouseout', function () {
            document.body.style.cursor = 'default';
        });

        layer.draw();

    } // end init();

init();

}); // end $(function(){});

</script>       
</head>

<body>
    <div id="container"></div>
</body>
</html>