我有一个大圆圈,图像作为填充图案。圆圈旋转。
当我在圆圈内部单击时,我希望创建一个包含相同图像和相同偏移的较小圆圈。基本上它应该看起来好像较小的圆圈是透明的。
所以我的问题如下:
如何通过旋转更大的圆圈来确定较小圆圈的背景图像的偏移量?
以下是错误偏移的示例:
答案 0 :(得分:1)
我猜你的小圆圈的源图像与大圆圈相同 - 只是没有旋转。
如果是这种情况,您需要找到未旋转的鼠标点击位置。
然后,您可以在未旋转的鼠标点击周围剪切较小的圆圈并将其旋转到位。
假设:
您可以像这样计算未旋转的鼠标点击位置(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>