Creative Coding — Как создать VJ-движок на JavaScript

1656615738 creative coding kak sozdat vj dvizhok na javascript

автор Джордж Галли

Узнайте, как динамически вводить JavaScript на веб-страницы

В течение многих лет я использовал браузер для своих выступлений и инсталляций, используя свой простой доморощенный VJ-движок. А теперь, после того, как вы научитесь нескольким простым приемам, вы тоже можете…

Быстрое поступление

Во-первых, что такое двигатель VJ? вы можете спросить. И, может быть, даже: что такое VJ? Вот основное определение характеристик VJing:

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

И VJ двигатель – это просто программное обеспечение, которое используется для VJing.

Но зачем мне строить свой собственный, когда есть так много VJ двигателей?

Я никогда не любил программное обеспечение для VJ – они всегда чувствовали себя раздутыми, и все вещи выглядели одинаково. Это похоже, когда вы впервые получили в руки Photoshop, и просто смешали кучу вещей вместе, добавили несколько фильтров, и это было круто (потому что это были 90-е). Но больше всего я хотел более тесной и лучшей интеграции между разработкой контента и входными звуковыми частотами.

В наши дни я редко пользуюсь VJ, но он все еще стимулирует большинство моих инсталляций и выступлений – везде, где мне нужно несколько визуализаций, которые я использую RBVJ ( РБ для Радорбой — это я) как обертка/проигрыватель.

RBVJ В течение многих лет я перешел от Flash к обработке и, наконец, к JavaScript, используя ту же простую систему.

Раньше я открывал его и свой контент (до дней Git и не зная, что существует вещь, которая называется открытым кодом). Он получил кучу наград, и я видел, как мой контент использовали во многих местах, что было приятно. Поэтому я подумал, что пора снова сделать его доступным для других вместе с кучей содержимого, чтобы показать, как я отношусь к творческой кодировке.

zXTWFCVzeLIVWd0XKR5aH03BI647fO5gKJwb
от radarboy3000 в Instagram

Ладно, это довольно долгое поступление. Покажи мне деньги, ты говоришь!

1. Структурирование содержания

По сути, движок VJ – это просто модный браузер и плеер. Итак, нам действительно нужен способ получить и воспроизвести наше содержимое.

Вы можете просто сбросить все свое содержимое в папку, но эта система лучше сработала для меня, обеспечивая простую структуру для управления клавиатурой:

  • Чтобы изменить наборы, нажмите Shift 0–9
  • Клавиши 0–9 для смены банков
  • Клавиши az для выбора содержимого внутри банка.

Это дает вам 2700 файлов для работы. Если вы действительно (действительно!?) хотели больше, вы также можете удвоить это, получив доступ к еще 26 файлам в банке со смещением AZ).

Как и большинство проектов HTML, я имею простую структуру верхнего уровня и сохраняю содержимое VJ в пронумерованной структуре внутри ст папка, например:

index.html/css/js/art <- content goes here

Моя папка содержимого (/art) содержит 10 пронумерованных папок, которые я называю наборы. Внутри каждого набора есть еще 10 пронумерованных папок банки. И внутри каждого банка имеется 27 отдельных пронумерованных файлов содержимого, например:

9SfMeEsL-OHXdShxWbJ3ZlihlxiYXlNw0Oqx
Внутри /art имеется 10 наборов папок. Каждый набор содержит 10 банков, внутри каждого банка есть 27 JavaScript. Доступ к банкам и наборам осуществляется с помощью цифровых клавиш, а содержимое – с помощью клавиш az

2. Получение и воспроизведение содержимого

Теперь нам просто нужен способ получить доступ к нашим файлам, который осуществляется путем ввода содержимого на страницу индекса.

И сделать это достаточно просто.

Магия происходит в функции под названием I’ve loadJS(). Он создает тег сценария в заголовке страницы, а затем вводит в него некоторый JavaScript (который будет нашим содержимым). Мы запускаем эту функцию с помощью нажатия клавиши (но это также может быть сигнал midi или OSC) и передаем имя файла нужного нам содержимого. Тогда сценарий доступен на странице.

// INJECT JS ONTO PAGE
var my_script;
function loadJS(filename) {
 // delete injected JavaScript if there’s been some loaded in before if (my_script != undefined)   document.getElementsByTagName("head")[0].removeChild(my_script); 
 // create a script element my_script = document.createElement(’script’); my_script.setAttribute("type", "text/javascript");
 // Load the file in and insert it into the page’s head tag my_script.setAttribute("src", filename); document.getElementsByTagName("head")[0].appendChild(my_script);
}

Мы прослушиваем нажатие клавиш с помощью прослушивателя событий, вызывающего вызванную функцию onKeyDown(), вот так:

window.addEventListener( ’keydown’, function( event ) {   onKeyDown( event ); });

Слушатель передает объект события функции, содержащей кучу полезных вещей. Вот что нас интересует: event.keycode. Нажатие клавиши a дает нам a код ключа из 65, а нажатие на нас ‘z’ дает нам a код ключа 90. Итак, мы просто вычитаем 65 из код ключа чтобы дать нам необходимый номер файла и передать это значение в a changeFile() функцию, которую я покажу чуть позже.

Аналогично мы хотим, чтобы ключи 0–9 (коды клавиш от 48 до 57, поэтому вычтите 48), чтобы изменить банки. Мы также хотим проверить, была ли нажата клавиша shift для загрузки наборов. Объект происшествия имеет удобный event.shiftKey переменная для этого, поэтому наша onKeyDown функция будет выглядеть так:

// KeyPress Stuff
function onKeyDown( event ) {
    var keyCode = event.keyCode;
   // CHANGE FILE // keys a-z   if ( keyCode >= 65 && keyCode <= 90 ) {      changeFile(keyCode - 65);
   // CHANGE SET AND BANK // keys 0-9   } else if ( keyCode >= 48 && keyCode <= 57 ) {
      // Test whether the shift key is also being pressed      if( event.shiftKey ) {       changeBank( keyCode-48 );      } else {       changeSet( keyCode-48 );      }
   }
}

The changeFile() функция в основном просто принимает нажатие клавиши и преобразует ее в URL. Это называет наш loadJS() функция для ввода содержимого на страницу, и бум, мы плохие…

IzvgpLah3pAqNZ0KLPWx0rHgsqBWGLf916TP
от radarboy3000 в Instagram

Да наш changeFile() функция будет выглядеть так:

var current_file = 0;var current_set = 0;var current_bank = 0;
var art_location = "art/";
// FILE LOADER FUNCTIONS
function changeFile(file) {
  current_file = file;  var loc = current_set + '/' + current_bank + '/' + current_file;  var filename = contentLocation + loc + '.js';  loadJS(filename);  document.location.hash = loc; //console.log("File: " + loc);
}

У меня тоже есть art_location переменная, если я хочу иметь разные коллекции визуальных элементов (поэтому я могу иметь разные папки для различных шоу и инсталляций). Я также добавляю имя файла как хэш ( к URL-адресу браузера, чтобы было легко увидеть, где я нахожусь).

Наши changeBank() и changeSet() функции устанавливают текущий_банк и текущий_набор переменные. Тогда они просто звонят changeFile() функция, чтобы получить правильный файл.

Для ведения хозяйства я также сбросил все счетчики – настройку текущий_файл вернуться к 0, когда я изменю банк, и текущий_банк вернуться к 0, когда я изменю наборы. Это я знаю, когда меняюсь банки, воспроизводимый файл будет первым файлом в банке. Так же, когда я меняюсь наборы, воспроизводимый файл будет сброшен, чтобы быть первым файлом из первого банка текущего набора (current_set/0/0.js).

Немного ласково, но функции действительно очень просты:

function changeSet(set) {
  current_set = set;  console.log("changeSet: " + current_set);
  // reset bank number  changeBank(0);
}
function changeBank(bank) {
current_bank = bank;  console.log("changeBank: " + current_bank);
  // reset file number and load new file  changeFile(0);
}

Итак, полный код вашего базового двигателя VJ выглядит так:

// FILE LOADER FUNCTIONS
var art_location = "/art";
var fileref;var current_file = 0;var current_set = 0;var current_bank = 0;
function changeFile( file ) {  reset()  current_file = file;  var loc = current_set + '/' + current_bank + '/' + current_file;  var filename="art/" + loc + '.js';  loadJS( filename );  document.location.hash = loc;  //console.log("File: " + loc);}
function changeSet( set ) {  current_set = set;  current_bank = 0;  console.log( "changeSet: " + current_bank );  // reset  changeFile( 0 );}
function changeBank( bank ) {  current_bank = bank;  console.log( "changeBank: " + current_bank );  changeFile( 0 );}
function reset(){  ctx.clearRect( 0, 0, w, h );  ctx2.clearRect( 0, 0, w, h );  ctx3.clearRect( 0, 0, w, h );  ctx.lineCap = "butt";}
// INJECT JS ONTO PAGE
function loadJS( filename ) {
if ( fileref != undefined ) document.getElementsByTagName( "head" )[ 0 ].removeChild( fileref );  fileref = document.createElement( 'script' );  fileref.setAttribute( "type", "text/javascript" );  fileref.setAttribute( "src", filename );  document.getElementsByTagName( "head" )[ 0 ].appendChild( fileref );
}
XnCcboR0KFixjweg9JBvoGifwsfXUZqyMcyT
от radarboy3000 в Instagram

Все, что осталось показать вам, это то, как я структурирую фактические файлы содержимого, которые используют инкапсулированную функцию, например:

// RBVJ art
rbvj = function() {
  draw = function() {     // do some creative coding here  }
}();

Функция rbvj() это то, что вводится на страницу. Он используется повторно, так как всякий раз, когда на мою страницу вставляется новый файл, память очищается от всего предыдущего содержимого.

С помощью инкапсуляции кода (см. ‘()’ после функции), любой код внутри rbvj() Функция запускается автоматически, когда файл будет вставлен на страницу.

Вы заметите, что внутри содержимого у меня есть a рисуем() функция (это от моего собственного creative_coding.js вспомогательный скрипт). Это просто простой цикл, использующий JavaScript requestAnimationFrame() и может изменять частоту кадров.

var frame_number = 0;var frame_rate = 60;var last_update = Date.now();
function loop() {
var now = Date.now();  var elapsed_mils = now - last_update;
if ((typeof window.draw == 'function') && (elapsed_mils >= (1000 / window.frame_rate))) {    window.draw();    frame_number++;    last_update = now - elapsed_mils % (1000 / window.frame_rate);  }  requestAnimationFrame(loop);
};

И почти все. Теперь у вас есть рабочий двигатель VJ в боузере.

3. Некоторые другие вещи, которые могут быть полезны

Обычно я просто подключаю звуковой вход компьютера непосредственно к входу от микшера или усилителя места проведения (я использую версию своего стандартного микрофонного входа mic.js файл, о котором вы можете прочитать больше здесь. И у меня есть настройки ключей (в моем случае, файл плюс и минус клавиши), чтобы настроить входящие уровни вверх или вниз, поэтому мне не нужно продолжать доступ к микшеру.

Также обратите внимание, что для ввода звука вам понадобится безопасное соединение HTTPS — или если вы используете что-то вроде Atom’s Live Server, то это встроено.

У меня также есть множество других клавиш, настроенных для простых аудио- и визуальных фильтров (смотрите, как создать фильтр пикселизации здесь).

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

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

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

Счастливый код. И спасибо за прочтение!

Как обычно полный код доступен на Github.

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

Вы можете просмотреть все мои предыдущие учебники по креативному кодированию здесь.

И следите за мной здесь, чтобы получать обновления, техники и конфеты для глаз:

@radarboy3000 * Фото и видео в Instagram
3960 подписчиков, 843 подписок, 1082 публикации — смотрите фотографии и видео Instagram от @radarboy3000www.instagram.comДжордж Галли (@radarboy_japan) | Twitter
Последние твиты от Джорджа Галли (@radarboy_japan). Медиахудожник, технолог, мастер, мечтатель. Реакция на…twitter.comРадорбой
Родорбой. 130 лайков · 7 говорят об этом. Искусство, визуализация дизайна, хакиwww.facebook.com

Добавить комментарий

Ваш адрес email не будет опубликован.