在KineticJS中通过SVG路径的矩形孔

时间:2014-01-27 19:44:56

标签: javascript canvas svg kineticjs

globalCompositeOperation with KineticJS描述了如何用圆圈在矩形上打孔。我想使用SVG路径来代替圆圈,例如:

  

米876.30799 492.53209Ç-36.64554 -0.29484 -69.69962 33.8121 -67.84069 70.49382 3.60444 27.60835 34.32996 46.34894 60.8096 40.13747 10.35153 -2.31261 21.0251 -4.39193 30.54799 -9.18203 10.45071 -6.35814 19.46448 -14.76346 29.73686 -21.39213 10.83886 -8.06083 21.32637 -16.94052 29.19035 -28.02964 -1.53​​049 -9.55445 -13.2442 -8.25504 -20.39998 -9.87533 -12.44629 -2.06296 -25.58989 -5.04642 -34.93228 -14.14783 -10.44361 -7.80509 -20.00756 -17.00681 -27.11185 -28.00433 z

如何在context.globalCompositeOperation="destination-out";

中实现这个洞,即new Kinetic.Path({ data: path });

编辑:我刚刚在这里找到了圆孔的更新版本:

use globalcompositeoperations on KineticJS 4.7.2

现在只是让它适用于SVG路径的问题;)

1 个答案:

答案 0 :(得分:1)

使用SVG绘图来显示模糊的图像非常复杂。

以下是所需的步骤:

  • 使用图片
  • 创建背景图层
  • 创建前景层
  • 创建一个覆盖前景的矩形以遮盖背景图像
  • 使用SVG数据创建Kinetic.Path
  • 使用path.toImage
  • 将该SVG路径转换为图像
  • 创建一个Kinetic.Shape,使用“destination-out”合成绘制SVG图像以显示背景
  • Kinetic.Shape不可拖动,因此使用相同的SVG数据创建另一个Kinetic.Path作为拖动显示的Kinetic.Shape的句柄。拖动此路径句柄时,将显示形状移动到相同的坐标。

演示:http://jsfiddle.net/m1erickson/7Yvt5/

此演示使用简单的SVG矩形,但您可以使用所需的任何SVG绘图。

enter image description here enter image description here

以下是示例代码:

<!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:300px;
  height:300px;
}
</style>        
<script>
$(function(){

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

    var path;
    var reveal;
    var cutoutImage;
    //var pathData="M 0,0 L50,0 50,50 0,50 z";
    var pathData="M 0,0 L50,0 50,50 0,50 z";

    var img=new Image();
    img.onload=function(){
        start();
    }
    img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/KoolAidMan.png";

    function start(){

        var image=new Kinetic.Image({
            x:0,
            y:0,
            width:300,
            height:300,
            image:img
        });
        bklayer.add(image);
        bklayer.draw();

        var rect = new Kinetic.Rect({
            x: 0,
            y: 0,
            width: 300,
            height: 300,
            fill: 'skyblue',
            stroke: 'lightgray',
            strokeWidth: 3
        });
        layer.add(rect);

        // path filled
        var path = new Kinetic.Path({
          x: 0,
          y: 0,
          data:pathData,
          fill: 'green',
        });
        layer.add(path);

        // turn the path into an image
        cutoutImage=path.toImage({
            callback: function(img){
                reveal = new Kinetic.Shape({
                    sceneFunc: function(context) {
                        var ctx=this.getContext()._context;
                        var pos=this.pos;
                        ctx.save();
                        ctx.globalCompositeOperation="destination-out";
                        ctx.drawImage(this.image,pos.x,pos.y);
                        ctx.restore();
                    },
                });
                reveal.pos={x:0,y:0};
                reveal.image=img;
                reveal.position(path1.position());
                layer.add(reveal);
                // remove the original path
                path.remove();
                layer.draw();
            }
        });


        // draggable path
        path1 = new Kinetic.Path({
            x: 0,
            y: 0,
            data:pathData,
            stroke: 'red',
            draggable:true
        });
        path1.on("dragmove",function(){
            reveal.pos=this.position();
            layer.draw();
        });
        layer.add(path1);

        layer.draw();

    }   // end start 


    function addReveal(img){
        reveal = new Kinetic.Shape({
            sceneFunc: function(context) {
                var ctx=this.getContext()._context;
                var pos=this.pos;
                ctx.save();
                ctx.globalCompositeOperation="destination-out";
                ctx.drawImage(this.image,pos.x,pos.y);
                ctx.restore();
            },
        });
        reveal.pos={x:0,y:0};
        reveal.image=img;
        reveal.position(path1.position());
        layer.add(reveal);
        layer.draw();
    }


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

</script>       
</head>

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