最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Clipping images into different shapes like triangle, pentagon in html5 canvas? - Stack Overflow

programmeradmin0浏览0评论

I am developing a game in html 5 canvas where I have to clip images into many shapes. I also want to join these clipped images using mouse events. Can I only clip a square shape? Also, is it necessary to save x and y co-ordinates of each clipped image to know its position or is there any alternate way?

I am developing a game in html 5 canvas where I have to clip images into many shapes. I also want to join these clipped images using mouse events. Can I only clip a square shape? Also, is it necessary to save x and y co-ordinates of each clipped image to know its position or is there any alternate way?

Share Improve this question edited Apr 16, 2014 at 4:25 acarlon 17.3k7 gold badges78 silver badges96 bronze badges asked Jan 23, 2014 at 4:32 HarshaHarsha 311 silver badge8 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

Here is an example to illustrate how to:

  • clip an image into 4 triangle pieces,
  • hit-test the pieces,
  • move the pieces using your mouse

Here's code and a Fiddle: http://jsfiddle/m1erickson/r59ch/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery./jquery.min.js"></script>
<style>
    body{ background-color: ivory; }
    #canvas{border:1px solid red;}
</style>
<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var $canvas=$("#canvas");
    var canvasOffset=$canvas.offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;
    var scrollX=$canvas.scrollLeft();
    var scrollY=$canvas.scrollTop();

    var isDown=false;
    var startX;
    var startY;

    var parts=[];
    var selectedPart=-1;

    var img=new Image();
    img.onload=function(){
        var cx=img.width/2;
        var cy=img.height/2;
        var w=img.width;
        var h=img.height;
        parts.push({x:25,y:25,points:[{x:0,y:0},{x:cx,y:cy},{x:0,y:h}]});
        parts.push({x:25,y:25,points:[{x:0,y:0},{x:cx,y:cy},{x:w,y:0}]});
        parts.push({x:125,y:25,points:[{x:w,y:0},{x:cx,y:cy},{x:w,y:h}]});
        parts.push({x:25,y:25,points:[{x:0,y:h},{x:cx,y:cy},{x:w,y:h}]});
        drawAll();
    }
    img.src="https://dl.dropboxusercontent./u/139992952/stackoverflow/house100x100.png";

    function drawAll(){
        ctx.clearRect(0,0,canvas.width,canvas.height);
        for(var i=0;i<parts.length;i++){
            draw(parts[i]);
        }
    }

    function draw(part){
        ctx.save();
        define(part);
        ctx.clip();
        ctx.drawImage(img,part.x,part.y);
        ctx.stroke();
        ctx.restore();
    }

    function hit(part,x,y){
        define(part);
        return(ctx.isPointInPath(x,y))
    }

    function move(part,x,y){
        part.x+=x;
        part.y+=y;
        draw(part);
    }

    function define(part){
        ctx.save();
        ctx.translate(part.x,part.y);
        ctx.beginPath();
        var point=part.points[0];
        ctx.moveTo(point.x,point.y);
        for(var i=0;i<part.points.length;i++){
            var point=part.points[i];
            ctx.lineTo(point.x,point.y);
        }
        ctx.closePath();
        ctx.restore();
    }

    function handleMouseDown(e){
      e.preventDefault();
      startX=parseInt(e.clientX-offsetX);
      startY=parseInt(e.clientY-offsetY);

      // Put your mousedown stuff here
      for(var i=0;i<parts.length;i++){
          if(hit(parts[i],startX,startY)){
              isDown=true;
              selectedPart=i;
              return;
          }
      }          
      selectedPart=-1;
    }

    function handleMouseUp(e){
      e.preventDefault();
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      // Put your mouseup stuff here
      isDown=false;
    }

    function handleMouseOut(e){
      e.preventDefault();
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      // Put your mouseOut stuff here
      isDown=false;
    }

    function handleMouseMove(e){
      if(!isDown){return;}
      e.preventDefault();
      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;
      //
      var part=parts[selectedPart];
      move(part,dx,dy);
      drawAll();


    }

    $("#canvas").mousedown(function(e){handleMouseDown(e);});
    $("#canvas").mousemove(function(e){handleMouseMove(e);});
    $("#canvas").mouseup(function(e){handleMouseUp(e);});
    $("#canvas").mouseout(function(e){handleMouseOut(e);});


}); // end $(function(){});
</script>

</head>

<body>
    <h4>Drag the right triangle-image into place</h4>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

You can define a path and use that for clipping:

ctx.save();    /// store current state of canvas incl. default clip mask

ctx.beginPath();
ctx.moveTo(0, 10);
ctx.lineTo(200, 10);
ctx.lineTo(100, 110);
ctx.clip();    /// will close the path implicit

/// draw graphics here

ctx.restore(); /// restore default infinite clipping mask

This will create a triangle. If you now draw on top the graphics will be clipped to this shape. Coordinates given here are of course just for example.

A small note: the different browsers may or may not anti-alias the clipping mask. If not the result may turn out "hard-edged".

(I remend to use save()/restore() in connection with clip(). There is suppose to be a resetClip() method but this is rarely implemented in the browsers and is currently considered for removal from the specs.)

An alternative to using clip() is to use image pattern. Define a pattern with the image you want to clip, then create the path as above and use fill() with the pattern set as fillStyle. For this to work properly you need to translate() the canvas before filling to place the image pattern in the desired position.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论