Javascript 虚线笔划在<;帆布>;
我想这是不可能设置笔划属性,如CSS,这是很容易的。在CSS中,我们有虚线、虚线、实线,但在画布上绘制线条或笔划时,这似乎不是一个选项。你是如何实现这一点的 我看过一些例子,但对于这样一个愚蠢的函数,它们实在太长了 例如:Javascript 虚线笔划在<;帆布>;,javascript,html,canvas,Javascript,Html,Canvas,我想这是不可能设置笔划属性,如CSS,这是很容易的。在CSS中,我们有虚线、虚线、实线,但在画布上绘制线条或笔划时,这似乎不是一个选项。你是如何实现这一点的 我看过一些例子,但对于这样一个愚蠢的函数,它们实在太长了 例如: myContext.lineCap = 'round'; myContext.lineWidth = 4; // Lines 4px wide, dots of diameter 4 myContext.dashedLine(20,150,170,10,[30,10,0,
myContext.lineCap = 'round';
myContext.lineWidth = 4; // Lines 4px wide, dots of diameter 4
myContext.dashedLine(20,150,170,10,[30,10,0,10]);
目前HTML5画布规范中不支持虚线 看看这个: 或 查看Raphael JS库:
有趣的问题!我已经编写了一个虚线的自定义实现;你可以。我采用了Adobe Illustrator的方法,允许您指定一组破折号/间隙长度 对于stackoverflow的后代,以下是我的实现(s/o线宽略有改变): 要交替绘制虚线和圆点,请使用(例如): “极短”划线长度
0
与圆角线头相结合,将沿直线形成点
如果有人知道访问画布上下文路径的当前点的方法,我很想知道,因为它允许我以
ctx.dashTo(x,y,破折号)的形式编写
而不是要求您在方法调用中重新指定起点。这个简化版的Phrogz代码利用了Canvas的内置转换功能,还处理特殊情况,例如当dx=0时
var CP = window.CanvasRenderingContext2D && CanvasRenderingContext2D.prototype;
if (CP.lineTo) {
CP.dashedLine = function(x, y, x2, y2, da) {
if (!da) da = [10,5];
this.save();
var dx = (x2-x), dy = (y2-y);
var len = Math.sqrt(dx*dx + dy*dy);
var rot = Math.atan2(dy, dx);
this.translate(x, y);
this.moveTo(0, 0);
this.rotate(rot);
var dc = da.length;
var di = 0, draw = true;
x = 0;
while (len > x) {
x += da[di++ % dc];
if (x > len) x = len;
draw ? this.lineTo(x, 0): this.moveTo(x, 0);
draw = !draw;
}
this.restore();
}
}
我认为我的计算是正确的,它看起来还不错。Mozilla一直在开发一个for画布,因此我们可能会在不久的将来看到它被添加到规范中。我在Mozilla规范中找到了属性
mozDash
和mozDashOffset
:
它们可能是用来控制破折号的,但我没有用过。Phroz的解决方案很棒。但当我在应用程序中使用它时,我发现了两个bug 以下代码是Phroz版本的调试(并为可读性而重构)
//修复:减去xStep错误(当x2Math.abs(dy));
变量斜率=(xSlope)?dy/dx:dx/dy;
这个。移动到(x,y);
var Distrimining=Math.sqrt(dx*dx+dy*dy);
var指数=0;
而(分发>=0.1){
var dashLength=Math.min(分发,dashArray[dashIndex%dashCount]);
var step=Math.sqrt(dashLength*dashLength/(1+slope*slope));
if(xSlope){
如果(dx<0)步长=-步长;
x+=阶跃
y+=斜率*阶跃;
}否则{
如果(dy<0)步长=-步长;
x+=斜率*阶跃;
y+=阶跃;
}
此[(dashIndex%2==0)-“lineTo”:“moveTo”](x,y);
分布-=长度;
dashIndex++;
}
}
有一种更简单的方法。根据strokeStyle接受字符串、画布渐变或画布图案。我们只拍一张这样的照片:
<img src="images/dashedLineProto.jpg" id="cvpattern1" width="32" height="32" />
这并不会产生一条完美的虚线,但它非常简单且可修改。当然,当你画的不是水平线或垂直线时,结果可能会变得不完美,虚线模式可能会有所帮助
请记住,当您试图在代码中使用来自外部源的IMG时,SOP适用。中有对它的支持 似乎
ctx.webkitLineDash
以前工作过,但他们删除了它,因为它有一些
say
ctx.setLineDash([5,10])代码>但它似乎还没有在任何地方实现。目前至少setLineDash([5,10])与Chrome和ctx兼容。mozDash=[5,10]与FF兼容:
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
if ( ctx.setLineDash !== undefined ) ctx.setLineDash([5,10]);
if ( ctx.mozDash !== undefined ) ctx.mozDash = [5,10];
ctx.beginPath();
ctx.lineWidth="2";
ctx.strokeStyle="green";
ctx.moveTo(0,75);
ctx.lineTo(250,75);
ctx.stroke();
设置为null将使直线变为实线。我修改了虚线
函数以添加对偏移的支持。如果浏览器支持ctx.setLineDash
和ctx.lineDashOffset
,它将使用本机虚线
例如:
var CP=window.canvasrendingcontext2d&&canvasrendingcontext2d.prototype;
如果(CP.lineTo){
CP.dashedLine=CP.dashedLine | |函数(x,y,x2,y2,da,偏移){
如果(!da)da=[10,5];
如果(!offset)offset=0;
if(CP.setLineDash&&typeof(CP.lineDashOffset)=“number”){
这是save();
这是setLineDash(da);
this.lineDashOffset=偏移量;
这个。移动到(x,y);
这个.lineTo(x2,y2);
这个.restore();
返回;
}
这是save();
变量dx=(x2-x),
dy=(y2-y);
var len=Math.sqrt(dx*dx+dy*dy);
var rot=数学常数2(dy,dx);
这个。翻译(x,y);
这个。移动到(0,0);
这个。旋转(腐烂);
var dc=da.长度;
var di=0;
var模式长度=0;
对于(变量i=0;i=startPos){
如果(偏移量>=startPos+da[startSegment%dc]){
startPos+=da[startSegment%dc];
startSegment++;
}否则{
offset=Math.abs(offset-startPos);
打破
}
如果(起始段>100)中断;
}
draw=startSegment%2==0;
x=0;
di=起始段;
while(len>x){
var间隔=da[di++%dc];
if(x<偏移量){
<img src="images/dashedLineProto.jpg" id="cvpattern1" width="32" height="32" />
var img=document.getElementById("cvpattern1");
var pat=ctx.createPattern(img,"repeat");
ctx.strokeStyle = pat;
ctx.strokeRect(20,20,150,100);
ctx.mozDash = [5,10];
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
if ( ctx.setLineDash !== undefined ) ctx.setLineDash([5,10]);
if ( ctx.mozDash !== undefined ) ctx.mozDash = [5,10];
ctx.beginPath();
ctx.lineWidth="2";
ctx.strokeStyle="green";
ctx.moveTo(0,75);
ctx.lineTo(250,75);
ctx.stroke();
var CP = window.CanvasRenderingContext2D && CanvasRenderingContext2D.prototype;
if (CP.lineTo) {
CP.dashedLine = CP.dashedLine || function (x, y, x2, y2, da, offset) {
if (!da) da = [10, 5];
if (!offset) offset = 0;
if (CP.setLineDash && typeof (CP.lineDashOffset) == "number") {
this.save();
this.setLineDash(da);
this.lineDashOffset = offset;
this.moveTo(x, y);
this.lineTo(x2, y2);
this.restore();
return;
}
this.save();
var dx = (x2 - x),
dy = (y2 - y);
var len = Math.sqrt(dx * dx + dy * dy);
var rot = Math.atan2(dy, dx);
this.translate(x, y);
this.moveTo(0, 0);
this.rotate(rot);
var dc = da.length;
var di = 0;
var patternLength = 0;
for (var i = 0; i < dc; i++) {
patternLength += da[i];
}
if (dc % 2 == 1) {
patternLength *= 2;
}
offset = offset % patternLength;
if (offset < 0) {
offset += patternLength;
}
var startPos = 0;
var startSegment = 0;
while (offset >= startPos) {
if (offset >= startPos + da[startSegment % dc]) {
startPos += da[startSegment % dc];
startSegment++;
} else {
offset = Math.abs(offset - startPos);
break;
}
if (startSegment > 100) break;
}
draw = startSegment % 2 === 0;
x = 0;
di = startSegment;
while (len > x) {
var interval = da[di++ % dc];
if (x < offset) {
interval = Math.max(interval - offset, 1);
offset = 0;
}
x += interval;
if (x > len) x = len;
draw ? this.lineTo(x, 0) : this.moveTo(x, 0);
draw = !draw;
}
this.restore();
};
}