对我有用的最终代码是:
<canvas id="bg-admin-canvas" width="500" height="500" style="margin:15px; background:#09F;"></canvas>
<script>
var postit = function(width,height,angle){
var canvas = document.getElementById("bg-admin-canvas");
var ctx = canvas.getContext("2d");
var radians = angle * Math.PI / 180;
var move = width*Math.sin(radians);
if(angle < 0 ){ ctx.translate(0,-move); }else{ ctx.translate(move,0); }
ctx.rotate(radians);
var gradient = ctx.createLinearGradient(0,height,width/2,height/2);
gradient.addColorStop(0.05,"rgba(0,0,0,0)");
gradient.addColorStop(0.5,"rgba(0,0,0,0.3)");
ctx.fillStyle = gradient;
ctx.fillRect(0,0,width,height);
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(width, 0);
ctx.lineTo(width,height);
ctx.lineTo(width-width*.8,height-height*.02);
ctx.quadraticCurveTo(0+width*.02,height-height*.02,0+width*.02,(height - height*.2));
ctx.closePath();
var gradient = ctx.createLinearGradient(0,height,width/2,height/2);
gradient.addColorStop(0,'#f7f8b9');
gradient.addColorStop(1,'#feffcf');
ctx.fillStyle = gradient;
ctx.fill();
ctx.beginPath();
ctx.moveTo(width-width*.8,height-height*.02);
ctx.quadraticCurveTo(0+width*.02,height-height*.02,0+width*.02,(height - height*.2));
ctx.quadraticCurveTo(width*.05,height-height*.05,width*.1,height-height*.1);
ctx.quadraticCurveTo(width*.1,height-height*.07,width-width*.8,height-height*.02);
ctx.closePath();
ctx.fillStyle = '#ffffff';
ctx.fill();
var gradient = ctx.createLinearGradient(0,height,width*.1,height-height*.1);
gradient.addColorStop(0,"rgba(222,222,163,0.8)");
gradient.addColorStop(1,'#feffcf');
ctx.fillStyle = gradient;
ctx.fill();
}
postit(300, 300, 10);
</script>
你好,
我用 html5 的 Canvas 和一些 js 做了一个快速而肮脏的“便利贴”。
我希望能够以任何方式旋转它们,所以我尝试使用翻译。下面的例子我有一个 0,250 的翻译,这样你就可以看到整个事情。
理想情况下,我知道如果我的 Canvas 是 300,300,那么我会 ctx.translate(150,150); ctx.旋转(-30); ctx.translate(-150,-150);
当然,因为我正在旋转一个正方形,所以它被切断了。
我如何旋转正方形并将其移动到 Canvas 上,以便整个内容都显示在 Canvas 的左上角边缘?
我添加了一张图片,我的想法是只获取三 Angular 形的高度并将其移动那么多,但是在翻译时,它似乎并不能正常工作。
我将粘贴我的整个函数以便您查看,但如果您有任何想法,我将不胜感激。这不重要,今天就来凑热闹。
var postit = function(width,height,angle){
var canvas = jQuery("#bg-admin-canvas").get(0);
var ctx = canvas.getContext("2d");
/*var area = (width*width*Math.sin(angle))/2;
var h = (area*2) / width + 30;
ctx.translate(0,h);
*/
//ctx.translate(150,150);
ctx.translate(0,250);
ctx.rotate(angle*Math.PI / 180);
//ctx.translate(-150,-150);
var gradient = ctx.createLinearGradient(0,height,width/2,height/2);
gradient.addColorStop(0.05,"rgba(0,0,0,0)");
gradient.addColorStop(0.5,"rgba(0,0,0,0.3)");
ctx.fillStyle = gradient;
ctx.fillRect(0,0,width,height);
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(width, 0);
ctx.lineTo(width,height);
ctx.lineTo(width-width*.8,height-height*.02);
ctx.quadraticCurveTo(0+width*.02,height-height*.02,0+width*.02,(height - height*.2));
ctx.closePath();
var gradient = ctx.createLinearGradient(0,height,width/2,height/2);
gradient.addColorStop(0,'#f7f8b9');
gradient.addColorStop(1,'#feffcf');
ctx.fillStyle = gradient;
ctx.fill();
ctx.beginPath();
ctx.moveTo(width-width*.8,height-height*.02);
ctx.quadraticCurveTo(0+width*.02,height-height*.02,0+width*.02,(height - height*.2));
ctx.quadraticCurveTo(width*.05,height-height*.05,width*.1,height-height*.1);
ctx.quadraticCurveTo(width*.1,height-height*.07,width-width*.8,height-height*.02);
ctx.closePath();
ctx.fillStyle = '#ffffff';
ctx.fill();
var gradient = ctx.createLinearGradient(0,height,width*.1,height-height*.1);
gradient.addColorStop(0,"rgba(222,222,163,0.8)");
gradient.addColorStop(1,'#feffcf');
ctx.fillStyle = gradient;
ctx.fill();
}
postit(300, 300, -35);
更多信息
Phrog,我想你知道我想做什么。这张图片显示了我想做的事情: 现在,唯一的问题是,我希望能够传入任何宽度、高度和 Angular ,并即时进行调整。
以如下代码为例:
var canvas = document.getElementById("bg-admin-canvas");
var ctx = canvas.getContext("2d");
ctx.arc(0,0,3,0,360,true); ctx.fill();
ctx.translate(50, 50);
ctx.arc(0,0,3,0,360,true); ctx.fill();
ctx.translate(-25, -25);
ctx.arc(0,0,3,0,360,true); ctx.fill();
我得到以下图像: 现在,如果我像这样在其中添加旋转:
var canvas = document.getElementById("bg-admin-canvas");
var ctx = canvas.getContext("2d");
ctx.arc(0,0,3,0,360,true); ctx.fill();
ctx.translate(50, 50);
ctx.arc(0,0,3,0,360,true); ctx.fill();
ctx.rotate(30*Math.PI/180);
ctx.translate(-25, -25);
ctx.arc(0,0,3,0,360,true); ctx.fill();
我现在有一个倾斜的坐标,结果是:
据我发现,这是因为坐标不再水平和垂直。
所以,对于这个旋转坐标结构,我无法弄清楚如何将我的正方形(可以是任何大小并以任何 Angular 旋转)移回左侧和顶部(因此它适合尽可能小的空间)
这有意义吗?
最佳答案
简而言之:
- 仅在 Y 方向平移上下文以将 Angular 放在应有的位置。
- 围绕这个偏移点旋转上下文。
- 在 0,0 处绘制对象。
这是一个交互式的工作示例,您可以在此处在线查看:
http://phrogz.net/tmp/canvas_rotate_square_in_corner.html
<!DOCTYPE HTML>
<html lang="en"><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>HTML5 Canvas Rotate Square in Corner</title>
<style type="text/css" media="screen">
body { background:#eee; margin:2em; text-align:center }
canvas { display:block; margin:auto; background:#fff; border:1px solid #ccc }
</style>
</head><body>
<canvas width="250" height="200"></canvas>
<script type="text/javascript" charset="utf-8">
var can = document.getElementsByTagName('canvas')[0];
var ctx = can.getContext('2d');
ctx.strokeStyle = '#600'; ctx.lineWidth = 2; ctx.lineJoin = 'round';
ctx.fillStyle = '#ff0'
document.body.onmousemove = function(evt){
var w=140, h=120;
var angle = evt ? (evt.pageX - can.offsetLeft)/100 : 0;
angle = Math.max(Math.min(Math.PI/2,angle),0);
ctx.clearRect(0,0,can.width,can.height); ctx.beginPath();
ctx.save();
ctx.translate(1,w*Math.sin(angle)+1);
ctx.rotate(-angle);
ctx.fillRect(0,0,w,h);
ctx.strokeRect(0,0,w,h);
ctx.restore();
};
document.body.onmousemove();
</script>
</body></html>
分析
在上图中,A 点是便利贴的左上角,B 点是右上角。我们将便利贴从正常 Angular 旋转了 -a 弧度(顺时针旋转为正,逆时针旋转为负)。
我们可以看到当便利贴旋转时,A 点保持在 y 轴上,所以我们只需要计算 y 向下多远 轴来移动它。此距离在图中表示为 BD。从三 Angular 学我们知道
sin(a) = BD/AB
重新排列这个公式可以得到
BD = **AB***sin(a)
我们知道 AB 是便利贴的宽度。一些细节:
因为我们的 Angular 会被表示为负数,而负数的sin会得到一个负数的结果,但是因为我们想要一个正数的结果,所以我们要么将结果取反
BD = -AB***sin(-a)
或者只是“作弊”并使用正 Angular :
**BD = **AB***sin(a)我们需要记住在旋转上下文之前对其进行翻译,以便我们首先直接沿着轴向下移动以在正确的位置建立我们的原点。
<请记住,HTML5 Canvas 中的旋转使用弧度(而非度数)。如果要旋转 20 度,则需要乘以
Math.PI/180
将其转换为弧度:
ctx.rotate( 20*Math.PI/180 );
这也适用于 arc
命令;你应该做 ctx.arc(x,y,r,0,Math.PI*2,false)
;一个完整的圆圈。
关于javascript - 在 Canvas 上旋转 'note' 以始终触摸左上角,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5555444/