- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想将以下 CSS 形状复制到 Canvas 中。它具有以下属性:
width: 325px;
height: 200px;
background: green;
border-radius: 60px 110px / 100px 80px;
我已经有了制作圆 Angular 矩形的功能,但没有那么变形......参见相关的堆栈帖子:https://stackoverflow.com/a/48491607/9264003
我尝试了 bezierCurveTo()
和 arcTo()
函数,但没有成功。
我认为我们必须为每个 Angular 计算一个椭圆:左上角、右上角、右下角、左下角,但我完全不确定...
如果有人要重现这个形状,或者给我任何提示或公式来计算这个,那将是一个很好的开始!
最佳答案
实际上有一个ellipse
2DContext API 的方法。它的浏览器支持不是很好,但可以polyfilled .
使用这种方法简化了很多操作,因为我们可以用它在每个 Angular 上绘制四分之一的椭圆,但它并不能解决整个问题...
您仍然需要解析 CSSString 才能知道如何绘制椭圆,为此,我使用了一个简单的虚拟 div + getComputedStyle。
根据规范,如果两个 border-XXX-XXX-radius 计算值之一是 0px
,那么我们应该画一个方 Angular 。
您还必须考虑 overlapping corners rule ,为此,我借用了 niklasvh 的 html2canvas implementation CSSWG 算法。
这是我尝试为 Canvas 创建这样一个 Border-radius 函数,但我没有进行广泛的测试,所以它可能会失败。
另请注意,它只接受速记 border-radius
CSS 语法,但如果您还想传递普通语法,则很容易调整。
var w = c.width = 325,
h = c.height = 200,
ctx = c.getContext('2d');
ctx.fillStyle = 'blue';
inp.onchange = function() {
blurb.style.borderRadius = this.value;
ctx.clearRect(0, 0, w, h);
drawBorderRadius(ctx, this.value, w, h);
ctx.fill();
};
inp.onchange();
function drawBorderRadius(ctx, CSSRule, w, h) {
var radii = parseBorderRadiusRules(CSSRule);
fixOverlappingCorners(radii);
ctx.beginPath();
var x, y, h_, v_;
// top-left corner
if (hasZero(radii.topleft))
ctx.moveTo(0, 0);
else {
x = radii.topleft[0];
y = radii.topleft[1];
ctx.ellipse(x, y, x, y, 0, Math.PI, Math.PI * 1.5);
}
// top-right corner
if (hasZero(radii.topright))
ctx.lineTo(w, 0);
else {
x = radii.topright[0];
y = radii.topright[1];
ctx.ellipse(w - radii.topright[0], y, x, y, 0, -Math.PI / 2, 0);
}
//bottom-right corner
if (hasZero(radii.bottomright))
ctx.lineTo(w, h);
else {
x = radii.bottomright[0];
y = radii.bottomright[1];
ctx.ellipse(w - x, h - y, x, y, 0, 0, Math.PI / 2);
}
//bottom-left corner
if (hasZero(radii.bottomleft))
ctx.lineTo(0, h);
else {
x = radii.bottomleft[0];
y = radii.bottomleft[1];
ctx.ellipse(x, h - y, x, y, 0, Math.PI / 2, Math.PI);
}
// we need to check if one value is zero in order to draw a squared corner in such case
function hasZero(corner) {
return !Array.isArray(corner) ||
corner.indexOf(0) > -1 ||
corner.indexOf(NaN) > -1;
}
// returns a dictionnary of four corners [horizontal, vertical] values as px
function parseBorderRadiusRules(CSSstring) {
var elem = document.createElement('div');
elem.style.borderRadius = CSSstring;
elem.style.width = w;
elem.style.height = h;
elem.style.position = 'absolute';
elem.zIndex = -999;
document.body.appendChild(elem);
var computed = getComputedStyle(elem);
var radii = {
topleft: cleanRule(computed['border-top-left-radius']),
topright: cleanRule(computed['border-top-right-radius']),
bottomright: cleanRule(computed['border-bottom-right-radius']),
bottomleft: cleanRule(computed['border-bottom-left-radius'])
};
document.body.removeChild(elem);
return radii;
function cleanRule(str) {
var xy = str.split(' ');
if (xy.length === 1) {
xy[1] = xy[0];
}
return xy.map(toPx);
}
function toPx(str, index) {
var val = parseFloat(str);
if (str.indexOf('%') > -1) {
return percentageToPx(val, !index ? w : h);
}
return val;
}
function percentageToPx(percent, length) {
return length * (percent / 100);
}
}
// borrowed from https://github.com/niklasvh/html2canvas/blob/8788a9f458f538c004a626c5ce7ee24b53e48c1c/src/Bounds.js#L200
// https://github.com/niklasvh/html2canvas/blob/master/LICENSE
function fixOverlappingCorners(radii) {
var factors = [
w / (radii.topleft[0] + radii.topright[0]),
w / (radii.bottomleft[0] + radii.bottomright[0]),
h / (radii.topleft[1] + radii.bottomleft[1]),
h / (radii.topright[1] + radii.bottomright[1])
],
minFactor = Math.min.apply(null, factors);
if (minFactor <= 1) {
for (var key in radii) {
radii[key] = radii[key].map(scale);
}
}
function scale(value) {
return value * minFactor;
}
}
}
#blurb {
width: 325px;
height: 200px;
background: green;
}
input:checked+.cont>#blurb {
opacity: 0.5;
position: absolute;
background: red;
}
.cont {
position: relative;
}
<input id="inp" value="60px 110px / 100px 80px">
<label>overlap</label><input type="checkbox">
<div class="cont">
<div id="blurb"></div>
<canvas id="c"></canvas>
</div>
关于javascript - 使用 canvas API 复制 CSS border-radius,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48554006/
我正在尝试实现 RADIUS 协议(protocol)。根据 RFC 2866,对于 RADIUS 记帐,在计算 Authenticator 字段时,这些步骤如下: The Authenticator
有一台pptp服务器,我使用radius服务器进行认证。有时 vpn 客户端不明原因离线,因此 radius 无法清除客户端的 session 。 我想用radius client运行一个进程来监控c
struct circle { int center; int radius; }; struct circle *cir; cir.center cir->radius (cir.rad
IE9、Firefox 4、Opera 10.5、Safari 5、Chrome 4、WebKit 532.5 支持 CSS3 border-radius。 最新的 jquerycurvycorner
环境: Radius 服务器:FreeRadius Radius 客户端:TinyRadius 我正在我们的组织中设置 RADIUS 服务器。我想保护我的 RADIUS 服务器,以便客户端需要提供两件
我继承了一个应该在 IE8 中工作的 Web 元素(以及其他浏览器,但相比之下我并不担心它们)。当我在 Firefox 中运行该网站并检查它提到的错误控制台时: “警告:未知属性‘-moz-borde
我是 Threejs 的新手。我试图用不同的方式画一个肘部 begin_radius和 end_radius沿着带有 curve_radius 的曲线路径和一个 angle ,却无法取得成果。 Cyl
有什么方法可以在 CSS 验证器中验证 -moz-border-radius/-webkit-border-radius 吗? 客户想要侧边栏中的验证按钮(呃!),但我找不到任何绕过它的方法。我也使用
我的 Captiveportal 显示出非常奇怪的行为。 偶尔(5-6 天内 2-3 次)它会返回有关耗尽允许内存大小的标准 php 错误。日志显示此时 FreeRadius 没有应答 Error s
Edit1: Span code in the code and it's style are not needed, i just added them to show, where my bord
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
基本上我想知道 Microsoft、LinkedIn 和其他人所指的渲染性能差异是在 0px 和 1px 之间还是在 1px 到无穷大 px 之间。 最佳答案 看看this article ,它没有回
谁能澄清为什么添加 padding-top 似乎会导致浏览器忽略 border-radius 属性? 您可以通过从样式属性中删除/添加填充来进行快速测试,注意如何使用填充,忽略边框半径。 这是一个错
我正在研究在 iOS 的 UIWebView 中使用的一些 CSS。我可以使用 border-radius 属性在 iOS 6 中将 div 的 Angular 变圆,但我无法使用 border-ra
这是数学高手的数学/几何问题(不是我最擅长的科目)。这是针对 WPF 的,但应该足够通用以解决问题: 我有两个嵌入的 Border 元素,外部元素具有特定的角半径 R 和边框厚度 T。给定这两个值,内
我有这个 HTML 代码: 还有这个 CSS: .categoryButton { position:
我正在使用 cakephp 并想为某些部分的圆 Angular 做 css border-radius。它适用于除 IE 之外的所有其他浏览器。我现在指的是链接 http://www.htmlremi
我在按钮上遇到 border-top-left-radius 和 border-bottom-left-radius 的问题,这似乎在开发构建中有效,但在生产。当我运行 ng serve 时,我得到了
我一直在寻找 acctinputoctets 或 acctoutputoctets 的明确含义我一直将它用作字节。 但是这个属性的真正单位是什么?我不懂八位位组,而且它太含糊了。 你能用通俗的语言解释
我一直在寻找 acctinputoctets 或 acctoutputoctets 的明确含义我一直将它用作字节。 但是这个属性的真正单位是什么?我不懂八位位组,而且它太含糊了。 你能用通俗的语言解释
我是一名优秀的程序员,十分优秀!