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 回答