画布剪贴蒙版定位问题

时间:2016-02-26 14:38:59

标签: css html5 canvas clip

长话短说 - 看看下面简单的小提琴。长话故事 - 我正在使用HTML5 Canvas和SVG路径剪切蒙版来屏蔽图像中的自定义形状。除了我试图将容器放在哪里之外,一切都按预期工作。

你可以在这个小提琴中看到有问题的问题 - https://jsfiddle.net/eyv35f6k/1/

body {
  padding: 0; 
  margin: 0
  }
  
  .container {
    position:absolute;
    top: 0px;
    /* *********** top: 50px; *********** */
  }

.css-clipped {
  display: block; 
  -webkit-clip-path:url(#svgPath);
  clip-path:url(#svgPath);
  }
<!- Element that cointains image that must be clipped by using custom shape  ->
  <div class="container">
    <img class="css-clipped" src="https://sarasoueidan.com/demos/css-svg-clipping/html-img-clipped-with-css/flowers.jpg">
  </div>


<!- SVG that contains clop path ->
  <svg height="0" width="0">
    <defs>
      <clipPath id="svgPath">
        <path fill="#FFFFFF" stroke="#000000" stroke-width="1.0" stroke-miterlimit="10" d="m49,0c2,0 4,0 6,0c16,1 30,3 36,13c6,9 7,23 7,36c0,13 -1,27 -7,36c-6,10 -20,12 -36,13c-2,0 -4,0 -6,0l0,0c-2,0 -4,0 -6,0c-16,-1 -30,-3 -36,-13c-6,-9 -7,-23 -7,-36c0,-13 1,-27 7,-36c6,-10 20,-12 36,-13c2,0 4,0 6,0l0,0z"/>
      </clipPath>
    </defs>
  </svg>

如果您尝试移动 .container 元素,您将看到其中的容器和图像移动,而画布蒙版仍保留在页面主体的左上角,而不是移动与元素一起被应用于。我在photoshop中制作了示例图片来说明我想要实现的目标:

enter image description here

你可以告诉我,如何制作它以使画布面具与它应用的元素一起移动?提前谢谢。

1 个答案:

答案 0 :(得分:1)

您可以使用至少两种方式进行裁剪:

视口模式:

当您拖动时,剪裁会在下方较大图像的不同较小部分显示“窗口”。

拖动 - 静态剪辑模式:

从较大的图像中剪切小的静态图像。拖动时,静态图像会在画布上移动。

这是示例代码和显示两种裁剪模式的演示。

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
function reOffset(){
    var BB=canvas.getBoundingClientRect();
    offsetX=BB.left;
    offsetY=BB.top;        
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }
window.onresize=function(e){ reOffset(); }

var isDown=false;
var startX,startY;

var ox=0;
var oy=0;
var width=75;
var height=50;
var mode='Viewport'
var clippedImage;

var img=new Image();
img.onload=start;
img.src="https://sarasoueidan.com/demos/css-svg-clipping/html-img-clipped-with-css/flowers.jpg";
function start(){
    clipImage=createClipImg(ox,oy,width,height);
    $("#canvas").mousedown(function(e){handleMouseDown(e);});
    $("#canvas").mousemove(function(e){handleMouseMove(e);});
    $("#canvas").mouseup(function(e){handleMouseUpOut(e);});
    $("#canvas").mouseout(function(e){handleMouseUpOut(e);});
    //
    $('input[type=radio][name=group1').change(function(){
        mode=this.value;
        if(mode=='Drag'){
            clippedImage=createClipImg(ox,oy,width,height);
        }
        draw();
    });
    draw();
}

function draw(){
    ctx.clearRect(0,0,cw,ch);
    if(mode=='Viewport'){
        clippedViewport(ox,oy,width,height);
    }else{
        ctx.drawImage(clippedImage,ox,oy);
    }
}

function clippedViewport(x,y,w,h){
    ctx.save();
    ctx.beginPath();
    ctx.rect(x,y,w,h);
    ctx.closePath();
    ctx.clip();
    ctx.drawImage(img,0,0);
    ctx.restore();
}

function createClipImg(x,y,w,h){
    var c=document.createElement('canvas');
    var cctx=c.getContext('2d');
    c.width=w;
    c.height=h;
    cctx.drawImage(img,-x,-y);
    return(c);
}



function handleMouseDown(e){
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();
  //
  startX=parseInt(e.clientX-offsetX);
  startY=parseInt(e.clientY-offsetY);
  // Put your mousedown stuff here
  if(startX>ox && startX<ox+width && startY>oy && startY<=oy+height){
      isDown=true;
  }
}

function handleMouseUpOut(e){
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();
  // Put your mouseup stuff here
  isDown=false;
}

function handleMouseMove(e){
  if(!isDown){return;}
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();
  //
  mouseX=parseInt(e.clientX-offsetX);
  mouseY=parseInt(e.clientY-offsetY);
  // Put your mousemove stuff here
  var dx=mouseX-startX;
  var dy=mouseY-startY;
  startX=mouseX;
  startY=mouseY;
  //
  ox+=dx;
  oy+=dy;
  draw();
}
body{ background-color: ivory; }
canvas{border:1px solid red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
Mode:&nbsp
<input type=radio name=group1 value=Viewport checked>Viewport
<input type=radio name=group1 value=Drag>Drag clip
<hr>
"Viewport" reveals different part of the image underneath.
<br>
"Drag clip" drags the same clipped image part around the canvas.
<hr>
<canvas id="canvas" width=300 height=300></canvas>

[添加:剪裁到html5画布中的图片]

您可以将剪裁的图像绘制到html5画布上(每个图像1个画布),然后像使用图像一样使用画布。

enter image description here enter image description here

var img=new Image();
img.onload=start;
img.src="https://sarasoueidan.com/demos/css-svg-clipping/html-img-clipped-with-css/flowers.jpg";
function start(){
    var container=document.getElementById('container');
    for(var i=0;i<6;i++){
        makeClippedCanvas(img,100,100,container);
    }
}


function makeClippedCanvas(img,w,h,container){
    var c=document.createElement("canvas");
    var ctx=c.getContext("2d");
    c.width=w;
    c.height=h;
    //
    ctx.moveTo(50,0);
    ctx.bezierCurveTo(100,5, 100,15, 100,50);
    ctx.bezierCurveTo(100,85, 100,95, 50,100);
    ctx.bezierCurveTo(0,95, 0,85, 0,50);
    ctx.bezierCurveTo(0,15, 0,5, 50,0);
    ctx.closePath();
    ctx.stroke();
    ctx.clip();
    ctx.drawImage(img,0,0);
    container.appendChild(c);
    return(c);
}
body{ background-color: ivory; }
#container{width:50%; border:1px solid blue;}
canvas{margin:5px;}
<h4>Resize the window</h4>
<div id=container></div>