0

塗りつぶしパターンとして画像を含む大きな円があります。円が回転します。

円の内側をクリックすると、同じ画像と同じオフセットを含む小さな円を作成したいと思います。基本的に、小さい円が透明であるかのように見えるはずです。

だから私の質問は次のとおりです。

大きな円の回転で小さな円の背景画像のオフセットを決定するにはどうすればよいですか?

不適切なオフセットの例を次に示します。

間違ったオフセットの例

4

1 に答える 1

1

小さな円のソース画像は大きな円と同じで、回転していないだけだと思います。

その場合は、回転していないマウスクリックの位置を見つける必要があります。

次に、回転していないマウスクリックの周りに小さな円をクリップして、所定の位置に回転させることができます。

与えられた:

  • 元の回転中心は cx/cy です。
  • 回転角度は radAngle (ラジアン)
  • 回転したマウスクリック ポイントは rx/ry です。

次のように、回転していないマウスクリック位置 ( preRX / preRY ) を計算できます。

// the bigger circle's rotation point  
var cx=150;
var cy=150;

// the rotation angle in radians
var radAngle=Math.PI/6;   // 30 degrees, for example

// the rotated mouseclick point
var rx=225;
var ry=245;

// the radius of the smaller circle
var smallRadius=50;

// calculate the unrotated mouseclick point
var dx= rx-cx;
var dy= ry-cy;
var preRX= cx+ dx*Math.cos(-radAngle) - dy*Math.sin(-radAngle); 
var preRY= cy+ dy*Math.cos(-radAngle) + dx*Math.sin(-radAngle);

次に、小さい円を使用してクリッピング パスを作成します。

// create a clipping path for the small circle
ctx.arc(preRX,preRY,smallRadius,0,Math.PI*2,false);
ctx.closePath();
ctx.clip();

そして最後に、クリップされた画像を移動+回転して所定の位置に描画します

// rotate the small circle into position
ctx.translate(cx,cy);
ctx.rotate(radAngle);
ctx.globalAlpha=1.0;
ctx.drawImage(img,-img.width/2,-img.height/2);

ここにコードとフィドルがあります: http://jsfiddle.net/m1erickson/YAt5r/

<!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.com/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 img=new Image();
    img.onload=function(){
        draw();
    }
    img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house-icon.png";


    function draw(){

        // the bigger circle's rotation point  
        var cx=150;
        var cy=150;

        // the rotation angle in radians
        var radAngle=Math.PI/6;   // 30 degrees

        // the rotated mouseclick point
        var rx=225;
        var ry=245;

        // the radius of the smaller circle
        var smallRadius=50;

        // calculate the unrotated mouseclick point
        var dx= rx-cx;
        var dy= ry-cy;
        var preRX= cx+ dx*Math.cos(-radAngle) - dy*Math.sin(-radAngle); 
        var preRY= cy+ dy*Math.cos(-radAngle) + dx*Math.sin(-radAngle);

        // test

        // rotate the original image and draw it
        ctx.save();
        ctx.translate(cx,cy);
        ctx.rotate(radAngle);
        ctx.globalAlpha=.25;
        ctx.drawImage(img,-img.width/2,-img.height/2);
        ctx.restore();

        // clip the smaller image, rotate it and draw it
        ctx.save();
        ctx.beginPath();

        // create a clipping path for the small circle
        ctx.arc(preRX,preRY,smallRadius,0,Math.PI*2,false);
        ctx.closePath();
        ctx.clip();

        // rotate the small circle into position
        ctx.translate(cx,cy);
        ctx.rotate(radAngle);
        ctx.globalAlpha=1.0;
        ctx.drawImage(img,-img.width/2,-img.height/2);

        // stroke the circle
        ctx.arc(preRX,preRY,smallRadius,0,Math.PI*2,false);
        ctx.stroke();
        ctx.restore();

    }


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

</head>

<body>
    <p>Original image is 25% opacity</p>
    <p>Clipped overlay image is 100% opacity</p>
    <canvas id="canvas" width=350 height=350></canvas>
</body>
</html>
于 2013-05-09T21:35:33.087 に答える