Съвет за сътрудничество AngularJS със Socket.io

Автор: Peter Berry
Дата На Създаване: 14 Юли 2021
Дата На Актуализиране: 13 Може 2024
Anonim
Дмитрий Захаров - ANGULAR + NESTJS
Видео: Дмитрий Захаров - ANGULAR + NESTJS

Съдържание

  • Необходими знания: Междинен JavaScript
  • Изисква: Node.js, NPM
  • Време на проекта: 2 часа

AngularJS е особено подходящ за създаване на богати клиентски приложения в браузъра и когато добавите малко Socket.io в микса, нещата стават наистина интересни. В тази статия ще изградим борд за сътрудничество в реално време, който използва AngularJS за клиентското приложение и Socket.io за споделяне на състояние между всички свързани клиенти.

Нека да разгледаме малко домакинство, преди да започнем. Ще предположа, че имате основни познания за HTML и JavaScript, тъй като няма да обхващам всеки малък ъгъл на кода. Например няма да извиквам CSS и JavaScript файловете, които съм включил в главата на HTML файла, тъй като там няма нова информация.

Също така ви препоръчвам да вземете кода от моя акаунт в GitHub, за да го следвате. Моят добър приятел Брайън Форд също има отличен семенник Socket.io, на който базирах някои от оригиналните си идеи.

Четирите основни характеристики, които искаме в борда за сътрудничество, е възможността да създаваме бележка, да четем бележките, да актуализираме бележка, да изтриваме бележка и за забавление да преместваме бележка на дъската. Да, точно така, фокусираме се върху стандартните CRUD функции. Вярвам, че като се фокусираме върху тези основни характеристики, ще покрием достатъчно код, за да се появят модели, за да можете да ги вземете и да ги приложите другаде.


01. Сървърът

Първо ще започнем със сървъра Node.js, тъй като той ще служи като основа, върху която ще надграждаме всичко останало.

Ще изградим сървър Node.js с Express и Socket.io. Причината, поради която използваме Express, е, че той предоставя приятен механизъм за настройка на статичен сървър на активи в Node.js. Express се предлага с куп наистина страхотни функции, но в този случай ще го използваме, за да разделим приложението чисто между сървъра и клиента.

(Работя под предположението, че имате инсталирани Node.js и NPM. Бързо търсене с Google ще ви покаже как да ги инсталирате, ако не го направите.)

02. Голите кости

Така че, за да изградим голите кости на сървъра, трябва да направим няколко неща, за да стартираме и работим.

// app.js

// A.1
var express = require (’express’),
app = express ();
сървър = изисква (’http’). createServer (приложение),
io = require (’socket.io’). listen (сървър);

// A.2
app.configure (function () {
app.use (express.static (__ dirname + ’/ public’));
});

// A.3
server.listen (1337);


A.1 Декларираме и създаваме инстанции на нашите модули Node.js, за да можем да ги използваме в нашето приложение. Декларираме Express, създаваме екземпляр на Express и след това създаваме HTTP сървър и изпращаме в него екземпляр Express. И оттам създаваме инстанция на Socket.io и му казваме да държи под око на нашия сървър екземпляр.

A.2 След това казваме на нашето приложение Express да използва нашата публична директория за обслужване на файлове от.

A.3 Стартираме сървъра и му казваме да слуша на порт 1337.

Досега това беше доста безболезнено и бързо. Вярвам, че имаме по-малко от 10 реда в кода и вече имаме функционален сървър Node.js. Напред!

03. Декларирайте вашите зависимости

// пакети.json
{
"name": "ъглова дъска",
"description": "Съвет за сътрудничество AngularJS",
"версия": "0.0.1-1",
"private": вярно,
"зависимости": {
"express": "3.x",
"socket.io": "0.9.x"
}
}

Една от най-хубавите характеристики на NPM е възможността да декларирате вашите зависимости в пакети.json файл и след това автоматично да ги инсталирате чрез npm инсталиране в командния ред.


04. Свържете Socket.io

Вече дефинирахме основните функции, които искаме в приложението, и затова трябва да настроим слушатели на събития Socket.io и подходящо затваряне, за да се справим със събитието за всяка операция.

В кода по-долу ще забележите, че това е по същество конфигурация на слушатели на събития и обратно извикване. Първото събитие е Връзка събитие, което използваме за свързване на другите ни събития в затварянето.

io.sockets.on (’connection’, function (socket) {
socket.on (’createNote’, функция (данни) {
socket.broadcast.emit (’onNoteCreated’, данни);
});

socket.on (’updateNote’, функция (данни) {
socket.broadcast.emit (’onNoteUpdated’, данни);
});

socket.on (’deleteNote’, функция (данни) {
socket.broadcast.emit (’onNoteDeleted’, данни);
});

socket.on (’moveNote’, функция (данни) {
socket.broadcast.emit (’onNoteMoved’, данни);
});
});

От тук добавяме слушатели към createNote, updateNote, deleteNote и moveNote. А във функцията за обратно извикване просто излъчваме какво се е случило, за да може всеки клиент, който слуша, да бъде уведомен, че се е случило.

Има няколко неща, които си струва да се отбележат относно функциите за обратно извикване в отделните манипулатори на събития. Първо, ако искате да изпратите събитие на всички останали, освен на клиента, който е излъчил събитието, което сте вмъкнали излъчване преди излъчвам извикване на функция. На второ място, ние просто предаваме полезния товар на събитието на заинтересованите страни, за да могат те да го обработят, както сметнат за добре.

05. Стартирайте двигателите си!

След като дефинирахме зависимостите си и настроихме нашето приложение Node.js с правомощия Express и Socket.io, съвсем лесно е да инициализираме сървъра Node.js.

Първо инсталирате вашите зависимости Node.js така:

npm инсталиране

И тогава стартирате сървъра така:

възел app.js

И тогава! Отивате на този адрес във вашия браузър. Бам!

06. Няколко откровени мисли, преди да продължите напред

Аз съм предимно разработчик на интерфейс и първоначално бях малко уплашен от свързването на сървър Node.js към моето приложение. Частта AngularJS беше бърза, но JavaScript от страна на сървъра? Опашка зловещата музика от филм на ужасите.

Но аз бях абсолютно убеден, за да открия, че мога да настроя статичен уеб сървър само в няколко реда код и в още няколко реда използвам Socket.io за обработка на всички събития между браузърите. И все още беше само JavaScript! За навременност обхващаме само няколко функции, но се надявам, че в края на статията ще видите, че е лесно да се плува - и дълбокият край на басейна не е толкова страшен.

07. Клиентът

Сега, когато имаме стабилна основа с нашия сървър, нека преминем към любимата ми част - клиента! Ще използваме AngularJS, jQueryUI за плъзгащата се част и Twitter Bootstrap за основа за стил.

08. Голите кости

Що се отнася до личните предпочитания, когато стартирам ново приложение на AngularJS, обичам бързо да определям минималния минимум, за който знам, че ще трябва да започна, и след това да започна да преглеждам това възможно най-бързо.

Всяко приложение на AngularJS трябва да бъде заредено с поне един контролер и така обикновено това е мястото, от което винаги стартирам.

За да стартирате автоматично приложението, трябва просто да добавите ng-app към HTML възела, в който искате приложението да живее. През повечето време добавянето му към HTML тага ще бъде напълно приемливо. Добавих и атрибут към ng-app да му кажа, че искам да използвам ап модул, който ще дефинирам само след малко.

// public / index.html
html ng-app = "app">

Знам, че ще ми трябва поне един контролер и затова ще извикам това с помощта ng-контролер и му присвоява свойство на MainCtrl.

body ng-controller = "MainCtrl"> / body>

Така че сега сме готови за модул с име ап и контролер с име MainCtrl. Нека да продължим и да ги създадем сега.

Създаването на модул е ​​доста лесно. Вие го определяте чрез обаждане ъглова.модул и му дадете име. За бъдеща справка вторият параметър на празен масив е мястото, където можете да инжектирате подмодули за използване в приложението. Това е извън обхвата на този урок, но е удобно, когато вашето приложение започне да нараства в сложност и нужди.

// public / js / collab.js
var app = angular.module (’app’, []);

Ще обявим няколко празни заместители в ап модул, започващ с MainCtrl По-долу.Ще ги попълним по-късно, но аз исках да илюстрирам основната структура от самото начало.

app.controller (‘MainCtrl’, функция ($ scope) {});

Също така ще обгърнем функционалността Socket.io в гнездо услуга, за да можем да капсулираме този обект и да не го оставяме да се носи в глобалното пространство на имената.

app.factory (’сокет’, функция ($ rootScope) {});

И докато сме в това, ще обявим директива, наречена лепкава бележка които ще използваме за капсулиране на функционалността на лепкава бележка във.

app.directive (’stickyNote’, функция (сокет) {});

Така че нека да прегледаме това, което сме направили досега. Заредихме приложението с помощта на ng-app и декларирахме нашия контролер на приложения в HTML. Също така определихме модула за приложение и създадохме MainCtrl контролер, гнездо услуга и лепкава бележка директива.

09. Създаване на лепкава бележка

Сега, когато разполагаме със скелета на приложението AngularJS, ще започнем да изграждаме функцията за създаване.

app.controller (‘MainCtrl’, функция ($ scope, socket) {// B.1
$ scope.notes = []; // B.2

// Входящ
socket.on (’onNoteCreated’, функция (данни) {// B.3
$ scope.notes.push (данни);
});

// Изходящ
$ scope.createNote = function () {// B.4
var бележка = {
id: нова дата (). getTime (),
заглавие: „Нова бележка“,
body: „Изчаква се“
};

$ scope.notes.push (бележка);
socket.emit (’createNote’, бележка);
};

B.1 AngularJS има вградена функция за инжектиране на зависимост, така че инжектираме a $ обхват обект и гнездо обслужване. The $ обхват object служи като ViewModel и по същество е обект на JavaScript с включени в него някои събития, за да се даде възможност за двупосочно свързване на данни.

Б.2 Декларираме масива, в който ще използваме, за да обвържем изгледа.

Б.3 Добавяме слушател за onNoteCreated събитие на гнездо услуга и избутване на полезния товар на събитието в $ scope.notes масив.

Б.4 Обявихме a createNote метод, който създава по подразбиране Забележка обект и го избутва в $ scope.notes масив. Той също така използва гнездо услуга за излъчване на createNote събитие и предайте нова бележка обект заедно.

И така, след като имаме метод за създаване на бележката, как да го наречем? Това е добър въпрос! В HTML файла добавяме вградената директива AngularJS ng-щракване към бутона и след това добавете createNote извикване на метод като стойност на атрибута.

button id = "createButton" ng-click = "createNote ()"> Създаване на бележка / бутон>

Време е за бърз преглед на това, което сме направили до момента. Добавихме масив към $ обхват обект в MainCtrl това ще съдържа всички бележки за приложението. Добавихме и a createNote метод на $ обхват обект, за да създадете нова локална бележка и след това да я излъчите на останалите клиенти чрез гнездо обслужване. Добавихме и слушател на събития в гнездо услуга, за да можем да знаем кога други клиенти са създали бележка, за да можем да я добавим към нашата колекция.

10. Показване на лепкавите бележки

Вече имаме възможността да създадем обект за бележка и да го споделяме между браузърите, но как всъщност да го покажем? Тук влизат директивите.

Директивите и техните тънкости са обширна тема, но кратката версия е, че те предоставят начин за разширяване на елементи и атрибути с персонализирана функционалност. Директивите са лесно любимата ми част за AngularJS, защото ви позволява по същество да създадете цял DSL (Domain Specific Language) около вашето приложение в HTML.

Естествено е, че тъй като ще създаваме лепкави бележки за нашия съвет за сътрудничество, ние трябва да създадем лепкава бележка директива. Директивите се дефинират чрез извикване на директивния метод на модул, в който искате да го декларирате, и предаване на име и функция, които връщат обект на дефиниция на директива. Обектът за дефиниция на директива има много възможни свойства, които можете да дефинирате върху него, но тук ще използваме само няколко за нашите цели.

Препоръчвам ви да разгледате документацията на AngularJS, за да видите всички списъци със свойства, които можете да дефинирате в обекта за дефиниция на директива.

app.directive (’stickyNote’, функция (сокет) {
var linker = функция (обхват, елемент, attrs) {};

var контролер = функция ($ обхват) {};

връщане {
ограничи: „A“, // C.1
връзка: линкер, // C.2
контролер: контролер, // C.3
обхват: {// C.4
бележка: ’=’,
ondelete: ’&’
}
};
});

В.1 Можете да ограничите вашата директива до определен тип HTML елемент. Двете най-често срещани са елемент или атрибут, които декларирате, че използвате Е. и A съответно. Можете също да го ограничите до CSS клас или коментар, но те не са толкова често срещани.

В.2 Функцията за връзка е мястото, където поставяте целия си DOM код за манипулация. Има няколко изключения, които открих, но това винаги е вярно (поне 99 процента от времето). Това е основно основно правило на AngularJS и затова го подчертах.

В.3 Функцията контролер работи точно като основния контролер, който дефинирахме за приложението, но $ обхват обектът, който предаваме, е специфичен за елемента DOM, от който живее директивата.

C.4 AngularJS има концепция за изолиран обхват, която ви позволява изрично да дефинирате как обхватът на директивата комуникира с външния свят. Ако не бяхме декларирали обхвата, директивата би имплицитно наследила от обхвата родител с връзка родител-дете. В много случаи това не е оптимално. Като изолираме обхвата, ние смекчаваме шансовете външният свят да неволно и неблагоприятно да повлияе на състоянието на вашата директива.

Декларирах двупосочно обвързване на данни с Забележка с = символ и израз, обвързващ с ondelete с & символ. Моля, прочетете документацията на AngularJS за пълно обяснение на изолирания обхват, тъй като това е една от най-сложните теми в рамката.

Така че нека всъщност добавим лепкава бележка към DOM.

Както всяка добра рамка, AngularJS се предлага с някои наистина страхотни функции веднага. Една от най-удобните функции е ng-повторение. Тази директива AngularJS ви позволява да предавате масив от обекти и дублира какъвто и да е таг, толкова пъти, колкото има елементи в масива. В случая по-долу итерираме над бележки и дублиране на div елемент и неговите деца за дължината на бележки масив.

div sticky-note ng-repeat = "note in notes" note = "note" ondelete = "deleteNote (id)">
button type = "button" ng-click = "deleteNote (note.id)"> × / button>
input ng-model = "note.title" ng-change = "updateNote (note)" type = "text">
textarea ng-model = "note.body" ng-change = "updateNote (бележка)"
> {{note.body}} / textarea>
/ div>

Красотата на ng-повторение е, че е обвързан с какъвто и да е масив, който подадете и когато добавите елемент към масива, вашият DOM елемент ще се актуализира автоматично. Можете да направите това още една стъпка и да повторите не само стандартните DOM елементи, но и други потребителски директиви. Ето защо виждате лепкава бележка като атрибут на елемента.

Има два други бита персонализиран код, които трябва да бъдат изяснени. Изолирахме обхвата върху лепящи бележки директива за две свойства. Първият е дефинираният обвързващ изолиран обхват на Забележка Имот. Това означава, че когато обектът на бележката се промени в обхвата на родителя, той автоматично ще актуализира съответния обект на бележка в директивата и обратно. Другият дефиниран изолиран обхват е на ondelete атрибут. Това означава, че когато ondelete се извиква в директивата, тя ще извика какъвто и да е израз в ondelete атрибут на DOM елемента, който създава екземпляр на директивата.

Когато дадена директива е създадена, тя се добавя към DOM и се извиква функцията за връзка. Това е идеална възможност да зададете някои DOM свойства по подразбиране на елемента. Параметърът на елемента, който предаваме, всъщност е обект jQuery и така можем да изпълняваме jQuery операции върху него.

(AngularJS всъщност идва с вградена подгрупа от jQuery, но ако вече сте включили пълната версия на jQuery, AngularJS ще отложи това.)

app.directive (’stickyNote’, функция (сокет) {
var linker = функция (обхват, елемент, attrs) {
// Няколко DOM инициации, за да го направим хубаво
element.css (‘вляво’, ‘10px’);
element.css (‘top’, ’50px’);
element.hide (). fadeIn ();
};
});

В горния код ние просто позиционираме лепкавата бележка на сцената и я избледняваме.

11. Изтриване на лепкава бележка

Така че сега, когато можем да добавим и покажем лепкава бележка, е време да изтрием лепкавите бележки. Създаването и изтриването на лепкави бележки е въпрос на добавяне и изтриване на елементи от масива, към който са обвързани бележките. Това е отговорността на родителския обхват да поддържа този масив, поради което произвеждаме заявката за изтриване от директивата, но нека родителският обхват направи действителното вдигане на тежки тежести.

Ето защо преминахме през всички проблеми при създаването на дефиниран изолиран обхват на директивата: така директивата може да получи вътрешно събитие за изтриване и да го предаде на родителя си за обработка.

Забележете HTML в директивата.

button type = "button" ng-click = "deleteNote (note.id)"> × / button>

Следващото нещо, което ще кажа, може да изглежда като дълъг път, но не забравяйте, че сме на една и съща страна и ще има смисъл, след като доразвия. Когато се кликне бутонът в горния десен ъгъл на лепенката, ние се обаждаме deleteNote на контролера на директивата и предаване на бележка.id стойност. След това контролерът се обажда отмени, който след това изпълнява какъвто и да е израз, който сме свързали с него. Дотук добре? Извикваме локален метод на контролера, който след това го предава, като извиква какъвто и да е израз, дефиниран в изолирания обхват. Изразът, който се извиква на родителя, просто се извиква deleteNote както добре.

app.directive (’stickyNote’, функция (сокет) {
var контролер = функция ($ обхват) {
$ scope.deleteNote = функция (id) {
$ scope.ondelete ({
направих
});
};
};

връщане {
ограничи: „A“,
връзка: линкер,
контролер: контролер,
обхват: {
бележка: ’=’,
ondelete: ’&’
}
};
});

(Когато се използва дефиниран от израза изолиран обхват, параметрите се изпращат в обектна карта.)

В обхвата на родителя, deleteNote се извиква и прави доста стандартно изтриване с помощта на ъглова.за всеки полезна функция за итерация над масива от бележки. След като функцията се справи с местния си бизнес, тя продължава и излъчва събитието за останалия свят, за да реагира съответно.

app.controller (‘MainCtrl’, функция ($ scope, socket) {
$ scope.notes = [];

// Входящ
socket.on (’onNoteDeleted’, функция (данни) {
$ scope.deleteNote (data.id);
});

// Изходящ
$ scope.deleteNote = функция (id) {
var oldNotes = $ scope.notes,
newNotes = [];

angular.forEach (oldNotes, функция (бележка) {
if (note.id! == id) newNotes.push (бележка);
});

$ scope.notes = newNotes;
socket.emit (’deleteNote’, {id: id});
};
});

12. Актуализиране на лепкава бележка

Постигаме фантастичен напредък! Досега се надявам, че започвате да виждате някои модели, които се появяват от това вихрено турне, което предприемаме. Следващият елемент в списъка е функцията за актуализация.

Ще започнем от действителните елементи на DOM и ще го проследим чак до сървъра и обратно до клиента. Първо трябва да знаем кога се променя заглавието или тялото на лепенката. AngularJS третира елементите на формуляра като част от модела на данни, така че можете да свържете двупосочно свързване на данни в един момент. За целта използвайте ng-модел директива и поставете в свойството, към което искате да се свържете. В този случай ще използваме бележка.заглавие и note.body съответно.

Когато някое от тези свойства се промени, ние искаме да уловим тази информация, за да я предадем. Постигаме това с ng-промяна директива и я използвайте за извикване updateNote и предайте в самия обект на бележката. AngularJS прави много интелигентна мръсна проверка, за да открие дали стойността на каквото и да е ng-модел се промени и след това изпълнява израза, който е в ng-промяна.

input ng-model = "note.title" ng-change = "updateNote (note)" type = "text">
textarea ng-model = "note.body" ng-change = "updateNote (бележка)"> {{note.body}} / textarea>

Положителната страна на използването ng-промяна е, че локалната трансформация вече се е случила и ние просто сме отговорни за предаването на съобщението. В контролера, updateNote се извиква и оттам ще излъчваме updateNote събитие за нашия сървър за излъчване на останалите клиенти.

app.directive (’stickyNote’, функция (сокет) {
var контролер = функция ($ обхват) {
$ scope.updateNote = функция (бележка) {
socket.emit (’updateNote’, бележка);
};
};
});

И в контролера на директивите ние слушаме за onNoteUpdated събитие, за да знаем кога се актуализира бележка от друг клиент, за да можем да актуализираме локалната си версия.

var контролер = функция ($ обхват) {
// Входящ
socket.on (’onNoteUpdated’, функция (данни) {
// Актуализиране, ако същата бележка
ако (data.id == $ scope.note.id) {

$ scope.note.title = data.title;
$ scope.note.body = data.body;
}
});
};

13. Преместване на лепкава бележка

Към този момент направихме обиколка около детския басейн CRUD и животът е добър! Само заради трик за салон, за да впечатлите приятелите си, ще добавим възможността за преместване на бележки по екрана и актуализиране на координатите в реално време. Не се паникьосвайте - това са само още няколко реда код. Цялата тази упорита работа ще се изплати. Обещавам!

Поканихме специален гост, jQueryUI, на партито и направихме всичко за плъзгачите. Добавянето на възможността за плъзгане на бележка локално отнема само един ред код. Ако добавите element.draggable (); към вашата функция за свързване ще започнете да чувате ‘Eye of the Tiger’ от Survivor, защото вече можете да плъзнете бележките си наоколо.

Искаме да знаем кога плъзгането е спряло и да уловим новите координати, които да преминат. jQueryUI е създаден от някои много умни хора, така че когато плъзгането спира, просто трябва да дефинирате функция за обратно извикване за събитието стоп. Грабваме бележка.id изключете обекта на обхвата и лявата и горната CSS стойности от ui обект. С това знание правим това, което сме правили през цялото време: излъчвайте!

app.directive (’stickyNote’, функция (сокет) {
var linker = функция (обхват, елемент, attrs) {
element.draggable ({
стоп: функция (събитие, потребителски интерфейс) {
socket.emit (’moveNote’, {
id: scope.note.id,
x: ui.position.left,
y: ui.position.top
});
}
});

socket.on (’onNoteMoved’, функция (данни) {
// Актуализиране, ако същата бележка
if (data.id == scope.note.id) {
element.animate ({
вляво: data.x,
отгоре: data.y
});
}
});
};
});

На този етап не би трябвало да ни изненадва, че ние също слушаме събитие, свързано с преместване от услугата на сокета. В този случай това е onNoteMoved събитие и ако бележката е съвпадение, ние актуализираме левия и горния CSS свойства. Бам! Свършен!

14. Бонусът

Това е бонус раздел, който не бих включил, ако не бях абсолютно уверен, че можете да го постигнете за по-малко от 10 минути. Ще се разположим на сървър на живо (все още съм изумен колко лесно е да се направи).

Първо, трябва да отидете да се регистрирате за безплатна пробна версия на Nodejitsu. Пробният период е безплатен за 30 дни, което е идеално за намокряне на краката ви.

След като създадете акаунта си, трябва да инсталирате jitsu пакета, което можете да направите от командния ред чрез $ npm инсталиране на jitsu -g.

След това трябва да влезете от командния ред чрез $ jitsu вход и въведете вашите идентификационни данни.

Уверете се, че сте в приложението си директно, въведете $ jitsu разполагане и преминете през въпросите. Обикновено оставям колкото се може повече по подразбиране, което означава, че давам име на моето приложение, но не и поддомейн и т.н.

И, скъпи мои приятели, това е всичко! Ще получите URL адреса на вашето приложение от изхода на сървъра, след като е разположен и той е готов за работа.

15. Заключение

В тази статия разгледахме много основи на AngularJS и се надявам да сте се забавлявали много в процеса. Мисля, че наистина е добре какво можете да постигнете с AngularJS и Socket.io в приблизително 200 реда код.

Имаше няколко неща, които не разгледах, за да се съсредоточа върху основните точки, но ви препоръчвам да изтеглите източника и да си поиграете с приложението. Изградихме здрава основа, но все още има много функции, които можете да добавите. Вземете хакване!

Лукас Рюбелке е технологичен ентусиаст и е съавтор на AngularJS в действие за окомплектоване на публикации. Любимото му нещо е да накара хората да се вълнуват от новите технологии като него. Той управлява потребителската група за уеб приложения на Phoenix и е домакин на множество хакатони с колегите си в престъпление.

Хареса ли ви това? Прочетете тези!

  • Как да си направим приложение
  • Нашите любими уеб шрифтове - и те не струват и стотинка
  • Открийте какво следва за разширената реалност
  • Изтеглете безплатни текстури: висока разделителна способност и готов за използване сега
Ние Съветваме
Pixar’s Saschka Unseld за оживяване на чадъри
Допълнително

Pixar’s Saschka Unseld за оживяване на чадъри

Работейки като технически художник в Pixar от 2008 г., a chka Un eld се прослави миналата година, след като създаде The Blue Umbrella, късометражния филм на Pixar, който беше прожектиран с Mon ter Uni...
Как да се рекламирате като дизайнер
Допълнително

Как да се рекламирате като дизайнер

Повечето творци прекарват големи части от времето в мислене за други хора и техните мнения, нужди и желания. От клиенти и клиенти до хората, които следите в Twitter, има огромна и разнообразна аудитор...
Aardman разкрива тайните на трейлъра-убиец
Допълнително

Aardman разкрива тайните на трейлъра-убиец

Реших, че трейлърът на Hippy Dinner трябва да бъде заснет чрез техники за стоп движение от самото начало. Исках филмът да създаде усещане за фрагментирани спомени и носталгия, а заснемането на екшън н...