簡體   English   中英

Javascript-畫布CSS邊框半徑模仿

[英]Javascript - Canvas CSS border-radius imitation

我正在嘗試在畫布上模仿CSS border-radius屬性的行為。 我已經做了一些有效的事情,但是瀏覽器正在處理一些缺少的修改,我無法在畫布上復制這些修改(請參見下面的圖片鏈接作為示例)

但是,當邊界變形時,我會努力調整邊界。

這是一個示例,我們以HTML形狀為100px(寬度)X 100px(高度),然后應用以下半徑: border-radius: 100px 52px 1px 1px;

然后在具有相同參數的畫布中繪制此形狀。

然后我得到這個(紅色形狀=畫布形狀,綠色形狀= HTML形狀) https://imgur.com/a/XGuca

(抱歉,由於我的聲譽,我無法上傳圖片)

我正在使用此功能繪制形狀

function (xx, yy, ww, hh, rad, fill, stroke) {
    if (typeof(rad) === "undefined") rad = 5;
    this.beginPath();
    this.moveTo(xx, yy);
    this.arcTo(xx + ww, yy, xx + ww, yy + hh, rad.tr);
    this.arcTo(xx + ww, yy + hh, xx, yy + hh, rad.br);
    this.arcTo(xx, yy + hh, xx, yy, rad.bl);
    this.arcTo(xx, yy, xx + ww, yy, rad.tl);
    if (stroke) this.stroke();  // Default to no stroke
    if (fill || typeof(fill) === "undefined") this.fill();  // Default to fill
};

這是參數的描述

xx: X axis position yy: Y axis position ww: Width hh: Height rad: {tl:0, tr:0, br:0, bl: 0} (For top-left, top-right, bottom-right, bottom-left RADIUS)

我沒有獲得使它正常工作的能力,有人可以幫助我還是給我小費以實現目標? 謝謝 !

PS:對不起,我英語不好

(請參見下面的代碼段)

  // Ctx var ctx = document.getElementById("rounded-rect").getContext("2d"); //Round rect func ctx.constructor.prototype.fillRoundedRect = function (xx, yy, ww, hh, rad, fill, stroke) { if (typeof(rad) === "undefined") rad = 5; this.beginPath(); this.moveTo(xx, yy); this.arcTo(xx + ww, yy, xx + ww, yy + hh, rad.tr); this.arcTo(xx + ww, yy + hh, xx, yy + hh, rad.br); this.arcTo(xx, yy + hh, xx, yy, rad.bl); this.arcTo(xx, yy, xx + ww, yy, rad.tl); if (stroke) this.stroke(); // Default to no stroke if (fill || typeof(fill) === "undefined") this.fill(); // Default to fill }; ctx.fillStyle = "red"; ctx.strokeStyle = "#ddf"; var copy = document.getElementById('copy'); var tl = document.getElementById('tl'); var tr = document.getElementById('tr'); var bl = document.getElementById('bl'); var br = document.getElementById('br'); var off = document.getElementById('off'); function test() { ctx.clearRect(0, 0, 600, 500); /* 1.Top left */ /* 2. Top right */ /* 3. Bottom right */ /* 4. Bottom left */ var borders = [tl.value, tr.value, br.value, bl.value].join('px ') + 'px'; copy.style.borderRadius = borders; var copyRad = borders.replace(/px/g, '').split(' ').map(function (a) { return parseInt(a) }); var rad = { tl: copyRad[0], tr: copyRad[1], br: copyRad[2], bl: copyRad[3] }; var o = +off.value; ctx.fillRoundedRect(15 + o, 15 + o, 100, 100, rad); } tl.oninput = test; tr.oninput = test; bl.oninput = test; br.oninput = test; off.oninput = test; test(); 
 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> html, body { margin: 0; padding: 0; } </style> </head> <body> <div style="display:inline-block; position: absolute; left:120px;top:120px; width: 100px; height: 100px; background:green; border-radius: 10px 5px 10px 20px;" id="copy"> </div> <canvas style="display: inline-block; position: absolute; zindex:0; left:0; top:0;" id="rounded-rect" width="600" height="500"> </canvas> <div style="top: 300px; position:absolute; z-index: 1;"> <label> Top left <input type="range" min="1" max="100" value="0" class="slider" id="tl"></label><br/> <label> Top right <input type="range" min="1" max="100" value="0" class="slider" id="tr"></label><br/> <label> Bottom left <input type="range" min="1" max="100" value="0" class="slider" id="bl"></label><br/> <label> Bottom right <input type="range" min="1" max="100" value="0" class="slider" id="br"></label><br/> <label> Offset <input type="range" min="1" max="200" value="0" class="slider" id="off"></label><br/> </div> </body> </html> 

似乎瀏覽器如果變形會以某種方式校正半徑。 我創建了correctRadius函數,該函數可以執行以下操作。 當然,結果並不完全相同,但至少形狀沒有任何間隙。

 // Ctx var ctx = document.getElementById("rounded-rect").getContext("2d"); function correctRadius(r, w, h) { if (r.tl + r.tr > w) { r.tl -= (r.tl + r.tr - w) / 2; r.tr = w - r.tl; } if (r.bl + r.br > w) { r.br -= (r.br + r.bl - w) / 2; r.bl = w - r.br; } if (r.tl + r.bl > h) { r.tl -= (r.tl + r.bl - h) / 2; r.bl = h - r.tl; } if (r.tr + r.br > h) { r.tr -= (r.tr + r.br - h) / 2; r.br = h - r.tr; } } //Round rect func ctx.constructor.prototype.fillRoundedRect = function (xx, yy, ww, hh, rad, fill, stroke) { correctRadius(rad, ww, hh); if (typeof(rad) === "undefined") rad = 5; this.beginPath(); this.moveTo(xx, yy); this.arcTo(xx + ww, yy, xx + ww, yy + hh, rad.tr); this.arcTo(xx + ww, yy + hh, xx, yy + hh, rad.br); this.arcTo(xx, yy + hh, xx, yy, rad.bl); this.arcTo(xx, yy, xx + ww, yy, rad.tl); if (stroke) this.stroke(); // Default to no stroke if (fill || typeof(fill) === "undefined") this.fill(); // Default to fill }; ctx.fillStyle = "red"; ctx.strokeStyle = "#ddf"; var copy = document.getElementById('copy'); var tl = document.getElementById('tl'); var tr = document.getElementById('tr'); var bl = document.getElementById('bl'); var br = document.getElementById('br'); var off = document.getElementById('off'); function test() { ctx.clearRect(0, 0, 600, 500); /* 1.Top left */ /* 2. Top right */ /* 3. Bottom right */ /* 4. Bottom left */ var borders = [tl.value, tr.value, br.value, bl.value].join('px ') + 'px'; copy.style.borderRadius = borders; var copyRad = borders.replace(/px/g, '').split(' ').map(function (a) { return parseInt(a) }); var rad = { tl: copyRad[0], tr: copyRad[1], br: copyRad[2], bl: copyRad[3] }; var o = +off.value; ctx.fillRoundedRect(15 + o, 15 + o, 100, 100, rad); } tl.oninput = test; tr.oninput = test; bl.oninput = test; br.oninput = test; off.oninput = test; test(); 
 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> html, body { margin: 0; padding: 0; } </style> </head> <body> <div style="display:inline-block; position: absolute; left:120px;top:120px; width: 100px; height: 100px; background:green; border-radius: 10px 5px 10px 20px;" id="copy"> </div> <canvas style="display: inline-block; position: absolute; zindex:0; left:0; top:0;" id="rounded-rect" width="600" height="500"> </canvas> <div style="top: 300px; position:absolute; z-index: 1;"> <label> Top left <input type="range" min="1" max="100" value="0" class="slider" id="tl"></label><br/> <label> Top right <input type="range" min="1" max="100" value="0" class="slider" id="tr"></label><br/> <label> Bottom left <input type="range" min="1" max="100" value="0" class="slider" id="bl"></label><br/> <label> Bottom right <input type="range" min="1" max="100" value="0" class="slider" id="br"></label><br/> <label> Offset <input type="range" min="1" max="200" value="0" class="slider" id="off"></label><br/> </div> </body> </html> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM