首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与KineticJS楔形交叉处的夹子

与KineticJS楔形交叉处的夹子
EN

Stack Overflow用户
提问于 2013-02-10 05:52:17
回答 1查看 781关注 0票数 0

我是KineticJS的初学者,我想做两个可拉的楔形,在它们的交叉处改变到特定的颜色。我在这个论坛上看到了形状剪裁教程和形状交叉问题。我理解一般的策略是捕捉拖动事件,然后重新绘制KineticJS形状,并在该形状的drawFunc中使用context.rect/context.弧线复制形状并在其上剪辑。

我的问题是,没有方便的context.wedge来模拟KineticJS楔。所以我要么停止使用楔形,要么执行复杂的计算,用context.arc和线条模拟楔形,或者我想出一个更好的方法。有谁知道更好的方法吗?

谢谢,

Mae

JSFiddle上的代码:http://jsfiddle.net/kdRjP/5/ (不起作用,只是到处都是重复的楔形,甚至没有剪裁的楔形)。

代码:

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript" charset="utf-8" src="js/kinetic-v4.3.1.min.js"></script>
</head>



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

    <script type="text/javascript">

        drawWedges();


        function drawWedges() {
            var stage = new Kinetic.Stage({
                container: "container",
                width: 400,
                height: 400
            });
            window.console.log("Wedges: 1");

            var wedgeLayer = new Kinetic.Layer();


            var wedgeGroup = new Kinetic.Group({
                x: stage.getWidth() / 2,
                y: stage.getWidth() / 2
            });


            var wedge_1 = new Kinetic.Wedge({
                x: -100,
                y: 0,
                radius: 80,
                angleDeg: 40,
                opacity: 0.7,
                fill: 'red',
                stroke: 'black',
                strokeWidth: 2,
                draggable: true,
                rotationDeg: 0
            });


            var wedge_2 = new Kinetic.Wedge({
                x: 100,
                y: 0,
                radius: 80,
                angleDeg: 40,
                opacity: 0.7,
                fill: 'cyan',
                stroke: 'black',
                strokeWidth: 2,
                draggable: true,
                rotationDeg: 0
            });             



            function makeShapeClip(clipShape, compositeShape) {
                clipShape.attrs.drawFunc_bak = clipShape.attrs.drawFunc;
                clipShape.attrs.drawFunc = function() {
                    var context = this.getContext();
                    context.save();
                    context.beginPath();
                    this.attrs.drawFunc_bak.call(this, context);
                    context.clip();
                    context.beginPath();
                    compositeShape.attrs.drawFunc.call(this, context);
                    context.fill();
                    context.closePath();
                    context.restore();
                };

                return compositeShape;
            };   


            wedge_1.on("dragend", function(evt) {
                var mousePos = stage.getMousePosition();

                var stageIntersections = stage.getIntersections({"x": mousePos.x, "y": mousePos.y});
                if (stageIntersections.length > 0) {
                    // Want to draw a piece of wedge_1 clipped around wedge_2.
                    // Since can't turn wedge_2 into a clip path after it's been drawn, 
                    // draw a duplicate of wedge_2 superimposed on top of wedge_2, 
                    // turn that duplicate into a clip path, 
                    // and then try to draw a duplicate of wedge_1 into it.


                    // Start by creating the wedge_1 duplicate in proper "intersection area color"
                    var wedgeComposite = new Kinetic.Wedge({
                        x: wedge_1.getX(),
                        y: wedge_1.getY(),
                        radius: wedge_1.getRadius(),
                        angleDeg: wedge_1.getAngleDeg(),
                        opacity: 0.5,
                        fill: 'yellow',
                        stroke: 'blue',
                        strokeWidth: 2,
                        draggable: true,
                        rotationDeg: wedge_1.getRotationDeg()
                    });


                    // Now pass that wedge_1 duplicate into a special function that 
                    // creates wedge_2 duplicate and makes it into a clip path.
                    var wedgeClip = makeShapeClip(new Kinetic.Wedge({
                        x: stageIntersections[0].getX(),
                        y: stageIntersections[0].getY(),
                        radius: stageIntersections[0].getRadius(),
                        angleDeg: stageIntersections[0].getAngleDeg(),
                        opacity: 0.5,
                        fill: '#999999',
                        stroke: 'red',
                        strokeWidth: 2,
                        draggable: true,
                        rotationDeg: stageIntersections[0].getRotationDeg()
                    }), wedgeComposite);


                    wedgeGroup.add(wedgeClip);
                }

                wedgeLayer.draw();
            });




            wedgeGroup.add(wedge_1);
            wedgeGroup.add(wedge_2);
            wedgeLayer.add(wedgeGroup);
            stage.add(wedgeLayer);
        }   
    </script>


</body>
</html>
EN

回答 1

Stack Overflow用户

发布于 2013-02-10 19:32:57

以下是一个解决方案:

假设您的canvas#1有两个动态and楔形(红色和青色)。

当用户完成其拖动时:

  1. 创建一个新的canvas#2 (与canvas#1相同的大小),其当前位置/旋转的红色楔形。不要显示canvas#2 (可见性:隐藏)。
  2. 创建一个新的canvas#3 (与canvas#1相同的大小),在其当前位置/旋转的正好青色楔形。不要显示canvas#3 (可见性:隐藏)。
  3. 从canvas#2和canvas#3中的左上角像素开始,迭代canvas#2和canvas#3上的每个对应像素。
  4. 如果#2和#3上的任何对应像素都是“有色”的,则楔形在该像素处相交。
  5. 对于step4中的任何“点击”,请在相交像素处在canvas#1上绘制您想要的任何内容(比如将该像素更改为指定的颜色)。

为了提高性能,您可以计算这两个楔形的边框,并查看它们是否相交。

如果楔形根本不相交,就不要费心于像素撞击测试。

如果他们相交,只需像素击中-测试组合楔形的包围框。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14795138

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档