![](/img/trans.png)
[英]How can I make my HTML5 canvas arc less pixellated, or more anti-aliased?
[英]How can i make my HTML canvas dots move more naturally?
鏈接到我的代碼筆在這里
我想知道如何讓畫布點以更流暢,更液體的方式移動。
我已經嘗試限制一定數量的渲染(draw())的方向,這已經改善了一點! 但它仍然缺乏流動性,只是僵硬和“硬編碼”。
此switch語句是方向設置的方式,可以傳遞隨機整數或前一個方向。
switch (direction) {
case 1:
star.x--;
break;
case 2:
star.x++;
break;
case 3:
star.y--;
break;
case 4:
star.y++;
break;
case 5:
star.y--;
star.x--;
break;
case 6:
star.y--;
star.x++;
break;
case 7:
star.y++;
star.x++;
break;
case 8:
star.y++;
star.x--;
break;
}
謝謝!
你可以這樣做:
為什么選擇基數樣條? 基數樣條曲線將在一組點之間生成平滑線。 如果還有張力值。 通過誇大張力值(即在正常[0,1]范圍之外),它將產生卷曲的線條。
// draw example lines
var ctx = c.getContext("2d"), p = [0,100, 25,40, 50,70, 75,50, 100,80, 125,32, 150,100, 175,60];
ctx.font = "bold 16px sans-serif";
render(0); render(0.5); render(-2);
ctx.setTransform(1,0,0,1,0, 110);
render(-2, 3, "Segments: 3"); render(-2, 9, "Segments: 9"); render(-2, 25, "Segments: 25");
function render(t, seg, txt) {
ctx.beginPath();
ctx.moveTo(0, 100);
ctx.curve(p, t, seg || 20);
ctx.stroke();
ctx.fillText(txt ? txt : (!t ? "Plain poly-line" : "Cardinal, tension: " + t), 0, 20);
ctx.translate(200,0);
}
我們可以利用這個屬性並沿着這樣的線繪制一個點以產生液體運動。 可以通過降低/增加樣條中每條線之間的分段分辨率來改進運動,這將影響平滑度和速度。
其他優點是我們不必在動畫本身中計算任何東西(在設置點(緩存)時會有一個初始的“峰值”),我們只是更新數組指針並渲染。 並且分布將是相當均勻的,因為點是沿着稍微均勻分布(不可見)路徑的力。
如何實現它可以改變當然 - 這是一個方法的一個例子:
定義一個星形對象(它應該是原型,但為了演示):
function Star(ctx, xseg) {
var points = [], // holds points for cardinal points
cPos = 0, oPos = -1, // positions in line
len,
w = ctx.canvas.width,
x = -10, y = -10;
// this iterates and loop the point list
this.animate = function() {
cPos++;
if (cPos > len - 2) {
cPos = 0; oPos = -1;
}
var pos = cPos * 2;
x = points[pos];
y = points[pos + 1];
drawStar();
}
// render some star
function drawStar() {
ctx.rect(x, y, 2, 2);
}
// This generate a set of random points, then converts those into
// points for a cardinal spline (linked as script).
function generatePath() {
var w = ctx.canvas.width,
h = ctx.canvas.height,
numOfSeg = 20,
dh = h / numOfSeg,
i= 0, l, x, y;
for(; i<= numOfSeg; i++) {
x = xseg + w / 8 * Math.random();
y = h - (i * dh + ((dh / 2) * Math.random() - (dh / 4)));
points.push(x, y);
}
points = curve(points, -2, 200 * Math.random() + 100);
l = points.length;
// adjust for out of edges
for(i = 0; i < l; i += 2) if (points[i] > w) points[i] -= w;
len = points.length / 2;
cPos = parseInt(len * Math.random());
}
generatePath();
}
function Star(ctx, xseg) {
var points = [], // holds points for cardinal points
cPos = 0, oPos = -1, // positions in line
len,
w = ctx.canvas.width,
x = -10, y = -10;
this.animate = function() {
cPos++;
if (cPos > len - 2) {
cPos = 0; oPos = -1;
}
var pos = cPos * 2;
x = points[pos];
y = points[pos + 1];
drawStar();
};
function drawStar() {
ctx.moveTo(x + 2, y);
ctx.arc(x, y, 2, 0, Math.PI*2);
}
function generatePath() {
var w = ctx.canvas.width,
h = ctx.canvas.height,
numOfSeg = 20,
dh = h / numOfSeg,
i= 0, l, x, y;
for(; i <= numOfSeg; i++) {
x = xseg + w / 8 * Math.random();
y = h - (i * dh + ((dh / 2) * Math.random() - (dh / 4)));
points.push(x, y);
}
points = getCurvePoints(points, -2, (400 * Math.random() + 200)|0);
l = points.length;
for(i = 0; i < l; i += 2) if (points[i] > w) points[i] -= w;
len = points.length / 2;
cPos = (len * Math.random())|0;
}
generatePath();
}
// Main code
var canvas = document.querySelector("canvas"),
ctx = canvas.getContext("2d"),
stars = [],
numOfStars = 100,
segs = canvas.width / numOfStars,
i = 0,
throttle = 0,
delay = 2;
// create stars
for(; i < numOfStars; i++) stars.push(new Star(ctx, i * segs - segs));
ctx.fillStyle = "#fff";
ctx.shadowColor ="#fff";
ctx.shadowBlur = 7;
// ANIMATE
(function animate() {
if (!throttle) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
for(var i = 0; i < stars.length; i++) stars[i].animate();
ctx.fill();
}
throttle++;
if (throttle === delay) throttle = 0;
requestAnimationFrame(animate);
})();
請參閱此答案中的基數樣條實現的代碼。
另一種方法是使用粒子並使用例如正弦函數來變化速度。 為了使其最佳地工作,您可能需要使用速度網格來影響基於位置的粒子。 網格可以具有隨機方向和速度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.