2013-05-09 248 views
0

我有一个大图像作为填充图案的圆圈。圆圈旋转。确定图像偏移量

当我在圆圈内单击时,我希望创建一个包含相同图像和相同偏移量的较小圆圈。本质上它应该看起来好像小圆圈是透明的。

所以我的问题是:

如何确定与更大的圆圈旋转的小圆圈的背景图像偏移?

这里是不正确的例子偏移:

An example of the wrong offset

回答

1

我猜你的小了一圈源图像是一样的大圈 - 只是不旋转。

如果是这样的话,您需要找到您未旋转的鼠标点击位置。

然后你可以将你的小圆圈夹在未旋转的鼠标点击并旋转到位。

鉴于:

  • 你的旋转中心原来是CX/CY,
  • 你的旋转角度是radAngle(弧度)
  • 你的旋转mousclick点是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>