Холст анимация с JavaScript. Случайные координаты и скорость при каждом запуске

1

Отредактировано: Спасибо всем за ценное время и силы. Наконец я сделал это)) JSfiddle

Я просто играл с холстом и делал это. Fiddle ссылка здесь.

... some code here ...

var cords = [];

for(var i = 50; i <= width; i += 100) {
  for(var j = 50; j <= height; j += 100) {
    cords.push({ cor: i+','+j});
  }
}

console.log(cords);

var offset = 15,
    speed = 0.01,
    angle = 0.01;

cords.forEach(function(e1) {
  e1.base = parseInt(Math.random()*25);
  e1.rgb = 'rgb('+parseInt(Math.random()*255)+','+parseInt(Math.random()*255)+','+parseInt(Math.random()*255)+')';
});

setInterval(function() {
  cords.forEach(function(e1) {
    e1.base = parseInt(Math.random()*25);
    e1.rgb = 'rgb('+parseInt(Math.random()*255)+','+parseInt(Math.random()*255)+','+parseInt(Math.random()*255)+')';
  });
},5000);

function render() {

  ctx.clearRect(0,0,width,height);

  cords.forEach(function(e1) {
    //console.log(e1);
    ctx.fillStyle = e1.rgb;
    ctx.beginPath();
    var r = e1.base + Math.abs(Math.sin(angle)) * offset;
    var v = e1.cor.split(',');
    ctx.arc(v[0],v[1],r,0,Math.PI * 2, false);
    ctx.fill();
  });
  angle += speed;
  requestAnimationFrame(render);
}

render();

Интересно,

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

Также приветствуется любое предложение по улучшению кода и его улучшению/быстрее/легче. Спасибо !

  • 2
    определить скорость и угол в окружностях объекта объекта jsfiddle.net/v9x1gpLq/5
  • 0
    @Kaiido Спасибо, но я хотел, чтобы шнуры были случайными при каждом запуске. Смотрите это
Показать ещё 1 комментарий
Теги:
canvas
animation

2 ответа

3

TL; DR - Посмотрите, как он работает здесь.

Создание координат случайным образом:

Это требует от вас добавить случайное смещение в координаты x и y. Поэтому я добавил случайное значение в координаты. Но тогда смещение меньше 1 не заметно. Поэтому вам нужно увеличить это случайное число множителем. То, что входит в randomizationFactor. Я установил его равным 100 поскольку это значение, с помощью которого вы меняете координаты на каждой итерации. Таким образом, это дает поистине случайный взгляд на анимацию.

Создание скорости Random:

Это заняло у меня некоторое время, чтобы понять, но идеальным способом является толкать значение скорости в массив координат. Это позволит вам гарантировать, что во время анимации скорость будет оставаться постоянной, и это даст вам более плавное ощущение. Но при повторном умножении радиуса r со значением от 0 до 1 значительно уменьшается скорость для некоторых кругов. Поэтому я добавил множитель к 3, чтобы немного компенсировать это.

В идеале я бы поставил 2, так как среднее значение Math.random() равно 0,5, поэтому множитель из 2 будет достаточным для компенсации этого. Но небольшое экспериментирование показало, что множитель 3 был намного лучше. Вы можете выбрать значение в соответствии с вашими предпочтениями.

Ваша логика генерации координат изменяется следующим образом:

for(var i = 50; i <= width;i += 100)  {
  for(var j = 51; j <= height;j += 100) {
    var x = i + (Math.random() - 0.5)*randomizationFactor;
    var y = j + (Math.random() - 0.5)*randomizationFactor;
    cords.push({ cor: x+','+y, speed: Math.random()});
  }
}

Ваша логика расширения кругов изменяется следующим образом:

function render() {

  ctx.clearRect(0,0,width,height);

  cords.forEach(function(e1) {
    //console.log(e1);
    ctx.fillStyle = e1.rgb;
    ctx.beginPath();
    var r = e1.base + Math.abs(Math.sin(angle)) * offset * e1.speed * 3;
    var v = e1.cor.split(',');
    ctx.arc(v[0],v[1],r,0,Math.PI * 2, false);
    ctx.fill();
  });
  angle += speed ;
  requestAnimationFrame(render);
}

Предложение: обновить координаты цветом

Я бы, вероятно, также обновил местоположение кругов каждые 5 секунд вместе с цветами. Это довольно просто сделать. Здесь я только что создал функцию resetCoordinates которая запускается каждые 5 секунд вместе с функцией setBaseRgb.

var cords = [];
function resetCoordinates() {
  cords = [];

  for(var i = 50; i <= width;i += 100)  {
    for(var j = 51; j <= height;j += 100) {
      var x = i + (Math.random() - 0.5)*randomizationFactor;
      var y = j + (Math.random() - 0.5)*randomizationFactor;
      cords.push({ cor: x+','+y, speed: Math.random()});
    }
  }
}
  • 0
    Огромное спасибо. Одна вещь, шары перекрывают друг друга. Как мы можем предотвратить это. Все остальное круто!
  • 0
    Один из способов сделать это состоит в том, чтобы сделать элемент randomizationFactor немного меньшим, а множитель скорости - меньшим (как я уже упоминал). Здесь я сохранил их 50 и 1,5 соответственно, а шары редко касаются друг друга. Другим способом достижения того же эффекта будет вычисление, касаются ли шары друг друга или нет, а затем изменяют свои координаты, чтобы избежать этого. Но это кажется мне слишком утомительным.
Показать ещё 1 комментарий
1

ОБНОВЛЕНИЕ Я сделал некоторые исправления в вашем коде, которые могут сделать вашу анимацию более динамичной. Полностью переписан образец. (извините за изменение имени переменной, теперь imo лучше)

Построенный в Math.random не очень случайный, и становится очевидным, когда вы встречаете анимацию. Попробуйте использовать этот случайный js lib.

var randEngine = Random.engines.mt19937().autoSeed();
var rand = function(from, to){
  return Random.integer(from, to)(randEngine)
}

Внутренние базовые свойства для каждого круга были бы лучше (более динамичными).

var circles = [];

// better to save coords as object neither as string
for(var i = 50; i <= width; i += 100)
  for(var j = 50; j <= height; j += 100)
   circles.push({ 
    coords: {x:i,y:j}
   });

Мы можем настроить анимацию с помощью нового свойства bouncing.

var offset = 15,
    speed = 0.005,
    angle = 0.01,
    bouncing = 25;

Вот как setBaseRgb функция setBaseRgb

function setBaseRgb(el){
  el.base = rand(-bouncing, bouncing);
  el.speed = rand(5, 10) * speed;
  el.angle = 0;
  el.rgb = 'rgb('+rand(0, 255)+','+rand(0, 255)+','+rand(0, 255)+')';
}

Все ваши анимации фиксировали тайм-аут setInterval. Лучше со случайным таймаутом.

cords.forEach(function(el){
  // random timeout for each circle
  setInterval(setBaseRgb.bind(null,el), rand(3000, 5000));
})

Вы забыли добавить свою базу в свое положение круга

function render() {    

  ctx.clearRect(0,0,width,height);

  circles.forEach(function(el) {
    ctx.fillStyle = el.rgb;
    ctx.beginPath();
    var r = bouncing + el.base + Math.abs(Math.sin(el.angle)) * offset;
    var coords = el.coords;
    ctx.arc(
       coords.x + el.base,
       coords.y + el.base,
       r, 0, Math.PI * 2, false
    );
    ctx.fill();
    el.angle += el.speed;
  });
  requestAnimationFrame(render);
}

render();

Эффект 1 JSFiddle

Добавление этого

if(el.angle > 1)
  el.angle=0;

Эффект публикации результатов

Эффект 2 JSFiddle

Воспроизведение с помощью формул приводит к

Эффект 3 JSFiddle

  • 0
    Мне понравилась мысль о нарушении процесса обновления всех шаров сразу! Это выглядит довольно интересно.
  • 0
    Да, это интересно! Совершенно другой взгляд. Спасибо! Но шнуры одинаковы. Мне нравятся они изменились. Не та же строка и столбец снова и снова. ;)
Показать ещё 9 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню