0

这两天我一直在努力解决的问题有点奇怪,所以我不确定如何在标题中指定它。

我有一个 KineticJs Line,它有一个点数组(line.attrs.points),形式为具有 x 和 y 值的对象。在拖动某个 Kinetic 元素时,我想动态地向线条添加点并重新绘制它。(例如:线条看起来像这样:\ _ _ _ / 并且在某些条件下拖动另一个形状时我想动态添加一个点并使其看起来像这样:\ _ / \ _ /)所以,当满足该条件时在另一个形状的 dragmove 事件中,我使用以下代码:

line.attrs.points.push({x:xValue, y:yValue});
line.attrs.points.sort(function(a,b){
    return a.x > b.x; // I tried with a.x - b.x and with short if-s which return only -1, 0 or 1, still nothing happened
});
line.setPoints(line.attrs.points);
layer.draw();

但是这些点没有排序,所以这条线会到达某个 x,然后返回到一个较小的 x,然后再继续前进,这不是我在获得某种点之后所期望的行为!

奇怪的是,当我使用 console.log(line.attrs.points); 对于三个连续的点加法(每次加法+2 点),我得到以下输出:

[Object, Object, Object, Object, Object, Object]
[Object, Object, Object, Object, Object, Object, Object, Object]
[Object, Object, Object, Object, Object, Object, Object, Object, Object, Object]

但是当我打开数组时,每个数组中有 10 个对象。怎么可能打开一个包含 6 个对象的数组并在其中看到 10 个对象(我使用的是 Google Chrome 的默认控制台)?会不会是 console.log 是异步的并在所有添加发生后记录它们?

主要问题是那种点不起作用,但我仍然很高兴理解为什么控制台表现得如此奇怪。

提前感谢您的长时间解释!

4

1 回答 1

0

你也需要保持你的点在绘图顺序(不是“x”顺序)

为此,向每个点对象添加一个 sortBy 字段

{ x:10, y:10, sortBy:”1” }
{ x:30, y:10, sortBy:”2” }

要在这 2 点之间添加一个点,只需在 sortBy 字段中添加一个后缀字母:

{ x:10, y:10, sortBy:”1” }
{ x:20, y:10, sortBy:”1A” }
{ x:30, y:10, sortBy:”2” }

然后使用如下比较函数按 sortBy 字段对对象进行排序:

function myCompare(a,b){
    if(a.sortBy<b.sortBy){ return -1; }
    if(a.sortBy>b.sortBy){ return 1; }
    return(0);
}

myPoints.sort(myCompare);

您可以创建一个 appendPoint 函数以按顺序插入点对象

var points=[];
var index=0;

appendPoint(100,150);
appendPoint(200,150);

function appendPoint(x,y){
    points.push({x:x,y:y,sortBy:index.toString()});
    index++;
}

并创建一个 insertPoint 函数,在任何 sortBy 索引之后插入一个点对象:

insertPoint(150,100,0);

function insertPoint(x,y,afterIndex){
    points.push({x:x,y:y,sortBy:afterIndex.toString()+"Z"});
    points.sort(pointsCompare);
}

function pointsCompare(a,b){
    if(a.sortBy<b.sortBy){ return -1; }
    if(a.sortBy>b.sortBy){ return 1; }
    return(0);
}

这是示例代码:

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    .cf:before, .cf:after { content: " "; /* 1 */ display: table; /* 2 */ }
    .cf:after { clear: both; }
</style>

<script>
    $(function(){

    var points=[];
    var index=0;

    appendPoint(100,150);
    appendPoint(200,150);
    showPoints();
    insertPoint(150,100,0);
    showPoints();


    function appendPoint(x,y){
        points.push({x:x,y:y,sortBy:index.toString()});
        index++;
    }

    function insertPoint(x,y,afterIndex){
        points.push({x:x,y:y,sortBy:afterIndex.toString()+"Z"});
        points.sort(pointsCompare);
    }

    function pointsCompare(a,b){
        if(a.sortBy<b.sortBy){ return -1; }
        if(a.sortBy>b.sortBy){ return 1; }
        return(0);
    }

    function showPoints(){
        for(var i=0;i<points.length;i++){
            var pt=points[i];
            console.log(pt.sortBy+": "+pt.x+"/"+pt.y);
        }
    }

    }); // end $(function(){});
</script>

</head>

<body>

</body>
</html>
于 2013-07-17T16:01:30.287 回答