使用 Canvas 平滑随机线
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
context.canvas.width = window.innerWidth;
context.canvas.height = window.innerHeight;
var x1 = Math.random()*context.canvas.width;
var y1 = Math.random()*context.canvas.height;
var xdir = 0; var ydir = 0;
context.beginPath();
setInterval(function(){
for (var i = 0; i < 10; i++) {
randx = Math.random(); randy = Math.random();
if (randx > 0.95) {
if (xdir < 0) xdir = (xdir+((Math.random()*1.5) - 1))/2;
else if (xdir > 0) xdir = (xdir+((Math.random()*1.5) - 0.5))/2;
else xdir = (Math.random()*1.5) - 0.75;
}
if (randy > 0.95) {
if (ydir < 0) ydir = (ydir+((Math.random()*1.5) - 1))/2;
else if (ydir > 0) ydir = (ydir+((Math.random()*1.5) - 0.5))/2;
else ydir = (Math.random()*1.5) - 0.75;
}
context.lineTo(x1+xdir, y1+ydir);
context.stroke();
x1 = x1+xdir;
y1 = y1+ydir;
}
},50);
这是我的随机行脚本,但我的行真的很难看: https://i.sstatic.net/YZT2o .png
有没有更好的方法使用canvas实现平滑的线条?
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
context.canvas.width = window.innerWidth;
context.canvas.height = window.innerHeight;
var x1 = Math.random()*context.canvas.width;
var y1 = Math.random()*context.canvas.height;
var xdir = 0; var ydir = 0;
context.beginPath();
setInterval(function(){
for (var i = 0; i < 10; i++) {
randx = Math.random(); randy = Math.random();
if (randx > 0.95) {
if (xdir < 0) xdir = (xdir+((Math.random()*1.5) - 1))/2;
else if (xdir > 0) xdir = (xdir+((Math.random()*1.5) - 0.5))/2;
else xdir = (Math.random()*1.5) - 0.75;
}
if (randy > 0.95) {
if (ydir < 0) ydir = (ydir+((Math.random()*1.5) - 1))/2;
else if (ydir > 0) ydir = (ydir+((Math.random()*1.5) - 0.5))/2;
else ydir = (Math.random()*1.5) - 0.75;
}
context.lineTo(x1+xdir, y1+ydir);
context.stroke();
x1 = x1+xdir;
y1 = y1+ydir;
}
},50);
This is my random line script, but my lines are really ugly: https://i.sstatic.net/YZT2o.png
Is there any better way for achieving a smooth line using canvas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看看这个问题:
画好看(就像在 Flash 中一样)画布上的线条 (HTML5) - 可能吗?
take a look at this question:
Drawing GOOD LOOKING (like in Flash) lines on canvas (HTML5) - possible?
HTML5 Canvas 上的线条在所有浏览器/操作系统上都可以很好地抗锯齿(据我所知)。但是,在每循环 10 笔画的更新回调中,您既不是 清除画布 或 清除您的路径,因此您每秒在其自身之上绘制相同的路径 200 次。这会导致所有抗锯齿功能被破坏,因为即使是最微弱的不透明像素也会逐渐累积,直到变成实线。
使代码看起来更漂亮的最简单的修复方法是添加以下行:
在
for
循环内,例如在context.lines();
。这一行更改使其看起来不错,但对性能不利,每次视觉更新都会清除并重绘画布 10 次。
这是一个更好的选择:
这样您就永远不会清除画布,而是每帧只绘制更改的线。
另一种替代方案(如果您需要始终可用的完整路径)是在一个高速
setInterval
循环中累积对上下文路径的更改,并在另一个较慢的循环中偶尔清除画布并重新抚摸整个路径。这与我在 Langton's (Very Fast) Ant 模拟中所做的类似。Lines on HTML5 Canvas are nicely antialiased on all browsers/OS (AFAIK). However, in your update callback with its 10-strokes-per-loop you are neither clearing your canvas nor clearing your path and so you are drawing the same path on top of itself 200 times per second. This is causing all the anti-aliasing to be destroyed as even the faintest opacity pixels build up until they are solid lines.
The simplest fix to make your code look pretty is to add this line:
inside your
for
loop, for example right beforecontext.stroke();
.This one-line change makes it look good, but is bad for performance, clearing and redrawing the canvas 10 times for each visual update.
Here's a better alternative:
This way you never clear the canvas, and instead draw only the changed line each frame.
One other alternative (if you need the full path always available) is to accumulate your changes to the context path in one high-speed
setInterval
loop, and in another, slower loop occasionally clear the canvas and re-stroke the entire path. This is similar to what I've done for my Langton's (Very Fast) Ant simulation.