এইচটিএমএল ক্যানভাসে গোলাকার আয়তক্ষেত্রটি কীভাবে আঁকবেন?


140

আমি দেখতে পেয়েছি যে কেবল আয়তক্ষেত্র পূরণ করতে পারে তবে কোনও গোলাকার কোণ নেই, আমি এটি কীভাবে করব?


1
এই লোকটি একটি দুর্দান্ত পদ্ধতিতে বৃত্তাকার আয়তক্ষেত্রগুলি (পূর্ণ, সীমান্ত দিয়ে ...) কীভাবে তৈরি করবেন তা লিখেছিলেন
নার্দি

উত্তর:


47

এইচটিএমএল 5 ক্যানভাসটি বৃত্তাকার কোণগুলির সাথে একটি আয়তক্ষেত্র আঁকতে কোনও পদ্ধতি সরবরাহ করে না।

কেমন ব্যবহার lineTo()এবংarc() পদ্ধতি ?

আপনি quadraticCurveTo()পদ্ধতির পরিবর্তে পদ্ধতিটিও ব্যবহার করতে পারেন arc()


কিছু কারণে, আমি ফায়ারফক্স 3.5 এবং অপেরা 10.0-তে আর্কটো নিয়ে সমস্যা বোধ করছি। : এই সাইটটির অনুরূপ ditchnet.org/canvas/CanvasRoundedCornerExample.html
bgw

আরকিটিও এফএফ এর সর্বশেষ সংস্করণে স্থির করা হয়েছে।
অ্যাশ ব্লু

3
আপনি একটি উদাহরণ প্রদান করতে পারেন?
জিন-পিয়েরে বাকোটে

324

আমার একই জিনিসটি করা দরকার এবং এটি করার একটি পদ্ধতি তৈরি করা হয়েছিল।

// Now you can just call
var ctx = document.getElementById("rounded-rect").getContext("2d");
// Draw using default border radius, 
// stroke it but no fill (function's default values)
roundRect(ctx, 5, 5, 50, 50);
// To change the color on the rectangle, just manipulate the context
ctx.strokeStyle = "rgb(255, 0, 0)";
ctx.fillStyle = "rgba(255, 255, 0, .5)";
roundRect(ctx, 100, 5, 100, 100, 20, true);
// Manipulate it again
ctx.strokeStyle = "#0f0";
ctx.fillStyle = "#ddd";
// Different radii for each corner, others default to 0
roundRect(ctx, 300, 5, 200, 100, {
  tl: 50,
  br: 25
}, true);

/**
 * Draws a rounded rectangle using the current state of the canvas.
 * If you omit the last three params, it will draw a rectangle
 * outline with a 5 pixel border radius
 * @param {CanvasRenderingContext2D} ctx
 * @param {Number} x The top left x coordinate
 * @param {Number} y The top left y coordinate
 * @param {Number} width The width of the rectangle
 * @param {Number} height The height of the rectangle
 * @param {Number} [radius = 5] The corner radius; It can also be an object 
 *                 to specify different radii for corners
 * @param {Number} [radius.tl = 0] Top left
 * @param {Number} [radius.tr = 0] Top right
 * @param {Number} [radius.br = 0] Bottom right
 * @param {Number} [radius.bl = 0] Bottom left
 * @param {Boolean} [fill = false] Whether to fill the rectangle.
 * @param {Boolean} [stroke = true] Whether to stroke the rectangle.
 */
function roundRect(ctx, x, y, width, height, radius, fill, stroke) {
  if (typeof stroke === 'undefined') {
    stroke = true;
  }
  if (typeof radius === 'undefined') {
    radius = 5;
  }
  if (typeof radius === 'number') {
    radius = {tl: radius, tr: radius, br: radius, bl: radius};
  } else {
    var defaultRadius = {tl: 0, tr: 0, br: 0, bl: 0};
    for (var side in defaultRadius) {
      radius[side] = radius[side] || defaultRadius[side];
    }
  }
  ctx.beginPath();
  ctx.moveTo(x + radius.tl, y);
  ctx.lineTo(x + width - radius.tr, y);
  ctx.quadraticCurveTo(x + width, y, x + width, y + radius.tr);
  ctx.lineTo(x + width, y + height - radius.br);
  ctx.quadraticCurveTo(x + width, y + height, x + width - radius.br, y + height);
  ctx.lineTo(x + radius.bl, y + height);
  ctx.quadraticCurveTo(x, y + height, x, y + height - radius.bl);
  ctx.lineTo(x, y + radius.tl);
  ctx.quadraticCurveTo(x, y, x + radius.tl, y);
  ctx.closePath();
  if (fill) {
    ctx.fill();
  }
  if (stroke) {
    ctx.stroke();
  }

}
<canvas id="rounded-rect" width="500" height="200">
  <!-- Insert fallback content here -->
</canvas>


2
নিখুঁত উত্তর ... এটি কীভাবে এখনও ক্যানভাসের নয় ?! ধন্যবাদ।
অ্যান্ডয়েস্টোহলিউড

1
কোডটিতে একটি ত্রুটি রয়েছে, তার পরে স্ট্রোক করা দরকার, অন্যথায় ছোট আয়তক্ষেত্রগুলিতে ফিল স্ট্রোকটি ওভাররাইট করে।
জিগ ম্যান্ডেল

2
আমার কাছে হাতে উদাহরণ নেই তবে আমি আমার কোডটিতে পরীক্ষিত কেসের জন্য আমাকে সেই আদেশটি সংশোধন করতে হয়েছিল। এর যৌক্তিক, কীভাবে এটি সঠিকভাবে স্ট্রোক করতে পারে (রেক্ট ব্যাকগ্রাউন্ডের রঙ ব্যবহার করে স্মুথ সহ) আপনি যদি এখনও রেক্টটি পূরণ করেন নি?
জিগ ম্যান্ডেল

2
@ জুয়ান হেই আমার খারাপ, আমি ব্লগ পোস্টটি লক্ষ্য করেছি এবং পরে সেই জালটি ধরলাম। আমি সম্পাদনাটি পূর্বাবস্থায় ফেরাতে চাইছিলাম। গুডজব ম্যান আপনাকে +1 করেছে! 😁
ফেব্বব

6
জিগ ম্যান্ডেল সঠিক: এটি পূরণ করা উচিত এবং তারপরে স্ট্রোক করা উচিত। কারণটি হ'ল যদি আপনি স্ট্রোক করেন এবং তারপরে পূরণ করেন তবে লাইনের প্রস্থটি অর্ধেক হয়ে যায়। সত্যিই ঘন রেখার প্রস্থের সাথে এটি চেষ্টা করুন (বলুন, 20) এবং একটি বৃত্তাকার আয়তক্ষেত্রের তুলনা করুন যা ব্যাকগ্রাউন্ড রঙে পূর্ণ হয় গোলাকার আয়তক্ষেত্রের সাথে যা পূর্ণ হয় না। ভরাট একের লাইনের প্রস্থ পূরণ না করা লাইনের প্রস্থের অর্ধেক হবে।
অ্যান্ড্রু স্ট্যাসি

106

আমি @ জোফের সমাধানটি দিয়ে শুরু করেছি, তবে প্রস্থ / উচ্চতার পরামিতিগুলি ব্যবহার করতে এটি আবার লিখেছি এবং ব্যবহারটি arcToএটিকে আরও কিছুটা বিশ্রুত করে তোলে:

CanvasRenderingContext2D.prototype.roundRect = function (x, y, w, h, r) {
  if (w < 2 * r) r = w / 2;
  if (h < 2 * r) r = h / 2;
  this.beginPath();
  this.moveTo(x+r, y);
  this.arcTo(x+w, y,   x+w, y+h, r);
  this.arcTo(x+w, y+h, x,   y+h, r);
  this.arcTo(x,   y+h, x,   y,   r);
  this.arcTo(x,   y,   x+w, y,   r);
  this.closePath();
  return this;
}

এছাড়াও প্রসঙ্গটি ফিরিয়ে দেওয়া হচ্ছে যাতে আপনি একটু চেইন করতে পারেন। উদাহরণ:

ctx.roundRect(35, 10, 225, 110, 20).stroke(); //or .fill() for a filled rect

4
আমি ভাল সমাধানটি বাদ দিয়ে ক্যানভাস রেন্ডারিং প্রসঙ্গে গণ্ডগোল করব না।
অ্যাশ ব্লু

এই সমাধানটির সমস্যাটি হ'ল আপনি প্রতিটি কোণার জন্য ব্যাসার্ধকে স্বাধীনভাবে নিয়ন্ত্রণ করতে পারবেন না। যথেষ্ট নমনীয় নয়। নীচে আমার সমাধান দেখুন।
Corgalore

1
এটি একটি কেন্দ্রিক আয়তক্ষেত্র, যদি কারও কাছে এর শীর্ষ বাম কোণে একটির প্রয়োজন হয় (x,y), প্রসঙ্গটি সংরক্ষণ করুন, একটি অনুবাদ যুক্ত করুন (-w/2,-h/2)এবং প্রসঙ্গে পুনরুদ্ধার করুন।
nessa.gp

আপনাকে ধন্যবাদ, এই একমাত্র তিনিই আমার পক্ষে এ পর্যন্ত কাজ করেছেন, অন্যরা যখন আমাকে ব্যাসার্ধ উচ্চতা বা প্রস্থের চেয়ে বৃহত্তর বা বড় ছিল তখন তারা আমাকে সমস্যা দেয়। বাস্তবায়িত!
হাওজিকি

1
নোট করুন যে এই দ্রবণটি কোনও বহুভুজকে গোলাকার করার জন্য কাজ করে। একটি বেহালার
ডগুলেজ

23

হুয়ান, প্রতিটি আয়তক্ষেত্র কোণার ব্যাসার্ধ পৃথকভাবে পরিবর্তনের জন্য অনুমতি দেওয়ার জন্য আমি আপনার পদ্ধতিতে সামান্য উন্নতি করেছি:

/** 
 * Draws a rounded rectangle using the current state of the canvas.  
 * If you omit the last three params, it will draw a rectangle  
 * outline with a 5 pixel border radius  
 * @param {Number} x The top left x coordinate 
 * @param {Number} y The top left y coordinate  
 * @param {Number} width The width of the rectangle  
 * @param {Number} height The height of the rectangle 
 * @param {Object} radius All corner radii. Defaults to 0,0,0,0; 
 * @param {Boolean} fill Whether to fill the rectangle. Defaults to false. 
 * @param {Boolean} stroke Whether to stroke the rectangle. Defaults to true. 
 */
CanvasRenderingContext2D.prototype.roundRect = function (x, y, width, height, radius, fill, stroke) {
    var cornerRadius = { upperLeft: 0, upperRight: 0, lowerLeft: 0, lowerRight: 0 };
    if (typeof stroke == "undefined") {
        stroke = true;
    }
    if (typeof radius === "object") {
        for (var side in radius) {
            cornerRadius[side] = radius[side];
        }
    }

    this.beginPath();
    this.moveTo(x + cornerRadius.upperLeft, y);
    this.lineTo(x + width - cornerRadius.upperRight, y);
    this.quadraticCurveTo(x + width, y, x + width, y + cornerRadius.upperRight);
    this.lineTo(x + width, y + height - cornerRadius.lowerRight);
    this.quadraticCurveTo(x + width, y + height, x + width - cornerRadius.lowerRight, y + height);
    this.lineTo(x + cornerRadius.lowerLeft, y + height);
    this.quadraticCurveTo(x, y + height, x, y + height - cornerRadius.lowerLeft);
    this.lineTo(x, y + cornerRadius.upperLeft);
    this.quadraticCurveTo(x, y, x + cornerRadius.upperLeft, y);
    this.closePath();
    if (stroke) {
        this.stroke();
    }
    if (fill) {
        this.fill();
    }
} 

এটি এর মতো ব্যবহার করুন:

var canvas = document.getElementById("canvas");
var c = canvas.getContext("2d");
c.fillStyle = "blue";
c.roundRect(50, 100, 50, 100, {upperLeft:10,upperRight:10}, true, true);

1
এই পদ্ধতিটি বৃত্তাকার কোণগুলিতে এত নিয়ন্ত্রণ সরবরাহ করে। কেন এটি গৃহীত উত্তর নয়>
বিঘ্নেশ রাউত

@ বিঘ্নেশরৌট সম্ভবত কারণ এই উত্তরটি অনুলিপি / মূল গৃহীত উত্তর আটকানো হয়েছে এবং বৃত্তাকার কোণগুলি যুক্ত করেছে। আমি এটিকে গ্রহণযোগ্য উত্তরে অন্তর্ভুক্ত করে এই উত্তরটির ক্রেডিট দিয়েছি। গৃহীত উত্তরের একটি জীবন্ত উদাহরণ রয়েছে এবং যদি আপনি একই ব্যাসার্ধের সাথে সমস্ত কোণগুলি (যা সবচেয়ে সাধারণ ক্ষেত্রে হয়) চান তবে বাক্য গঠন সহজ হয়। শেষ অবধি, এই উত্তরটি কোনও নেটিভ কোন নেটিভ অবজেক্টের প্রোটোটাইপটি সংশোধন করার পরামর্শ দেয়
জুয়ান মেন্ডেস

12

drawPolygonনিচে ফাংশন আঁকা ব্যবহার করা যেতে পারে কোন বৃত্তাকার কোণ সঙ্গে বহুভুজ।

এটি এখানে চলমান দেখুন।

function drawPolygon(ctx, pts, radius) {
  if (radius > 0) {
    pts = getRoundedPoints(pts, radius);
  }
  var i, pt, len = pts.length;
  ctx.beginPath();
  for (i = 0; i < len; i++) {
    pt = pts[i];
    if (i == 0) {          
      ctx.moveTo(pt[0], pt[1]);
    } else {
      ctx.lineTo(pt[0], pt[1]);
    }
    if (radius > 0) {
      ctx.quadraticCurveTo(pt[2], pt[3], pt[4], pt[5]);
    }
  }
  ctx.closePath();
}

function getRoundedPoints(pts, radius) {
  var i1, i2, i3, p1, p2, p3, prevPt, nextPt,
      len = pts.length,
      res = new Array(len);
  for (i2 = 0; i2 < len; i2++) {
    i1 = i2-1;
    i3 = i2+1;
    if (i1 < 0) {
      i1 = len - 1;
    }
    if (i3 == len) {
      i3 = 0;
    }
    p1 = pts[i1];
    p2 = pts[i2];
    p3 = pts[i3];
    prevPt = getRoundedPoint(p1[0], p1[1], p2[0], p2[1], radius, false);
    nextPt = getRoundedPoint(p2[0], p2[1], p3[0], p3[1], radius, true);
    res[i2] = [prevPt[0], prevPt[1], p2[0], p2[1], nextPt[0], nextPt[1]];
  }
  return res;
};

function getRoundedPoint(x1, y1, x2, y2, radius, first) {
  var total = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)),
      idx = first ? radius / total : (total - radius) / total;
  return [x1 + (idx * (x2 - x1)), y1 + (idx * (y2 - y1))];
};

ফাংশনটি বহুভুজ পয়েন্টগুলির সাথে এই জাতীয় অ্যারে গ্রহণ করে:

var canvas = document.getElementById("cv");
var ctx = canvas.getContext("2d");
ctx.strokeStyle = "#000000";
ctx.lineWidth = 5;

drawPolygon(ctx, [[20,   20],
                  [120,  20],
                  [120, 120],
                  [ 20, 120]], 10);
ctx.stroke();

এটি পোস্ট করা সমাধানের একটি বন্দর এবং আরও জেনেরিক সংস্করণ এখানে


9

আমি এখানে একটি লিখেছি ... ব্যাসার্ধের উপর আরও ভাল নিয়ন্ত্রণের জন্য চতুর্ভুজ কার্ভগুলির পরিবর্তে অর্ক ব্যবহার করে। এছাড়াও, এটি স্ট্রোকিংটি ছেড়ে দেয় এবং আপনাকে ভরিয়ে দেয়

    /* Canvas 2d context - roundRect
 *
 * Accepts 5 parameters, the start_x and start_y points, the end_x and end_y points, and the radius of the corners
 * 
 * No return value
 */

CanvasRenderingContext2D.prototype.roundRect = function(sx,sy,ex,ey,r) {
    var r2d = Math.PI/180;
    if( ( ex - sx ) - ( 2 * r ) < 0 ) { r = ( ( ex - sx ) / 2 ); } //ensure that the radius isn't too large for x
    if( ( ey - sy ) - ( 2 * r ) < 0 ) { r = ( ( ey - sy ) / 2 ); } //ensure that the radius isn't too large for y
    this.beginPath();
    this.moveTo(sx+r,sy);
    this.lineTo(ex-r,sy);
    this.arc(ex-r,sy+r,r,r2d*270,r2d*360,false);
    this.lineTo(ex,ey-r);
    this.arc(ex-r,ey-r,r,r2d*0,r2d*90,false);
    this.lineTo(sx+r,ey);
    this.arc(sx+r,ey-r,r,r2d*90,r2d*180,false);
    this.lineTo(sx,sy+r);
    this.arc(sx+r,sy+r,r,r2d*180,r2d*270,false);
    this.closePath();
}

এখানে একটি উদাহরণ:

var _e = document.getElementById('#my_canvas');
var _cxt = _e.getContext("2d");
_cxt.roundRect(35,10,260,120,20);
_cxt.strokeStyle = "#000";
_cxt.stroke();

এটি কীভাবে আপনাকে ব্যাসার্ধের উপর আরও ভাল নিয়ন্ত্রণ দেয়? আমি ভেবেছিলাম আপনি x / y রেডিও (ডিম্বাকৃতি কোণ) এর অনুমতি দিতে যাচ্ছেন, এবং প্রতিটি কোণার জন্য আলাদা আলাদা রেডিয়িও উল্লেখ করছেন
জুয়ান মেন্ডেস

3
আপনার r2dসম্ভবত ডাকা হতে চান d2r
গ্রুমড্রিগ

1
@ জুয়ানমেন্ডেস: এই দ্রবণটির বৃত্তাকার কোণগুলির (আর্ক ভিত্তিক) আকারগুলি আপনার (চতুর্ভুজ ভিত্তিক) সমাধানের চেয়ে বেশি বিজ্ঞপ্তিযুক্ত। আমি মনে করি এটিই তিনি "ব্যাসার্ধের উপর আরও ভাল নিয়ন্ত্রণ" বলতে চেয়েছিলেন।
ব্রেন্ট ব্র্যাডবার্ন

আমি এই পদ্ধতিটিও ব্যবহার করেছি, এটি চতুর্ভুজ ব্যবহারের চেয়ে ভাল। তবে আপনি যদি আয়তক্ষেত্রের চেয়ে আরও জটিল কিছু আঁকেন তবে এটি অবশ্যই বেদনাদায়ক। সাথে অ্যান্ড্রয়েড ক্যানভাসের মতো একটি স্বয়ংক্রিয় পদ্ধতি ছিল।
আলেক্সেই পেট্রেনকো

7
    var canvas = document.createElement("canvas");
    document.body.appendChild(canvas);
    var ctx = canvas.getContext("2d");
    ctx.beginPath();
    ctx.moveTo(100,100);
    ctx.arcTo(0,100,0,0,30);
    ctx.arcTo(0,0,100,0,30);
    ctx.arcTo(100,0,100,100,30);
    ctx.arcTo(100,100,0,100,30);
    ctx.fill();

এটি ঠিক আমি যা খুঁজছিলাম
ড্যানিয়েল

অবশেষে একটি সংক্ষিপ্ত এবং ব্যাপক উত্তর যা আসলে কাজ করে। ধন্যবাদ।
ফ্রেঞ্জ স্কুফকা

5

সুতরাং এটি লাইনজাইন = "রাউন্ড" ব্যবহারের ভিত্তিতে এবং সঠিক অনুপাত, গণিত এবং যুক্তি দিয়ে আমি এই ফাংশনটি তৈরি করতে সক্ষম হয়েছি, এটি নিখুঁত নয় তবে আশা করি এটি সহায়তা করবে। আপনি যদি প্রতিটি কোণার আলাদা আলাদা ব্যাসার্ধ তৈরি করতে চান তবে একবার দেখুন: https://p5js.org/references/#/p5/ सही

এখানে তুমি যাও:

CanvasRenderingContext2D.prototype.roundRect = function (x,y,width,height,radius) {
    radius = Math.min(Math.max(width-1,1),Math.max(height-1,1),radius);
    var rectX = x;
    var rectY = y;
    var rectWidth = width;
    var rectHeight = height;
    var cornerRadius = radius;

    this.lineJoin = "round";
    this.lineWidth = cornerRadius;
    this.strokeRect(rectX+(cornerRadius/2), rectY+(cornerRadius/2), rectWidth-cornerRadius, rectHeight-cornerRadius);
    this.fillRect(rectX+(cornerRadius/2), rectY+(cornerRadius/2), rectWidth-cornerRadius, rectHeight-cornerRadius);
    this.stroke();
    this.fill();
}

CanvasRenderingContext2D.prototype.roundRect = function (x,y,width,height,radius) {
    radius = Math.min(Math.max(width-1,1),Math.max(height-1,1),radius);
    var rectX = x;
    var rectY = y;
    var rectWidth = width;
    var rectHeight = height;
    var cornerRadius = radius;

    this.lineJoin = "round";
    this.lineWidth = cornerRadius;
    this.strokeRect(rectX+(cornerRadius/2), rectY+(cornerRadius/2), rectWidth-cornerRadius, rectHeight-cornerRadius);
    this.fillRect(rectX+(cornerRadius/2), rectY+(cornerRadius/2), rectWidth-cornerRadius, rectHeight-cornerRadius);
    this.stroke();
    this.fill();
}
    var canvas = document.getElementById("myCanvas");
    var ctx = canvas.getContext('2d');
function yop() {
  ctx.clearRect(0,0,1000,1000)
  ctx.fillStyle = "#ff0000";
  ctx.strokeStyle = "#ff0000";  ctx.roundRect(Number(document.getElementById("myRange1").value),Number(document.getElementById("myRange2").value),Number(document.getElementById("myRange3").value),Number(document.getElementById("myRange4").value),Number(document.getElementById("myRange5").value));
requestAnimationFrame(yop);
}
requestAnimationFrame(yop);
<input type="range" min="0" max="1000" value="10" class="slider" id="myRange1"><input type="range" min="0" max="1000" value="10" class="slider" id="myRange2"><input type="range" min="0" max="1000" value="200" class="slider" id="myRange3"><input type="range" min="0" max="1000" value="100" class="slider" id="myRange4"><input type="range" min="1" max="1000" value="50" class="slider" id="myRange5">
<canvas id="myCanvas" width="1000" height="1000">
</canvas>


1
স্ট্যাকওভারফ্লোতে আপনাকে স্বাগতম! যেহেতু এই কোডটি সমস্যার সমাধান করতে পারে, আপনি কীভাবে এটি কাজ করে সে সম্পর্কে আরও ব্যাখ্যা যুক্ত করলে এটি আরও ভাল।
Tân

3

অপেরা, এফএফএস

if (window["CanvasRenderingContext2D"]) {
    /** @expose */
    CanvasRenderingContext2D.prototype.roundRect = function(x, y, w, h, r) {
        if (w < 2*r) r = w/2;
        if (h < 2*r) r = h/2;
        this.beginPath();
        if (r < 1) {
            this.rect(x, y, w, h);
        } else {
            if (window["opera"]) {
                this.moveTo(x+r, y);
                this.arcTo(x+r, y, x, y+r, r);
                this.lineTo(x, y+h-r);
                this.arcTo(x, y+h-r, x+r, y+h, r);
                this.lineTo(x+w-r, y+h);
                this.arcTo(x+w-r, y+h, x+w, y+h-r, r);
                this.lineTo(x+w, y+r);
                this.arcTo(x+w, y+r, x+w-r, y, r);
            } else {
                this.moveTo(x+r, y);
                this.arcTo(x+w, y, x+w, y+h, r);
                this.arcTo(x+w, y+h, x, y+h, r);
                this.arcTo(x, y+h, x, y, r);
                this.arcTo(x, y, x+w, y, r);
            }
        }
        this.closePath();
    };
    /** @expose */
    CanvasRenderingContext2D.prototype.fillRoundRect = function(x, y, w, h, r) {
        this.roundRect(x, y, w, h, r);
        this.fill();
    };
    /** @expose */
    CanvasRenderingContext2D.prototype.strokeRoundRect = function(x, y, w, h, r) {
        this.roundRect(x, y, w, h, r);
        this.stroke();
    };
}

যেহেতু অপেরা ওয়েবকিট করছে, সুতরাং এটিও উত্তরাধিকার ক্ষেত্রে বৈধ থাকা উচিত।


3

ক্যানভাস প্রসঙ্গটি ব্যবহারের স্বাভাবিক পদ্ধতির সাথে ফাংশনটিকে আরও সুসংগত করতে ক্যানভাস প্রসঙ্গ শ্রেণিকে একটি ' fillRoundedRect' পদ্ধতি অন্তর্ভুক্ত করার জন্য বাড়ানো যেতে পারে - যা একইভাবে বলা যেতে পারে fillRect:

var canv = document.createElement("canvas");
var cctx = canv.getContext("2d");

// If thie canvasContext class doesn't have  a fillRoundedRect, extend it now
if (!cctx.constructor.prototype.fillRoundedRect) {
  // Extend the canvaseContext class with a fillRoundedRect method
  cctx.constructor.prototype.fillRoundedRect = 
    function (xx,yy, ww,hh, rad, fill, stroke) {
      if (typeof(rad) == "undefined") rad = 5;
      this.beginPath();
      this.moveTo(xx+rad, yy);
      this.arcTo(xx+ww, yy,    xx+ww, yy+hh, rad);
      this.arcTo(xx+ww, yy+hh, xx,    yy+hh, rad);
      this.arcTo(xx,    yy+hh, xx,    yy,    rad);
      this.arcTo(xx,    yy,    xx+ww, yy,    rad);
      if (stroke) this.stroke();  // Default to no stroke
      if (fill || typeof(fill)=="undefined") this.fill();  // Default to fill
  }; // end of fillRoundedRect method
} 

কোডটি ক্যানভাস কনটেক্সট অবজেক্টের জন্য কনস্ট্রাক্টরের প্রোটোটাইপটিতে একটি ' fillRoundedRect' সম্পত্তি রয়েছে কিনা তা পরীক্ষা করে দেখেছে এবং প্রথমবারের মতো একবার যুক্ত করে। এটি পদ্ধতির মতো একই পদ্ধতিতে আহ্বান করা হয়েছে fillRect:

  ctx.fillStyle = "#eef";  ctx.strokeStyle = "#ddf";
  // ctx.fillRect(10,10, 200,100);
  ctx.fillRoundedRect(10,10, 200,100, 5);

পদ্ধতিটি arcToগ্রামড্রিংয়ের মতো পদ্ধতিটি ব্যবহার করে । পদ্ধতিতে, thisএটির একটি রেফারেন্সctx অবজেক্টের । স্ট্রোক আর্গুমেন্ট যদি পূর্বনির্ধারিত হয় তবে তা মিথ্যাতে ডিফল্ট হয়। পূর্বাভাস অপরিজ্ঞাপিত হলে আয়তক্ষেত্র পূরণ করতে ডিফল্ট পূরণ করুন।

(ফায়ারফক্সে পরীক্ষিত, আমি জানি না যে সমস্ত বাস্তবায়ন এই পদ্ধতিতে সম্প্রসারণের অনুমতি দেয় কিনা))


1
আমি যোগ করার পরামর্শ দিচ্ছি: rad = Math.min( rad, ww/2, hh/2 );যাতে এটি @ গ্রামড্রিগ সংস্করণে যেমন বৃহত্তর রেডিও সহ কাজ করে।
ব্রেন্ট ব্র্যাডবার্ন

3

এখানে কোণার বৃত্তাকারে লাইনজাইন ব্যবহার করে একটি সমাধান দেওয়া হয়েছে। আপনার যদি কেবল শক্ত আকারের প্রয়োজন হয় তবে কাজ করে যদি আপনার সীমানা ব্যাসার্ধের চেয়ে ছোট পাতলা সীমানা প্রয়োজন হয়।

    function roundedRect(ctx, options) {

        ctx.strokeStyle = options.color;
        ctx.fillStyle = options.color;
        ctx.lineJoin = "round";
        ctx.lineWidth = options.radius;

        ctx.strokeRect(
            options.x+(options.radius*.5),
            options.y+(options.radius*.5),
            options.width-options.radius,
            options.height-options.radius
        );

        ctx.fillRect(
            options.x+(options.radius*.5),
            options.y+(options.radius*.5),
            options.width-options.radius,
            options.height-options.radius
        );

        ctx.stroke();
        ctx.fill();

    }

    const canvas = document.getElementsByTagName("CANVAS")[0];
    let ctx = canvas.getContext('2d');

    roundedRect(ctx, {
        x: 10,
        y: 10,
        width: 200,
        height: 100,
        radius: 10,
        color: "red"
    });

0

বৃত্তাকার কোণগুলি পেতে চাইলে এই লাইনটি যুক্ত করার চেষ্টা করুন: ctx.lineCap = "বৃত্তাকার";


1
হাই, ওভারফ্লো স্ট্যাক করতে স্বাগতম এখানে দেখুন । আপনি কি নিশ্চিত যে এটি আয়তক্ষেত্রগুলির জন্য ব্যবহারযোগ্য উত্তর?
জেরোইন হাইয়ার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.