HTML 5 холст Javascript дождь анимации (как эффективно и легко реализовать!)

Я попробовал оба из них на холсте и ничего не показал, также я сомневаюсь, что это даже эффективно: /. Я пытаюсь сделать дождь, который идет по экрану .. Интересно, что является наиболее эффективным способом сделать это. Я новичок в анимации и буду очень признателен за помощь.

Я подозреваю, что создание объекта дождя было бы наилучшим, каждый с качеством спускается по экрану, затем идет к вершине, а затем с массивом с ними ... возможно со случайными значениями x с шириной холста и значениями y, равными 0, но я не знаю, как это реализовать. Пожалуйста помоги!

                xofRain = 20;
        startY = 0;
        ctx.beginPath();
        ctx.moveTo(xofRain, startY);
        ctx.lineTo(xofRain, startY + 20);
        ctx.closePath();
        ctx.fillStyle = "black"; 
        ctx.fill();


     function rain(xofRain){

        startY = canvas.height();

        ctx.moveTo(xofRain, startY);
        ctx.beginPath();
        ctx.lineTo(xofRain, startY + 3);
        ctx.closePath();
        ctx.fillStyle = "blue"; 
        ctx.fill();
    }
 Phrogz30 мая 2012 г., 05:38
Что должен этот «дождь» выглядит как? Просто синие полосы? (Не преломляющая вода, верно?)
 user142277030 мая 2012 г., 05:50
Да, точно! простые синие полосы

Ответы на вопрос(2)

Решение Вопроса

этот снежный дождь создан с использованием чистого HTML5 Canvas, метод, используемый для создания этой анимации, называется «Двойная анимация буфера». Во-первых, полезно знать, что такое техника анимации Double Buffer.

Техника двойного буфера: это продвинутая техника, позволяющая сделать анимацию более четкой и с меньшим количеством мерцаний. В этом методе используется 2 холста, один отображается на веб-странице для отображения результата, а второй - для создания анимационных экранов в процессе поддержки.

Как это поможет в полной мере, предположим, что мы должны создать анимацию с очень большим количеством перемещений, как в нашем примере с Snow Fall, есть количество хлопьев, движущихся с собственной скоростью, поэтому, чтобы они оставались движущимися, мы должны изменить положение каждая пластинка и обновление ее на холсте, это довольно тяжелый процесс для решения.

Так что теперь вместо того, чтобы обновлять каждую Flake непосредственно на холсте нашей страницы, мы создадим буферный холст, где будут происходить все эти изменения, и мы просто захватим холст Picture from Buffer через 30 мс и отобразим его на нашем реальном холсте.

Таким образом, наша анимация будет четкой и без мерцаний. Так вот живой пример этого.

http://aspspider.info/erishaan8/html5rain/

Вот код этого:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset=utf-8 />
    <title>HTML5 Rain</title>
    <!--[if IE]>
      <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <style>
      article, aside, figure, footer, header, hgroup, 
      menu, nav, section { display: block; }
    </style>
    <script type="text/javascript">
        var canvas = null;
        var context = null;
        var bufferCanvas = null;
        var bufferCanvasCtx = null;
        var flakeArray = [];
        var flakeTimer = null;
        var maxFlakes = 200; // Here you may set max flackes to be created 
    
        function init() {
            //Canvas on Page
            canvas = document.getElementById('canvasRain');
            context = canvas.getContext("2d");
            //Buffer Canvas
            bufferCanvas = document.createElement("canvas");
            bufferCanvasCtx = bufferCanvas.getContext("2d");
            bufferCanvasCtx.canvas.width = context.canvas.width;
            bufferCanvasCtx.canvas.height = context.canvas.height;
    
            
            flakeTimer = setInterval(addFlake, 200);
    
            Draw();
    
            setInterval(animate, 30);
             
        }
        function animate() {
            
            Update();
            Draw();
            
        }
        function addFlake() {
    
            flakeArray[flakeArray.length] = new Flake();
            if (flakeArray.length == maxFlakes)
                clearInterval(flakeTimer);
        }
        function blank() {
            bufferCanvasCtx.fillStyle = "rgba(0,0,0,0.8)";
            bufferCanvasCtx.fillRect(0, 0, bufferCanvasCtx.canvas.width, bufferCanvasCtx.canvas.height);
            
        }
        function Update() {
            for (var i = 0; i < flakeArray.length; i++) {
                if (flakeArray[i].y < context.canvas.height) {
                    flakeArray[i].y += flakeArray[i].speed;
                    if (flakeArray[i].y > context.canvas.height)
                        flakeArray[i].y = -5;
                    flakeArray[i].x += flakeArray[i].drift;
                    if (flakeArray[i].x > context.canvas.width)
                        flakeArray[i].x = 0;
                }
            }
            
        }
        function Flake() {
            this.x = Math.round(Math.random() * context.canvas.width);
            this.y = -10;
            this.drift = Math.random();
            this.speed = Math.round(Math.random() * 5) + 1;
            this.width = (Math.random() * 3) + 2;
            this.height = this.width;
        }
        function Draw() {
            context.save();
            
            blank();
    
            for (var i = 0; i < flakeArray.length; i++) {
                bufferCanvasCtx.fillStyle = "white";
                bufferCanvasCtx.fillRect(flakeArray[i].x, flakeArray[i].y, flakeArray[i].width, flakeArray[i].height);
            }
    
            
            context.drawImage(bufferCanvas, 0, 0, bufferCanvas.width, bufferCanvas.height);
            context.restore();
        }
      
    </script>
    </head>
    <body onload="init()">
      <canvas  id="canvasRain" width="800px" height="800px">Canvas Not Supported</canvas>
    </body>
    </html>

Также, если вы найдете эту справку полной, примите как Ответ и составьте ее. о_О

Ура !!!

что "наиболее эффективно" является. Если бы это был я, я бы сделал это в WebGL, но мне неясно, насколько это эффективно.

В любом случае я бы попытался использовать формулу без состояния. Создание и обновление состояния для каждой капли дождя возможно медленное.

const ctx = document.querySelector("canvas").getContext("2d");
const numRain = 200;

function render(time) {
  time *= 0.001;  // convert to seconds
  
  resizeCanvasToDisplaySize(ctx.canvas);
  
  const width = ctx.canvas.width;
  const height = ctx.canvas.height;
  ctx.fillStyle = "black";
  ctx.fillRect(0, 0, width, height);  
  
  resetPseudoRandom();
  
  const speed = time * 500;
  ctx.fillStyle = "#68F";
  for (let i = 0; i < numRain; ++i) {
    const x = pseudoRandomInt(width);
    const y = (pseudoRandomInt(height) + speed) % height;
    ctx.fillRect(x, y, 3, 8);
  }
  
  requestAnimationFrame(render);
}

requestAnimationFrame(render);

let randomSeed_ = 0;
const RANDOM_RANGE_ = Math.pow(2, 32);

function pseudoRandom() {
  return (randomSeed_ =
          (134775813 * randomSeed_ + 1) %
          RANDOM_RANGE_) / RANDOM_RANGE_;
};

function resetPseudoRandom() {
  randomSeed_ = 0;
};

function pseudoRandomInt(n) {
  return pseudoRandom() * n | 0;
}

function resizeCanvasToDisplaySize(canvas) {
  const width = canvas.clientWidth;
  const height = canvas.clientHeight;
  if (canvas.width !== width || canvas.height !== height) {
    canvas.width = width;
    canvas.height = height;
  }
}
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
<canvas></canvas>

Обратите внимание, что я мог бы использоватьctx.moveTo(x, y); ctx.lineTo(x, y + 8); для каждой строки, а затем в конце цикла называетсяctx.stroke(), Я этого не делал, потому что полагаю, что это будет менее эффективно, чем использованиеctx.fillRect, Чтобы холст рисовал линии, ему фактически необходимо выделить динамический путь (вы вызываетеctx.beginPath). Затем он должен записать все добавленные вами строки. Затем он должен расширить эти линии в вершины различных видов, чтобы растеризовать линии. Вы можете в принципеувидеть различные алгоритмы, которые он использует здесь, И наоборот, ничего из этого не должно случиться сctx.fillRect, Не должно быть никаких распределений (не говоря, что они не происходят, просто говоря, что они не должны). Канва может просто использовать один предварительно выделенный квад и нарисовать его на графическом процессоре, передав правильную матрицу, чтобы нарисовать любой прямоугольник, который вы у него попросите. Конечно, они могут вызывать больше накладных расходов.ctx.fillRect 200 раз, а неctx.moveTo, ctx.lineTo 200 с +ctx.stroke один раз, но на самом деле это зависит от браузера.

Дождь выше может быть или не быть достаточно хорошим эффектом дождя. Это не было моей целью в публикации. Дело в эффективности. Практически во всех играх, которые имеют какой-то эффект дождя, для своего дождя используется некая формула без сохранения состояния. Другая формула создаст другой или менее повторяющийся дождь. Дело в том, что это безгражданство.

Ваш ответ на вопрос