- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的用例是模仿 css 边框渲染。有可能吗,使用 CanvasRenderingContext2D::rect
使用 CanvasRenderingContext2D::setLineDash
的方法模拟与 css 渲染器相同的边框绘制,如 border: 5px dashed red
。考虑这个例子:
let canvas = document.querySelector('canvas');
let ctx = canvas.getContext('2d');
ctx.lineWidth = 5
ctx.strokeStyle = 'red'
ctx.lineCap = 'square'
ctx.setLineDash([10, 10]);
ctx.beginPath();
ctx.moveTo(2.5,2.5);
ctx.rect(2.5, 2.5, 195, 65);
ctx.stroke();
div {
border: 5px dashed red;
width: 200px;
height: 70px;
box-sizing: border-box;
margin-bottom: 5px;
}
canvas {
display: block;
width: 200px;
height: 70px;
}
<div></div>
<canvas width=200 height=70></canvas>
您可能会注意到问题出在边缘。
我试图修改间隙和破折号的大小,但似乎不可能获得与 css 示例中相同的行为:边缘上的线条比侧面上的线条大。作为一种解决方法,我可以想象用一条线绘制每一面,但我想使用 rect
方法一次绘制。
提前谢谢你。
最佳答案
CSS border-style: dashed
算法不受规范约束,因此不可能在 Canvas API 中呈现完全相同的效果。
然后,你必须知道甚至 CSS 也是逐行渲染的:border
是所有 border-top-XXX
的简写, border-right-XXX
, border-bottom-XXX
, border-left-XXX
.
这就是为什么它会这样:每个边框都有独立于其他边框的划线集。
无论如何,如果你想用 Canvas API 来做,最简单的解决方案是做同样的事情,使用四行,并分别设置它们的短划线。
这是对破折号进行归一化以使它们始终在边缘开始和结束的粗略尝试:
var ctx = c.getContext('2d');
ctx.lineCap = 'square';
// returns a normalized dashArray per segment
// This in no way does the same as any browser's implementation,
// this is just a lazy way to always get dashes start and end at edges
function getLineDash(x1, y1, x2, y2) {
var length = Math.hypot((x2 - x1), (y2 - y1));
var dash_length = length / 8;
var nb_of_dashes = length / dash_length;
var dash_gap = (dash_length * 0.66);
dash_length -= dash_gap * 0.33;
return [dash_length, dash_gap];
}
function draw() {
ctx.lineWidth = lineWidth_.value;
ctx.clearRect(0, 0, c.width, c.height);
var points = [
[x1_.value, y1_.value],
[x2_.value, y2_.value],
[x3_.value, y3_.value],
[x4_.value, y4_.value]
];
points.forEach(function(pt, i) {
var next = points[(i + 1) % points.length];
ctx.beginPath();
ctx.moveTo(pt[0], pt[1]);
ctx.lineTo(next[0], next[1]);
ctx.setLineDash(getLineDash(pt[0], pt[1], next[0], next[1]));
ctx.stroke();
});
}
draw();
document.oninput = function(e) {
if (e.target.parentNode.parentNode === inputs_) {
draw();
}
}
label {
display: inline-block;
}
input {
max-width: 50px;
}
<div id="inputs_">
<label>x1<input type="number" id="x1_" value="10"></label>
<label>y1<input type="number" id="y1_" value="25"></label>
<label>x2<input type="number" id="x2_" value="350"></label>
<label>y2<input type="number" id="y2_" value="25"></label>
<label>x3<input type="number" id="x3_" value="350"></label>
<label>y3<input type="number" id="y3_" value="225"></label>
<label>x4<input type="number" id="x4_" value="10"></label>
<label>y4<input type="number" id="y4_" value="225"></label>
<label>lineWidth<input type="number" id="lineWidth_" value="3"></label>
</div>
<canvas id="c" width="400" height="400"></canvas>
现在,如果您只想使用 XXXRect
,您还可以创建一个包含所有破折号的巨大破折号数组...
var ctx = c.getContext('2d');
ctx.lineCap = 'square';
function getRectDashes(width, height) {
var w_array = getLineDashes(width, 0, 0, 0);
var h_array = getLineDashes(0, height, 0, 0);
dashArray = [].concat.apply([], [w_array, 0, h_array, 0, w_array, 0, h_array]);
return dashArray;
}
// same as previous snippet except that it does return all the segment's dashes
function getLineDashes(x1, y1, x2, y2) {
var length = Math.hypot((x2 - x1), (y2 - y1));
var dash_length = length / 8;
var nb_of_dashes = length / dash_length;
var dash_gap = dash_length * 0.66666;
dash_length -= dash_gap * 0.3333;
var total_length = 0;
var dasharray = [];
var next;
while (total_length < length) {
next = dasharray.length % 2 ? dash_gap : dash_length;
total_length += next;
dasharray.push(next);
}
return dasharray;
}
function draw() {
ctx.clearRect(0, 0, c.width, c.height);
ctx.lineWidth = lineWidth_.value;
var w = width_.value,
h = height_.value;
ctx.setLineDash(getRectDashes(w, h));
ctx.strokeRect(20, 20, w, h);
}
draw();
document.oninput = function(e) {
if (e.target.parentNode.parentNode === inputs_)
draw();
};
label {
display: inline-block;
}
input {
max-width: 50px;
}
<div id="inputs_">
<label>width<input type="number" id="width_" value="200"></label>
<label>height<input type="number" id="height_" value="225"></label>
<label>lineWidth<input type="number" id="lineWidth_" value="3"></label>
</div>
<canvas id="c" width="400" height="400"></canvas>
关于javascript - 以与 css 边框相同的方式在 Canvas 上绘制虚线和点线矩形 : draw 4 same edges,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47296842/
最近,我在各种俄罗斯Web 2.0网站中看到了点缀和虚线超链接的广泛使用。通常,此类链接(在其下方具有虚线或虚线,而不是普通的实线)不会将用户引导至另一页面,而是在同一页面上执行操作而不重新加载该页面
Google 没有帮助我找到问题的解决方案。 (据我所知...)。 我想知道是否可以在 Android 上画一 strip 有 9 个补丁功能的虚线。 我的目标是从一个布局到另一个布局画一条虚线。 我
有没有办法将多条线段视为一条线? IE:我将鼠标悬停在一个上,两个都突出显示,切换图例中的可见性将隐藏两个部分。 http://jsfiddle.net/rayholland/HSvBj/2/ ser
我在我的 C# WinForms 应用程序中使用 .net 4.0 的图表控件。我有两个系列的数据显示为折线图。 我绘制的基本上是作为时间函数的供求关系图。我希望需求是某种颜色的实线,供应是相同颜色的
如何在窗口调整大小期间避免线划线调整大小?考虑下图: http://leprastuff.ru/data/img/20130315/b83eea4a7a3f07ca53a0e118ddbb9230.G
我正在尝试使用纯 webgl 创建虚线。我知道这已经有一个问题,也许我很笨,但我不知道如何让它发挥作用。我理解这个概念,但我不知道如何在着色器中获取沿路径的距离。以前的答案有以下行: varying
我们应该在序列图中的哪些步骤中使用返回线? )没有返回箭头,因为它们隐式返回实例化对象 编辑 2 针对您更新的问题: 我不会有用户操作的返回箭头,例如 login(),因为结果不会以与对象相同的方式
我正在尝试使用 gnuplot v4.4 绘制一个包含虚线和连续线的图形。代码是: set term postscript eps enhanced color set style line 1 li
我正在尝试创建一个 React nivo 折线图,其中包含虚线而不是实线。我研究过图案,但不知道如何制作图案。感谢您的帮助。 最佳答案 nivo 在库中提供了自定义图层功能,您可以使用它来自定义从实线
我正在尝试创建一个 React nivo 折线图,其中包含虚线而不是实线。我研究过图案,但不知道如何制作图案。感谢您的帮助。 最佳答案 nivo 在库中提供了自定义图层功能,您可以使用它来自定义从实线
我使用一些通过的点创建虚线 UIBezierPath。 let pathLayer = CAShapeLayer() pathLayer.strokeColor = UIColor.blue.cgCo
我有以下问题。我必须从很多距离太近的点画一个圆。您可以在下面的 jsfiddle 链接中看到它: http://jsfiddle.net/L6e5oz3L/
我是 CSS 的新手,正在网上寻找自动重新压缩图像的代码,我发现的代码可以完美地做到这一点。但正确的是,它重新调整图像周围的一些红色虚线,当我尝试编辑时,整个图像消失了。可以请有人帮我解决图像显示时如
已将 Firebase Analytics 集成到我的 Android 项目中,它上个月运行正常,现在它只显示虚线并且用户数为 0。 不确定为什么会这样,我哪里错了?由于它之前工作正常,我相信我已经按
我正在使用 OpenGl ES 1.0 开发我的 Android 游戏,我想绘制虚线现在我使用这段代码来画我的线: gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f); // g
我正在尝试绘制 1 像素的虚线,但它总是绘制 2 像素的线。当前解决方案: let shapelayer = CAShapeLayer() let path = UIBezierPath() path
我这里有一个用 html 编码的菜单,但我需要一条虚线来跨越名称和价格,我将如何在这里做呢?我有点迷路了哈哈。 你可以在这里看到它。 http://mystycs.com/menu/menuifram
是否可以在 Chart.js 折线图上制作虚线?并使图表全宽?见附件样机。 这是我当前的代码(只是简单的例子): var ctx = document.getElementById("main
如何删除 JTabbedPane 上当前选定选项卡周围的虚线。 例如: 看到它周围的虚线了吗? 最佳答案 我刚刚找到了一个更好的方法: component.setFocusable(false); 关
我正在尝试使用 rgl 绘制一些 3d 形状,但我想使用虚线/虚线连接我的点。我怎样才能做到这一点?目前我有 require(rgl) p1 <- c(0,0,0) p2 <- c(1,0,0) p3
我是一名优秀的程序员,十分优秀!