CanvasRenderingContext2D.arcTo
Здравствуйте.
С наступающим новым годом. Помогите закрасить часть окружности, никак не могу сообразить что я делаю не так. Метод "drawSection". Заранее благодарю. https://jsfiddle.net/m36bkLjh/ <canvas id="canvas" width="400" height="400"></canvas> <script> class Circle{ /** * @param {Canvas} canvas */ constructor(canvas){ this.canvas=canvas; this.radius=canvas.width/2*0.8; } /** * @return {Canvas} */ getCanvas(){ return this.canvas; } /** * @param {number} radius * @return {Circle} */ setRadius(radius){ this.radius=radius; return this; } /** * @return {number} */ getRadius(){ return this.radius; } /** * @return {Circle} */ draw(){ const cnv=this.getCanvas(); const ctx=cnv.getContext('2d'); const center=[ cnv.width/2, cnv.height/2 ]; ctx.beginPath(); ctx.arc( center[0], center[1], this.getRadius(), 0, 2*Math.PI ); ctx.stroke(); ctx.fill(); return this; } /** * @param {number} angle * @return {Circle} */ *!* drawSection(angle){ */!* const cnv=this.getCanvas(); const ctx=cnv.getContext('2d'); const center=[ cnv.width/2, cnv.height/2 ]; const radius=this.getRadius(); const x=center[0]; const y=center[1]; angle=180-angle/2; const points=[ [ radius*Math.sin(-angle*Math.PI/180)+x, radius*Math.cos(-angle*Math.PI/180)+y, ], [ radius*Math.sin(angle*Math.PI/180)+x, radius*Math.cos(angle*Math.PI/180)+y, ] ]; ctx.beginPath(); ctx.moveTo(points[0][0],points[0][1]); ctx.lineTo(x,y); ctx.lineTo(points[1][0],points[1][1]); ctx.stroke(); //Заливка *!* ctx.beginPath(); ctx.fillStyle='#F00'; ctx.strokeStyle='#F00'; ctx.moveTo(x,y); //ctx.lineTo(points[0][0],points[0][1]); ctx.arcTo( points[0][0], points[0][1], points[1][0], points[1][1], radius ); //ctx.lineTo(x,y); ctx.stroke(); ctx.fill(); */!* return this; } } const circle=new Circle(document.getElementById('canvas')); circle.getCanvas().getContext('2d').fillStyle='#F5F5F5'; circle.draw().drawSection(45); </script> |
Nexus,
строка 104 и 105 нужна формула, какая именно не знаю. <!DOCTYPE html> <html> <head> <title>Untitled</title> <meta charset="utf-8"> </head> <body> <canvas id="canvas" width="400" height="400"></canvas> <script> class Circle{ /** * @param {Canvas} canvas */ constructor(canvas){ this.canvas=canvas; this.radius=canvas.width/2*0.8; } /** * @return {Canvas} */ getCanvas(){ return this.canvas; } /** * @param {number} radius * @return {Circle} */ setRadius(radius){ this.radius=radius; return this; } /** * @return {number} */ getRadius(){ return this.radius; } /** * @return {Circle} */ draw(){ const cnv=this.getCanvas(); const ctx=cnv.getContext('2d'); const center=[ cnv.width/2, cnv.height/2 ]; ctx.beginPath(); ctx.arc( center[0], center[1], this.getRadius(), 0, 2*Math.PI ); ctx.stroke(); ctx.fill(); return this; } /** * @param {number} angle * @return {Circle} */ drawSection(angle){ const cnv=this.getCanvas(); const ctx=cnv.getContext('2d'); const center=[ cnv.width/2, cnv.height/2 ]; const radius=this.getRadius(); const x=center[0]; const y=center[1]; angle=180 - angle/2; const points=[ [ radius*Math.sin(-angle*Math.PI/180)+x, radius*Math.cos(-angle*Math.PI/180)+y, ], [ radius*Math.sin(angle*Math.PI/180)+x, radius*Math.cos(angle*Math.PI/180)+y, ] ]; ctx.beginPath(); ctx.moveTo(points[0][0],points[0][1]); ctx.lineTo(x,y); ctx.lineTo(points[1][0],points[1][1]); ctx.stroke(); //Заливка ctx.beginPath(); ctx.fillStyle='#F00'; ctx.strokeStyle='#F00'; ctx.moveTo(x,y); ctx.lineTo(points[0][0],points[0][1]); ctx.arcTo(212, 32, points[1][0],points[1][1], radius); ctx.lineTo(x,y); ctx.stroke(); ctx.fill(); return this; } } const circle=new Circle(document.getElementById('canvas')); circle.getCanvas().getContext('2d').fillStyle='#F5F5F5'; circle.draw().drawSection(45); </script> </body> </html> |
рони, спасибо, я используя метод arc сделал, с помощью окружности.
https://jsfiddle.net/m36bkLjh/1/ https://jsfiddle.net/m36bkLjh/2/ <canvas id="canvas" width="400" height="400"></canvas> <script> class Circle{ /** * @param {Canvas} canvas */ constructor(canvas){ this.canvas=canvas; this.radius=canvas.width/2*0.8; } /** * @return {Canvas} */ getCanvas(){ return this.canvas; } /** * @param {number} radius * @return {Circle} */ setRadius(radius){ this.radius=radius; return this; } /** * @return {number} */ getRadius(){ return this.radius; } /** * @return {Circle} */ draw(){ const cnv=this.getCanvas(); const ctx=cnv.getContext('2d'); const center=[ cnv.width/2, cnv.height/2 ]; ctx.beginPath(); ctx.arc( center[0], center[1], this.getRadius(), 0, 2*Math.PI ); ctx.stroke(); ctx.fill(); return this; } /** * @param {number} angle * @return {Circle} */ drawSection(angle){ const cnv=this.getCanvas(); const ctx=cnv.getContext('2d'); const center=[ cnv.width/2, cnv.height/2 ]; const radius=this.getRadius(); const x=center[0]; const y=center[1]; angle=(angle%360)/2; const radian=(180-angle)*Math.PI/180; const points=[ [ radius*Math.sin(-radian)+x, radius*Math.cos(-radian)+y, ], [ radius*Math.sin(radian)+x, radius*Math.cos(radian)+y, ] ]; ctx.beginPath(); ctx.moveTo(points[0][0],points[0][1]); ctx.lineTo(x,y); ctx.lineTo(points[1][0],points[1][1]); ctx.stroke(); //Заливка ctx.beginPath(); ctx.fillStyle='#F00'; ctx.strokeStyle='#F00'; ctx.moveTo(x,y); ctx.lineTo(points[0][0],points[0][1]); ctx.arc( x, y, radius, (270-angle)*Math.PI/180, (angle-90)*Math.PI/180 ); ctx.lineTo(x,y); ctx.stroke(); ctx.fill(); return this; } } const circle=new Circle(document.getElementById('canvas')); circle.getCanvas().getContext('2d').fillStyle='#F5F5F5'; circle.draw().drawSection(45); </script> |
Nexus,
... надо условие добавить какое для yy <!DOCTYPE html> <html> <head> <title>Untitled</title> <meta charset="utf-8"> </head> <body> <canvas id="canvas" width="400" height="400"></canvas> <script> class Circle{ /** * @param {Canvas} canvas */ constructor(canvas){ this.canvas=canvas; this.radius=canvas.width/2*0.8; } /** * @return {Canvas} */ getCanvas(){ return this.canvas; } /** * @param {number} radius * @return {Circle} */ setRadius(radius){ this.radius=radius; return this; } /** * @return {number} */ getRadius(){ return this.radius; } /** * @return {Circle} */ draw(){ const cnv=this.getCanvas(); const ctx=cnv.getContext('2d'); const center=[ cnv.width/2, cnv.height/2 ]; ctx.beginPath(); ctx.arc( center[0], center[1], this.getRadius(), 0, 2*Math.PI ); ctx.stroke(); ctx.fill(); return this; } /** * @param {number} angle * @return {Circle} */ drawSection(angle){ const cnv=this.getCanvas(); const ctx=cnv.getContext('2d'); const center=[ cnv.width/2, cnv.height/2 ]; const radius=this.getRadius(); const x=center[0]; const y=center[1]; angle=180 - angle/2; const points=[ [ radius*Math.sin(-angle*Math.PI/180)+x, radius*Math.cos(-angle*Math.PI/180)+y, ], [ radius*Math.sin(angle*Math.PI/180)+x, radius*Math.cos(angle*Math.PI/180)+y, ] ]; ctx.beginPath(); ctx.moveTo(points[0][0],points[0][1]); ctx.lineTo(x,y); ctx.lineTo(points[1][0],points[1][1]); ctx.stroke(); //Заливка ctx.beginPath(); ctx.fillStyle='#F00'; ctx.strokeStyle='#F00'; ctx.moveTo(x,y); ctx.lineTo(points[0][0],points[0][1]); let yy = y + (radius / Math.cos(angle*Math.PI/180)); ctx.arcTo(x, yy, points[1][0],points[1][1], radius); ctx.lineTo(x,y); ctx.stroke(); ctx.fill(); return this; } } const circle=new Circle(document.getElementById('canvas')); const ctx=circle.getCanvas().getContext('2d'); let angle=0; const framesPerSecond=60; const step=30/framesPerSecond; setTimeout(function run(){ ctx.clearRect(0,0,canvas.width,canvas.height); ctx.fillStyle='#F5F5F5'; circle.draw().drawSection(angle=(angle+step)%360); setTimeout(run,1000/framesPerSecond); },1000/framesPerSecond); </script> </body> </html> |
Rise, у меня проблема с "arcTo" была, а не с "arc".
В итоге все на "arc" и переделал. рони, еще раз спасибо, но я оставлю свое решение с "arc", "arcTo" слишком геморойный метод. |
Часовой пояс GMT +3, время: 18:43. |