KineticJS - 我们如何在不移动蒙版的情况下在蒙版后面移动图像

时间:2014-04-04 02:12:27

标签: image kineticjs mask

是否可以在不移动蒙版本身的情况下在蒙版后面移动图像?我正在寻找一种允许在面具后面移动图像的操作,它应该是准确和平滑的。

我正在寻找的最佳答案是掩盖Kinetic.Image对象。 Kinetic.Image是可拖动的,需要担心它的运动。如果真的有可能掩盖Kinetic.Image对象,请告诉我吗?

1 个答案:

答案 0 :(得分:2)

演示:http://jsfiddle.net/m1erickson/u28MS/

使用Kinetic.Shape访问画布上下文,然后创建剪辑区域。

  • 创建一个新的Kinetic.Shape

  • 在形状中定义非矩形路径

  • 调用clip()以限制绘制到该路径。

  • 将图像绘制到剪裁区域。

  • 给图像x& y属性,以便可以绘制图像

以下是代码中的内容:

// create a Kinetic.Shape which gives you access
// to a context to draw on

clippingShape = new Kinetic.Shape({
    sceneFunc: function(context) {

      // define your path here
      // context.beginPath(); ...

      // make your path a clipping region

      context.clip();

      // draw the image inside the clipping region
      // img.x & img.y are offsets which can be used
      // to "drag" the image around the clipping region

      context.drawImage(img,img.x,img.y);

      // KineticJS specific context method
      context.fillStrokeShape(this);

    },
    stroke: 'black',
    strokeWidth: 4,
    listening:false
});

在舞台上侦听鼠标事件,以便在“形状”中绘制时重新定位图像。

  • 在mousedown中:保存鼠标位置并设置一个标志,指示拖动已经开始。

  • 在mousemove中:计算鼠标移动了多少并将图像的x / y偏移了该距离。

  • 在mouseup中:自拖动结束后清除拖动标记。

鼠标事件处理程序如下所示:

var isdown=false;

stage.getContent().onmousedown=function(e){ 
    var pos=stage.getPointerPosition();
    img.lastX=parseInt(pos.x);
    img.lastY=parseInt(pos.y);
    isdown=true; 
};
stage.getContent().onmouseup=function(e){ 
    isdown=false; 
};
stage.getContent().onmousemove=function(e){
    if(!isdown){return;}
    var pos=stage.getPointerPosition();
    var mouseX=parseInt(pos.x);
    var mouseY=parseInt(pos.y);
    var dx=mouseX-img.lastX;
    var dy=mouseY-img.lastY;
    img.lastX=mouseX;
    img.lastY=mouseY;
    img.x+=dx;
    img.y+=dy;
    layer.draw();
};

[以前版本的答案 - 在提问者提交后替换为上面的新答案]

这种裁剪传统上是使用包含透明“视口”的前景图像完成的,该视口允许用户看到下面背景图像的一部分。

演示:http://jsfiddle.net/m1erickson/2f9yu/

enter image description here

在底层创建可拖动的背景图片:

// create a background layer

var bottomLayer=new Kinetic.Layer();
stage.add(bottomLayer);

// put a draggable image on the background layer

var city=new Kinetic.Image({ image:bk,x:0,y:0,draggable:true,width:700,height:440, });
bottomLayer.add(city);
bottomLayer.draw();

在顶层创建不可拖动的前景图像。

顶部图片有一个透明的“视口”。

重要提示:顶层不会侦听事件,因此拖动会移动底部图像,而不是顶部图像。

// create a top layer that does not respond to mouse events
// any mouse events will filter down to the background image
// this enables the background to be dragged even while behind the top image

var topLayer=new Kinetic.Layer({listening:false,});
stage.add(topLayer);

// create a top image with transparent pixels 
// used as a viewport to see a portion of the bottom image

var mirror=new Kinetic.Image({ image:viewport,x:0,y:0 });
topLayer.add(mirror);
topLayer.draw();

示例代码:

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

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

    var bottomLayer=new Kinetic.Layer();
    stage.add(bottomLayer);
    var topLayer=new Kinetic.Layer({listening:false,});
    stage.add(topLayer);

    var loadedCount=0;
    //
    var bk=new Image();
    bk.onload=start;
    bk.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/desert1.jpg";
    //
    var viewport=new Image();
    viewport.onload=start;
    viewport.src="https://dl.dropboxusercontent.com/u/139992952/multple/car4.png";

    function start(){
        if(++loadedCount<2){return;}

        var city=new Kinetic.Image({ image:bk,x:0,y:0,draggable:true,width:700,height:440, });
        bottomLayer.add(city);
        bottomLayer.draw();

        var mirror=new Kinetic.Image({ image:viewport,x:0,y:0 });
        topLayer.add(mirror);
        topLayer.draw();

    }


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

</script>       
</head>
<body>
    <h4>Drag to move the background image in the mirror</h4>
    <div id="container"></div>
</body>
</html>