【问题标题】:Why don't my kineticjs events trigger a canvas redraw?为什么我的 kineticjs 事件不触发画布重绘?
【发布时间】:2014-04-23 06:59:43
【问题描述】:

我是 kineticjs 新手,在执行看似微不足道的操作时遇到了问题:当对绘制到它的对象进行更改时,使画布更新。

我有一个循环,可以创建一些带有数字的圆圈,它们都包含在一个组中。当我单击组时,我希望它们缩放和移动。 (在我当前的版本中,运动与动力学教程中的运动相同。)我还有两个文本框,当单击组时将显示组的 x,y 坐标,并在文本框值为时更新形状坐标改变了。文本框获取单击组的值,但如果您更改值,形状不会移动到正确的位置。我确定我只是遗漏了一些明显的东西,但我终生无法弄清楚它是什么。

HTML

<html>  
<head>  
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">

<title>TEST</title> 

<script src="js/jquery-1.10.2.js"></script>
<script src="Libraries/kinetic-v5.1.0.min.js" type='text/javascript'></script>

<script  src="KineticTest.js" type='text/javascript'></script>

<script type='text/javascript'>
window.onload = function(){
    Startup();
}

</script>

 </head>  
 <body>  
<br/>
<h1>TEST</h1>
<input id="x" type="text" value="3" onkeyup='UpdateCircle();'/>
<input id="y" type="text" value="3" onkeyup='UpdateCircle();'/>

<div id="holder" style="height:1000px; width:1000px;"></div>
</body> 

</html>

KineticTest.js

function Startup(){

    // Create a collector to store the created groups
    var ObjGroup = [];

    // Create a stage
    var stage = new Kinetic.Stage({
        container: 'holder',
        width: 1200,
        height: 1200
      });

    // Create a layer to draw stuff to
    var layer = new Kinetic.Layer();

    var ctr = 0;

    // Create a square array of circles with text in them
    for (var i=0; i<5; i++){
        for (var j=0; j<5; j++){
            var r = 15;
            var x = 3*r * i + 2*r;
            var y = 3*r * j + 2*r;

            var group = new Kinetic.Group({
                id: ctr
            });

            // Create a circle
            var circle = new Kinetic.Circle({
                x: 0,
                y: 0,
                radius: r,
                fill: 'lightblue',
                stroke: 'black',
                strokeWidth: 1
              });

            // Create a label
            var label = new Kinetic.Label({
                x: 0,
                y: 0+10,
                rotation:270
            });

            // Create a text element
            var text = new Kinetic.Text({
                  x: 0,
                  y: 0,
                  text: ctr,
                  fontSize: 10,
                  fontFamily: 'Calibri',
                  fill: 'black',
                  align: 'center'
              });

            // add the text element to the label  
            label.add(text);

            // ad the circle and label to the group
            group.add(circle);
            group.add(label);

            // set the x,y location of the group
            group.setX(x);
            group.setY(y);

            // Create a transformation tween to move the group
            group.tween = new Kinetic.Tween({
                node: group, 
                duration: 1,
                x: 400,
                y: 30,
                rotation: 360,
                opacity: 1,
                strokeWidth: 6,
                scaleX: 1.5
              });


            // Create the event handler for clicking on the groups
            group.on('click', function(){
                // Get the selected object
                window.SelectedObjId = this.attrs.id; 

                // Set the text box values
                $('#x').val(this.attrs.x);
                $('#y').val(this.attrs.y);

                // Run the animation
            this.tween.play();
            });

            // Add the group to the layer
            layer.add(group);

            // Add the group to an array so I can find it later
            ObjGroup.push(group);

            ctr++;
        }

    }
      this.ObjGroup = ObjGroup;

   // add the layer to the stage
      stage.add(layer);




}


function UpdateCircle(){
    // This function is called when the user changes the values in the text boxes
    var x = $('#x').val();
    var y = $('#y').val();

    for (var i=0; i<ObjGroup.length; i++){
        var group = ObjGroup[i];
        if (group.attrs.id == window.SelectedObjId){
            group.setX(x);
            group.setY(y);
        }
    }

}

【问题讨论】:

    标签: kineticjs


    【解决方案1】:

    补间无法使用您的代码正常工作。我通过将补间绑定放在点击事件中来解决这个问题。 请注意,这并不是一个好的解决方案,现在每次点击都会添加一个新的补间。至少它让它很快为我工作......

    实际上要回答您的问题,形状的更改值不会在视觉上更新。您必须在其自身的形状、层、舞台(任何容器)上调用绘图函数本身,以及要重绘的子级。

    我认为将 updateCircle 函数中的 if 语句更改为以下内容应该可以做到:

        if (group.attrs.id == window.SelectedObjId){
            group.setX(x);
            group.setY(y);
            layer.draw();
        }
    

    此外,将属性分配给全局 window 对象是一种不好的做法(在您的情况下是选定的组)。在外部范围内,我创建了一个变量 selectedGroup,它也在点击事件期间被分配。然后在 keyup 事件中使用此变量来检查需要从位置更改的组。

    另请参阅 fiddle 以获取工作示例:http://jsfiddle.net/BsK7Q/

    请注意,您似乎还需要进行一些检查,例如检查它是否为实数。

    【讨论】:

    • 嘿,谢谢一百万,Sjiep。我只是在玩东西时将窗口用作方便的支架(诚然是不好的做法)。 layer.draw() 我认为是我需要的。
    • 这里只是一个小更新:jsfiddle.net/BsK7Q/1 我现在在补间完成后在文本框中设置 x 和 y 值。对我来说似乎更好的行为。
    猜你喜欢
    • 1970-01-01
    • 2014-06-08
    • 2021-12-08
    • 1970-01-01
    • 2012-04-21
    • 2011-06-29
    • 2014-08-20
    • 2021-07-16
    • 2011-12-03
    相关资源
    最近更新 更多