Flex и RIA блоги



2014-08-12

16:44:12, Flash-ripper.com
WebRTC — Hello, World!

WebRTC — это технология передачи потоковых данных в реальном времени между браузерами или другими приложениями по типу peer-to-peer. В начале 2013 года состоялся первый видеозвонок между Chrome и Firefox.

Разработчики могут создавать приложения на WebRTC для реализации голосовой и видеосвязи, например, видео-чата. На GitHub есть пример Hello World.html для WebRTC.

Недавно появился WebRTC Media Server, он может потеснить Adobe FMS и Wowza которые продолжают удерживать позиции за счет того, что пока только во Flash реализован кодек H.264. В WebRTC его почему-то не внедрили до сих пор (Google никак не договорится с Mozilla, что лучше — H.264 или кодек VP8).

С высокой вероятностью станет веб-стандартом. Его поддерживают все, кроме Майкрософт (ох, доиграются они). 

Схема работы WebRTC

WebRTC Data Pathways

 

С чего начать знакомство с WebRTC?

 

HTML5 наступает :)

 

 


16:35:33, Flash-ripper.com
Две августовские встречи в Харькове

1. X Games Dev - 16 августа, суббота

Украинская независимая конференция разработчиков игр.

  • Анонс: страница ВКонтакте
  • Место: Харьков, ул. Новгородская, 3б, офис GlobalLogic (карта).
  • Цель: игроделы делятся опытом в разработке, дизайне (Гейм/Левел/Графика), продвижении, анимации, 3D моделинге игр
  • Регистрация: по ссылке
  • Стоимость: бесплатно

 

2. JS+UI Dev Meetup - 19 августа, вторник

  • Анонс: на Developers.Org.Ua
  • Место: Харьков, ул. Новгородская, 3б, офис GlobalLogic (карта)
  • Цель: обмен знаниями между fron-end и JavaScript-разработчиками.
  • Регистрация: по ссылке
  • Стоимость: бесплатно

Доклады:

  1. Igor Nesterenko (Software Engineer, GlobalLogic),
    «JavaScript Package Management Overview».
  2. Anna Khabibulina (co-founder of DA-14 Web Development Team),
    «Web Components: Web Now and Tomorrow».
  3. Oleg Yaroshevych (Consultant Software Engineer, GlobalLogic),
    “Ember Data Framework”.
 

Приходите — ждем!


2014-08-08

15:22:53, Flash-ripper.com
Sigma Ukraine ищет флэш-разработчика в Харькове
Sigma Ukraine LogoSigma приглашает сильного Flash-разработчика для разработки онлайн-казино (игровые автоматы, рулетки, покер и др.) для большого европейского заказчика. Язык — Action Script 3, есть готовая платформа.

2014-08-07

12:49:46, Flash-ripper.com
Онлайн-школа компьютерной графики и анимации на Flash

Владимир Лыков написал

Друзья, мы пробуем создать онлайн-школу Компьютерной графики и анимации. Будем учить детей и взрослых работать во Флэш, рисовать персонажей, создавать анимацию. У нас такое желание есть. По цене я думаю договоримся. Если Вам это интересно, то пишите нам. От Вас нужен компьютер, доступ к интернету, ну и программу Вы должны сами установить. А от нас онлайн-инструкторы, которые Вас научат всему. Занятия будут проходить 2-3 раза в неделю по вечерам Заинтересованные пишите в личку. Наши работы Вы можете посмотреть здесь: (http://www.toongu.ru)

От себя добавлю: у студии много хороших работ в 2D-анимации, включая участие в таких проектах, как Фиксики:

Напишите Владимиру!


2014-07-25

16:24:24, Flash-ripper.com
UPDATE: Встреча UAFPUG-47 - Харьков, 6 сентября
ВАЖНО: изменилась дата встречи!

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

Координаты:

Программа встречи: 

  1. Как я намучался с HTML5 Ростислав Сирык, Харьков.
  2. Почему я продолжаю использовать Adobe Flash Сергей Соболев, Харьков.
  3. Что ждет нас в новом Away3D в 2014 году Родион Сумской, Харьков.
  4. Украинский рынок мобильных приложений Андрей Комаров, Харьков.
  5. [Тема уточняется]

Хотите сделать доклад или услышать о чем-то конкретном?

Пишите в комменты или на rostislav.siryk@gmail.com

Как добраться?

Карта:

 

 

Регистрация началась!

 

 

 

 

Тэги: 

2014-07-24

10:28:48, Flash-ripper.com
Три вещи, которые айтишнику нужно знать о мобилизации

1. Началась третья очередь первой волны мобилизации

Вступил в силу закон о третьей очереди частичной мобилизации.

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

Руководствуясь этим списком, снаряжают бойцов в батальон "Айдар" (уточнения и дополнения приветствуются):

  1. Баул или большой рюкзак
  2. Камуфляж, лучше два комплекта
  3. Головной убор
  4. Берцы
  5. Кроссовки и кеды
  6. Резиновые тапки
  7. Резиновые сапоги
  8. Футболки, носки, трусы - несколько комплектов на неделю
  9. Свитер
  10. Перчатки
  11. Москитная сетка
  12. Очки тактические
  13. Очки солнцезащитные
  14. Часы наручные электронные
  15. Ремень военный
  16. Каска и кавер на каску
  17. Бронежилет
  18. Разгрузка
  19. Каремат
  20. Спальный мешок
  21. Палатка одноместная
  22. Дождевик
  23. Саперная лопатка
  24. Краска для лица
  25. Вещи личной гигиены и бритвенные принадлежности.

3. Чтобы до вашей мобилизации дело не дошло, помогите армии

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

Мы помогаем, покупая израильские компрессионные повязки (индивидуальные перевязочные пакеты) для срочной помощи при ранениях.
Полная информация здесь:

Помощь раненым в АТО

Мир вашему дому!

P.S. Справка: Украина воюет с организованными и хорошо вооруженными террористами.

 

 

 

 

 


2014-07-23

11:29:09, Flash-ripper.com
Трансляция 3-го дня Web Camp Odessa

Пишет Дмитрий Сподарец: Начали 3-й день Web Camp Odessa. Сегодня говорим об управлении проектами. Трансляция на сайте: http://webcamp.in.ua/ #geekslab

Web Camp Odessa

Темы конференции: разработка, управление проектами, дизайн, интернет-маркетинг и мобильные технологии.


2014-07-22

07:46:28, Flash-ripper.com
Онлайн-трансляция дня мобильных технологий с WebCamp Odessa

Пишет Дмитрий Сподарец из Одессы, организатор проходящей сейчас в рамках Odessa Innovation Week конференции WebCamp2014: "Сегодня говорим о мобильных технологиях." Онлайн-трансляция — на http://webcamp.in.ua

WebCamp Odessa

 

 

Тэги: 

2014-07-21

12:55:12, Flash-ripper.com
Бесплатный шрифт Shket

Shket is a modern sans serif typeface that comes with more than 460 glyphs to support a variety of languages. It also includes 471 kerning pairs, mathematical characters, and more. It's meant for use at large sizes, and is ideal for posters, headlines, and more. It's regularly updated and improved, too.

Download Free Shket font

Тэги: 

2014-07-18

10:32:27, Flash-ripper.com
Как изменить все шрифты в файле FLA

JSFL всех нас переживет: получил благодарность в твиттере за пост 2007 года на ActionScript.org — до сих пор актуальная инструкция. Так что перевожу на русский и делюсь по новой.

Задача: есть масса чужих FLA файлов с кучей анимации на таймлайне. Нужно изменить все шрифты на новые.

Решение: сценарий на JSFL. Он заменяет шрифты, строит и сохраняет отчет о каждой замене. Скрипт рекурсивно обходит весь документ, пока не найдет все текстовые элементы. Для каждого текстового элемента строится его путь, создается массив текстовых элементов документа для будущего использования.

Итак, в первом JSFL-файле по адресу "\Documents and Settings\[]\Local Settings\Application Data\Adobe\Flash X\en\Configuration\Commands\[FR] Replace Fonts.jsfl" происходит замена и создание отчета:

var dom = fl.getDocumentDOM();

dom.editScene(0);
//dom.selection = dom.getTimeline().layers[0].frames[0].elements;

fl.outputPanel.clear();
fl.trace("********************************************************************");
fl.trace("  START OF FONT REPLACEMENT REPORT\n");
fl.trace("  FONT REPLACEMENT UTILITY");
fl.trace("  v 1.0.2");
fl.trace("  Author: Rostislav Siryk");
fl.trace("  http://flash-ripper.com/");
fl.trace("********************************************************************");

fl.trace("\nFILE NAME:\t" + dom.name + ".fla");
fl.trace("FILE PATH:\t" + dom.path + "\n");

//fl.saveDocumentAs(.documents[0].path);

// Font to be replaced
var font_select = new Array("MyLifeSans", 
							"MyLifeSer",
							"Myriad",
							"Myriad-Bold",
							"Myriad-Roman",
							"Frutiger 45 Light",
							"Frutiger 55 Roman",
							"Garamond Book",
							"ArialNarrow-Bold",
							"Avenir LT Std 65 Medium",
							"Helvetica",
							"Verdana",
							"Arial Black",
							"Arial Narrow",
							"Myriad Roman"
							);

var textElements = new Array();

var numTotalRuns = 0;
var strOutput = "";
var fontsFound = new Array();
var strFoundFonts = "";
var numTextItemsTotal = 0;
var numTextItemsReplaced = 0;

var strLayerName = "";
var strItemFullPath = "";
var strItemHumanPath = "";


// Delimiters used to create element paths
var strTimelinesDelimiter = ".libraryItem.timeline";
var strLayerDelimiter = ".layers";
var strFrameDelimiter = ".frames";
var strElementDelimiter = ".elements";
var BR_O = "[";
var BR_C = "]";

findTextElements = function(theTimeline) 
{
	if(theTimeline && theTimeline.layers.length > 0)
	{
	var theLayers = theTimeline.layers;
	for(var numLayer = 0; numLayer < theLayers.length; numLayer++)
	{
		// Parse FRAMES of the LAYER
		var theFrames = theLayers[numLayer].frames;
		for(var numFrame = 0; numFrame < theFrames.length; numFrame++)
		{
			// Parse only KEY Frames. I said PARSE ONLY \KEY/ FRAMES.
			if (numFrame == theFrames[numFrame].startFrame)
			{
				// Parse ELEMENTS of the KEYFRAME
				var theElements = theFrames[numFrame].elements;
				for(var numElement=0; numElement < theElements.length; numElement++) 
				{
					numTotalRuns ++;
					
					var foundElement = theElements[numElement];

					// if element is not text but instance
					if(foundElement.elementType == "instance")
					{
						// Add LAYER to the item full path
						strItemFullPath += strLayerDelimiter + BR_O + numLayer + BR_C;

						strLayerName = "." + theLayers[numLayer].name;
						strItemHumanPath += strLayerName;
						
						// Add FRAME, ELEMENT and TIMELINE to the item full path
						strItemFullPath += strFrameDelimiter + BR_O + numFrame + BR_C + strElementDelimiter + BR_O + numElement + BR_C + strTimelinesDelimiter;
						strItemHumanPath += "[fr" + numFrame + "]" + (foundElement.name || "(unnamed)");
						
						findTextElements(foundElement.libraryItem.timeline);
					}
					else if	(foundElement.elementType == "text")
					{
						// Add LAYER to the item full path
						strItemFullPath += strLayerDelimiter + BR_O + numLayer + BR_C;

						strLayerName = "." + theLayers[numLayer].name;
						strItemHumanPath += strLayerName;
						
						// Add FRAME and ELEMENT to the full path and FINALIZE path
						strItemFullPath += strFrameDelimiter + BR_O + numFrame + BR_C + strElementDelimiter + BR_O + numElement + BR_C;
						strItemHumanPath += "[fr" + numFrame + "]" + (foundElement.name || "(unnamed)");

						textElements.push({theElement:		foundElement, 
										  	itemID:			numTextItemsTotal, 
											itemPath:		strItemFullPath,
											itemHumanPath:	strItemHumanPath
											});
						
						// Reset the paths for the next iteration 
						strItemFullPath = "";//strLayerDelimiter + BR_O + numLayer + BR_C;
						strItemHumanPath = "";
						
						numTextItemsTotal++;
						
/*						numElement = theElements.length;
						numFrame = theFrames.length;
						numLayer = theLayers.length;
						break;*/
					}
				}
			}
			else
			{
				// NO KEYFRAME ACTION
			}
		}
	}
	}
}
/*for(var i=0; i < dom.library.items.length; i++) 
{
	fl.trace("LIBITITEM.");
	findTextElements(dom.library.items[i].timeline)
}*/

function enumerateAllTextElements()
{
	for(var numTe = 0; numTe < textElements.length; numTe++)
	{
		var te = textElements[numTe];
		strOutput += "\n\tTEXT #" + te.itemID
			+ "\n\tFont:\t" + te.theElement.getTextAttr("face")
			+ "\n\tPath:\t" + te.itemPath
			//+ "\n\tSeek:\t" + te.itemHumanPath
			+ "\n\tText:\t" + te.theElement.getTextString()
			+ "\n";
	}
}

function replaceAllFonts()
{
	for(i=0; i < font_select.length; i++)
	{
		font_replaced = font_select[i];
		font_replacement = "Arial";
		if(font_replaced == "Garamond Book") 
			{
				font_replacement = "Times New Roman";
			}
		for(var te = 0; te < textElements.length; te++)
		{
			replaceFont(textElements[te]);
		}
	}
}

function replaceFont(objText)
{
	var textElement = objText.theElement;
	//fl.trace("TE= " + textElement.theElement);
	if(textElement.getTextAttr("face"))
	{
		var oldFont = textElement.getTextAttr("face");
		var oldSize = textElement.getTextAttr("size");
		var txt = textElement.getTextString();
		
		addFoundFont(oldFont);
		
		if(oldFont == font_replaced) 
		{
			numTextItemsReplaced++;
			textElement.setTextAttr("face", font_replacement);
			
			var strSizeChange = "";
			if(!isNaN(oldSize) && (oldFont == "FullLifeSans" || oldFont == "FullLifeSer"))
			{
				newSize = oldSize * 0.85 || Math.floor(oldSize * 0.85);
				textElement.setTextAttr("size", newSize);
				strSizeChange = 
					"\n\tOLD Size:\t" + oldSize
					+ "\n\tNEW Size:\t" + newSize;
			}

			strOutput += "\n\tREPLACE #" + objText.itemID
				+ "\n\tOLD Font:\t" + oldFont
				+ "\n\tNEW Font:\t" + font_replacement
				+ strSizeChange
				+ "\n\tPath:\t" + objText.itemPath
				//+ "\n\tSeek:\t" + objText.itemHumanPath
				+ "\n\tText:\t" + txt
				+ "\n"
		}
		else
		{
				//strOutput += "\t[NO CHANGES TO FONT]\n"; 	
		}
	}
}

function addFoundFont(fontName)
{
	isInFontsFoundAlready = false;
	for(var i=0; i < fontsFound.length; i++)
	{
		if(fontsFound[i] == fontName)
		{
			isInFontsFoundAlready = true;
			break;
		}
	}
	if(!isInFontsFoundAlready)
	{
		fontsFound.push(fontName);
		strFoundFonts += "\n\t" + fontsFound.length + "\t" + fontName;
	}
}

/*font_replaced = "FullLifeSer";
font_replacement = "Arial";*/

findTextElements(dom.getTimeline());

strOutput += "FOUND TEXT FIELDS:\t" + numTextItemsTotal + "\n";
strOutput += "******************\n";
enumerateAllTextElements();

strOutput += "\n\nREPLACEMENTS MADE:\t" /*+ numTextItemsReplaced*/ + "\n";
strOutput += "******************\n";

replaceAllFonts();

fl.trace("TOTAL RUNS:\t" + numTotalRuns);
fl.trace("ITEMS FOUND:\t" + numTextItemsTotal);
fl.trace("ITEMS REPLACED:\t" + numTextItemsReplaced);
fl.trace("FONTS FOUND:\t" + fontsFound.length + strFoundFonts + "\n");

fl.trace("DETAILS:");
fl.trace("********");
fl.trace("\n" + strOutput + "\n\n");

fl.trace("********************************************************************");
fl.trace("  END OF FONT REPLACEMENT REPORT");
fl.trace("********************************************************************");

// Saving created report to as file
fl.outputPanel.save("file:///d|/Projects/eLearn2/reports/" + dom.name + "-report.txt");

fl.outputPanel.clear();
// NOW WRITE SOME INFO JUST ABOUT FONTS FOR STATISTICS
fl.trace("\n==========================");
fl.trace("FONTS INFO FOR FILE:\t" + dom.name + ".fla");
fl.trace("FILE PATH:\t" + dom.path + "\n");
fl.trace("FONTS FOUND:\t" + fontsFound.length + strFoundFonts + "\n");

// Append font report to file
fl.outputPanel.save("file:///d|/Projects/eLearn2/reports/global-font-report.txt", true);

dom.publish();
dom.saveAndCompact();
dom.close();

Второй JSFL-файл управляет работой первого для процессинга нескольких FLA

Он запускает первый на каждом из исходных FLA:

2. "\Documents and Settings\[]\Local Settings\Application Data\Adobe\Flash X\en\Configuration\Commands\[FR] Batch Replace Fonts.jsfl"
fl.outputPanel.clear();

fl.trace("******************************************************");
fl.trace("  BATCH REPLACE FONTS IN MULTIPLE FILES");
fl.trace("  Author: Rostislav Siryk");
fl.trace("  http://flash-ripper.com/");
fl.trace("******************************************************\n");

function getDuration(tEnd, tStart)
{
	var msecsDur = tEnd - tStart;
	
	var msecs = String(msecsDur).substr(String(msecsDur).length - 3);
	var secs = Math.floor(msecsDur / 1000);
	var mins = Math.floor(msecsDur / 60000);
	var hrs = Math.floor(msecsDur / 3600000);

	if (hrs < 10) hrs = "0" + hrs;
	if (mins < 10) mins = "0" + mins
	if (secs < 10) secs = "0" + secs;
	if (msecs < 10) msecs = "00" + msecs;
	else if (msecs < 100) msecs = "0" + msecs;
	
	
	return {durString: hrs + ":" + mins + ":" + secs + "." + msecs, durValue:msecsDur};
}

function getTimeString(aDate)
{
	time = aDate.getTime();
	hours = aDate.getHours();
	minutes = aDate.getMinutes();
	seconds = aDate.getSeconds();
	milliseconds = aDate.getMilliseconds();
	if (minutes < 10) minutes = "0" + minutes
	if (seconds < 10) seconds = "0" + seconds;
	if (milliseconds < 10) milliseconds = "00" + milliseconds;
	else if (milliseconds < 100) milliseconds = "0" + milliseconds;

	return hours + ":" + minutes + ":" + seconds + ":" + milliseconds;
}

function getCurrentTime()
{
	var dateNow = new Date();
	return {timeString: getTimeString(dateNow), timeValue:time};
}

var timeStart = getCurrentTime().timeString;
var timeStartValue = getCurrentTime().timeValue;

var numErrors = 0;

scriptFile="file:///c|/Documents and Settings/rost/Local Settings/Application Data/Macromedia/Flash 8/en/Configuration/Commands/[FR] Replace Fonts.jsfl"

// ADVANCED COURSE FILES LIST
strPathsAdv = 
"file:///d|/Projects/eLearn2/Fla/sec01/s02_01_01.fla#" +
"file:///d|/Projects/eLearn2/Fla/sec01/s02_01_02.fla#" +
"file:///d|/Projects/eLearn2/Fla/sec01/s02_01_03.fla#" +
"file:///d|/Projects/eLearn2Fla/site_files/ssecondary_4.fla#";


// BASIC COURSE FILES LIST
strPathsBasic = 
"file:///d|/Projects/eLearn2/Fla/sec01/s01_01_01.fla#"+
"file:///d|/Projects/eLearn2/Fla/sec01/s01_01_02.fla#"+
"file:///d|/Projects/eLearn2/Fla/sec01/s01_01_03.fla#"+
"file:///d|/Projects/eLearn2/Fla/site_files/ssecondary_4.fla"

fileStr = strPathsAdv + strPathsBasic;

if(fileStr.length > 0 && scriptFile.length > 0)
{
	var files = fileStr.split("#")
	var numFiles = files.length
	
	for(var f = 0; f < numFiles; ++f)
	{
		if(fl.fileExists(files[f]))
		{
			var tStart = getCurrentTime().timeString;
			var tStartValue = getCurrentTime().timeValue;
			fl.trace("Open File:\t" + files[f]);
			fl.openDocument(files[f])
			fl.runScript(scriptFile)
			fl.trace("\tFILE COMPLETE");
			fl.trace("\tSTART TIME:\t" + tStart + "\t(" + tStartValue + " msec)");
			fl.trace("\tEND TIME:\t" + getCurrentTime().timeString + "\t(" + getCurrentTime().timeValue + " msec)");
			fl.trace("\tDURATION:\t" + getDuration(getCurrentTime().timeValue, tStartValue).durString + "\t(" + getDuration(getCurrentTime().timeValue, tStartValue).durValue + " msec)\n");
		}
		else
		{
			fl.trace("ERROR OPENING FILE: File doesn't exist:\t"+ files[f] + "\n");
			numErrors++;
		}
	}
}

fl.trace("\n******************************************************");
fl.trace("FILES TOTAL:\t" + numFiles);
fl.trace("ERRORS TOTAL:\t" + numErrors);

fl.trace("\nSTART TIME:\t" + timeStart + "\t(" + timeStartValue + " msec)");
fl.trace("END TIME:\t" + getCurrentTime().timeString + "\t(" + getCurrentTime().timeValue + " msec)");
fl.trace("DURATION TOTAL:\t" + getDuration(getCurrentTime().timeValue, timeStartValue).durString + "\t(" + getDuration(getCurrentTime().timeValue, timeStartValue).durValue + " msec)");
fl.trace("******************************************************");

// Save report to file
fl.outputPanel.save("file:///d|/Projects/eLearn2/reports/batch-font-replace-report.txt");

Когда-то JSFL стал моим первым шагом в JavaScript :)


2014-07-17

10:50:17, Flash-ripper.com
Зачем в JavaScript используют return !0

Часто в JavaScript-коде можно увидеть такое: return !0;  Зачем это нужно?

Это такой хитрый способ записать true и результат минимизации JavaScript для экономии веб-траффика. Ведь для передачи !1 нужно всего 2 байта, а для передачи true — целых 4!

А почему не return 1, ведь это тоже дает true и занимает всего один байт?

А потому, что результат return 1 будет типа number, и если кто-то будет обрабатывать это строгими операторами типа === или !== , то получит ожидаемый результат от !0, а не от 1. Утащил со StackOveflow.

См. также: JavaScript-компилятор Closure.

Тэги: 

2014-07-15

10:49:27, Flash-ripper.com
Быстрый старт с ASDoc во Flash Builder 4

Пока Флекс не собирается исчезать, этото совет может кому-то пригодиться.

Работа с ASDoc во Flex SDK обстоит неказуально, разобраться без посторонней помощи сложно, даже очень. Как-то я потерял на этом день и теперь знаю, как этого избежать. 

Ant ASDoc Task

Flex Ant ASDoc Task — это утилита-обертка вокруг ASDoc tool, позволюящая вынести опции сборки в файл build.xml, а затем собрать документацию через ASDoc с Apache AntДля быстрого старта с Ant ASDoc Task изучите и переделайте уже работающие примеры. Например, сборку документации к классам, идущим в составе Flex SDK.

Начните с файла "c:\Program Files\Adobe\Adobe Flash Builder 4\sdks\4.X.X\asdoc\build.xml". Это готовый конфиг для сборки. В любом Flex SDK нужный билд-файл находится по относительному адресу "[FLEX_SDK_DIR]\asdoc\build.xml". 

Данный конфиг можно легко переделать под свой проект. Это легче, чем начинать с нуля, вы быстро поймете, что в нем вам нужно, а что — нет.

Полезная ссылка: http://racer242.blogspot.com/2008/01/asdoc-as3.html


2014-07-14

10:52:08, Flash-ripper.com
Ссылки по CSS Media Queries и оптимизации под мобильные устройства

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

CSS Media Queries для веб-разработчиков:

  1. Media Queries for Standard Devices на css-tricks.com:
  2.  - Media Query Snippets на nmsdvid.com
  3.  - Экспериментируем с CSS3 на css3please.com
  4.  - Media Query Builder - arsec.com
  5.  - Combining meta viewport and media queries - quirksmode.com (2010-09)
  6.  - Fixes for Mobile Safari Zoom-Orientation bug - forrst.com (2012-06)
  7.  - iPad layout scales up when rotating from portrait to landcape - stackoveflow - 2012-04
  8.  - iOS-Orientationchange-Fix - github
  9.  - Как отличить iPhone от iPad - stackoverflow
  10. Considerations for Mobile Design (Part 2): Dimensions - uxbooth.com
  11. Designing for the Retina Display (326ppi) - LukeW, подборка ссылок
  12.  - Optimising for High Pixel Density Displays - menacingcloud.com
  13.  - How to make your web content look stunning on the iPhone 4's new Retina display - Aral Balkan (исторический интерес)
  14. CSS Techniques for Retina Displays - sitepoint.com - 2013-01
  15. Responsive Design in IE10 on Windows Phone 8 - mattstow.com - 2013-01
  16. Кризис идентичности пикселя - Хабр - 2012-06
  17. Progressive enhancement + mobile first = responsive web design - Хабр - 2012-01
  18. Адаптивный веб-дизайн на практике - Хабр - 2012-04
  19. Как сделать один сайт для всех устройств (Responsive Web Design) - Хабр - 2011-07
  20. Переводим в код 5 действительно полезных шаблонов адаптивной разметки - Хабр - 2012-04
  21. Коллекция паттернов поведения для элементов отзывчивого веб-дизайна - Хабр - 2012-09
  22. Туториал: Создаем адаптивную страницу портфолио с фильтрами - хабр - 2013
  23. [Перевод] HTML5 Адаптивные изображения.
  24. 62 полезных инструмента для адаптивного дизайна - Хабр - 2012-04

Как инструмент веб-разработки рекомендуем Sublime Text 2, почитайте.


2014-07-13

11:16:01, Flash-ripper.com
Почитать про Друпал
Тэги: 

2014-07-12

09:52:28, Flash-ripper.com
Мой фейл на Amazon Web Services

о боже что с его рукой

Амазон AWS - хороший сервис для хостинга и подстраховки хостинга. И мы переехали на него в апреле 2012 г. Но потом отказались от его использования по двум причинам: дорого и сложно.

Дорого: $86 в месяц за использование MySQL

Я этого не знал, пока не ощутил на себе, а дело было так:

  1. Апрель'2012. Я подписался на пакет бесплатных сервисов от Амазона и разместил на них сайт Ф. Потрошителя. Амазон честно предупредил, что я могу использовать MySQL бесплатно 750 часов. И что по исчерпании этого времени за MySQL нужно платить по обычному ценнику Амазона.
  2. Я легкомысленно согласился. Я поленился подсчитать, сколько придется платить.
  3. Июль'2012. Прошли 750 часов бесплатного MySQL, и от Амазона начали приходить увеличенные счета:
    • $7.09 - апрель
    • $3.21 - май
    • $3.19 - июнь
    • $86.11 - июль - халява закончилась, я начал платить за MySQL.
    • $86.11 - август - платим за БД.
    • $85.11 - сентябрь - платим.
    • $87.09 - октябрь - платим больше.
    • $67.70 - ноябрь - я отключил сервис Amazon RDS, дающий мне дорогой MySQL.
    • $0.00 - декабрь.
  4. Не понимая, что происходит, т.к. я уже все забыл про платный MySQL, и не находил времени разобраться, я платил. Через четыре месяца очнулся, понял, что сам виноват и начал разбираться. Отключил дорогостоящий MySQL от Амазона.
  5. Переехал на AN Hosting по $4 в месяц (можно через меня зарегистрироваться). О хостинге узнал от друпал-юзера 80-го уровня, автора drupalmodules.com. Потом они переименовались в MidPhase.

Не готов быть суперадмином

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

Сложная настройка FTP. В результате научился заливать обновления на сайт через svn, для чего установил его на  сервере, настроил репозитории и т.п. И даже получал эстетическое удовольствие от использования такой изощренной системы. Но удовольствие - это одно, а каждодневное удобство оказалось важнее. Отсутствие обычного FTP-доступа делало работу совсем не такой удобной.

Бесплатный сервер от Амазона не выдерживал нагрузки и часто лежал. Это подтвержадет правило: бесплатного сыра нет. За хороший сыр надо платить. Потрошитель использует Drupal, а это очень прожорливая система. Особенно много он хочет памяти и часто обращается к MySQL. 

А для чего подходит Amazon?

На самом деле - много для чего. Например, для сайтов, не требующих работы с MySQL. Вот пример: Ексей рассказывает, как Амазон спасает его, когда трафик его сайта взлетатет. При этом он платит в Амазону в среднем $4 в месяц. 

Друг-админ предложил идею: а почему бы не запустить сервер MySQL на том же бесплатном микро-инстансе, на котором работает сайт, и таким образом получить MySQL бесплатно? Идея интересная, но подойдет скорее для сайтов с небольшой нагрузкой на БД. Например, для сайтов в разработке, без широкого публичного трафика, создающего массу запросов к БД.

Также, думаю, при наличии хорошего админа Амазон подойдет многим высоконагруженным сайтам, в том числе и в качестве подстраховочного, резервного сервера.

Амазон не виноват :)

Моя ошибка с Амазоном была в том, что я хотел из бесплатного варианта выжать ресурсы, превосходящие его возможности. Я попытался хостить на нем сайт, отъедающий много памяти и интенсивно работающий с MySQL. Понимаю, что всегда есть варианты.  Интересно услышать мнение знающих людей :- )


2014-07-11

11:18:55, Flash-ripper.com
Как восстановить исходник FLA-файла, если Flash CS5 его запорол

Это не статья, а набор ссылок, которые могут помочь некоторым несчастным:

Корень проблемы: пустой тэг <frame/> в XML-файле и ETX (End of Text) character.

Тэги: 

09:11:52, Flash-ripper.com
Правило минимальной власти

Любая программа, которую можно написать на JavaScript, будет на нем написана.

Этот закон вывел сооснователь StackOverflow Джеф Этвуд в 2007 году задолго до того, как JavaScript приобрел взрывную популярность. Он развил "Правило минимальной власти", задокументированное создателем интернета Тимом Бернесом Ли. В 2005 году Тим выпустил книгу, резюмирующую его видение семантической сети как надстройки над интернетом. В ней компьютеры могут анализировать существующее содержимое и повторно перерабатывать его, создавая все более более осмысленные структуры на основе сетевого контента.

Язык, который не прячет данные

Правило минимальной власти в веб-программировании означает выбор наименее "властного" языка, пригодного для решения данной задачи. Чем описательнее язык (т.е. чем менее он процедурен, или императивен), тем больше можно сделать с данными, записанными на этом языке: повторно их обработать, и сделать это сколь угодно много раз, решая задачи в мире открытой информации.

Наименее властный, т.е. максимально описательный язык — это текстовая база данных или HTML. Максимально властными, или процедурными, являются традиционные языки программирования, дающие результат в виде скомпилированного кода, в т.ч. ActionScript. JavaScript некомпилируем, т.е. менее властен. Отец интернета Тим Бернес Ли:

Информатика 1960-80-х годов потратила уйму усилий на создание языков, мощных настолько, насколько это возможно. Сегодня мы должны ценить основания для выбора не наиболее, а наименее мощного языка. Менее мощный язык позволяет больше сделать с записанными на нем данными. Если вы пишете в простой декларативной форме, то любой желающий может написать программу и проанализировать ваши данные иначе. Семантическая сеть является попыткой отображения большого количества существующих данных на общем языке так, чтобы данные можно было проанализировать способом, неведомым оригинальным авторам. Например, если веб-страница о погоде является RDF-описанием погодных данных, то пользователь (имеется в виду другой программист) может получить результат в виде таблицы, проанализировать их или построить по ним диаграмму, сделать выводы, сопоставив это с другими данными. На другом конце шкалы находится информация о погоде, отображаемая сложным и красивым Java-апплетом. Его пользовательский интерфейс лучше, но он не может быть проанализирован желающими как данные. Поисковая система не поймет эти данные и о чем они. Единственный способ узнать, что означает Java-апплет — посмотреть на него глазами человека.

Недостижимо идеальная семантика

Сеть Тима Бернеса Ли пока осталась мечтой. Она нереализуема в чистом виде, как, например нереализуем в чистом виде вечный двигатель. Но, подобно тому, как попытка создания вечного двигателя может дать лучший двигатель,  мечта о семантической сети продолжает давать хорошие плоды. Например, микроформаты и стандарты мета-данных для адресации объектов сети.

Многие разработчики радуются возможности компиляции своих приложений, предпочитая не думать о том, как мало это дает остальным. Некоторые свысока смотрят на веб-программирование, HTML и JavaScript. Но возможно, что фактор закрытости Flash-контента и стал препятствием на пути развития. C точки зрения семантики Flash, как бинарный формат, является властным, закрытым языком, пригодным для использования лишь конечным пользователем-человеком, но не компьютером.

Флэш дает много конечному пользователю. Большинство визуальных эффектов было изобретено или впервые реализовано именно на Flash. Игры процветают (но все больше как Adobe AIR). Но из веба флэш уже ушел.

Скажи мне, где мои данные и я скажу, кто ты

Флэшеры критикуют несовершенство Javascript как некомпилируемого языка с "ненастоящим" ООП. Но благодаря этому "невластный" JavaScript больше подходит для  открытой веб-разработки.

Борьба открытости с закрытостью идет вечно, оба подхода имеют свои сильные стороны. Adobe ведет работы над конвертированием SWF в более открытый HTML5. Отдав технологию Flash сообществу для реализации бесплагинного внедрения в сетевой поток, Адоби сделает шаг к большей открытости Flash. Это может спасти Flash как технологию. 

Но изменит ли это отношение флэшеров к той сети, в которой они живут?


2014-07-10

12:50:16, Flash-ripper.com
Освобожденный Flex ищет друзей

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

Большие вещи живут крепко и держат даже самые подлые удары судьбы. Например, Apache Flex. Даже крайне неудачные обстоятельства вокруг передачи Флекса из сложных корпоративных клоак Adobe в руки опенсорса не смогли умалить реальную ценность и красоту этого события. Жаль, что Адоби не смогли представить это событие в его лучшем значении (но они пытались). Это породило уныние среди флексеров, а тем временем можно отвлечься от иллюзии декаданса и увидеть красоту события.

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

Кстати, Balsamiq Mockups, каждый день спасающий меня при прототипировании веб-интерфейсов, написан еще на третьем флексе и просто офигенно работает — так ,что я не пожалел $70 и таки купил его себе.

Тэги: 

2014-07-09

13:07:21, Flash-ripper.com
17 и 18 октября — DevGamm в Минске!

17 и 18 октября — DevGamm в Минске

В этом году гостеприимная столица Беларуси будет принимать участников международной игровой конференции DevGAMM! — сообщает блог конференции. Цитирую дальше:

Мы предлагаем провести два дня, 17 и 18 октября, в этом замечательном городе и посетить самое масштабное игровое мероприятие в Белоруссии!

Место встречи: Renaissance Minsk Hotel. Ожидается порядка 800+ профессионалов игровой индустрии из разных стран! 

Еще с момента самой первой конференции в 2008 году поступало множество просьб о том, чтобы провести DevGAMM в Минске. И теперь мы можем это осуществить. Традиционная киевская конференция DevGAMM в этом году не состоится по ряду причин, в том числе и из-за нестабильной ситуации в Украине.

Однако мы не покидаем Киев насовсем и планируем туда вернуться в следующем году. Конференция DevGAMM Minsk 2014 направлена на развитие игровой разработки в странах СНГ и мы обещаем поддерживать титул “самого продуктивного мероприятия в игровой индустрии”!

Мы с нетерпением ждем в Минске наших постоянных участников. Столица Белоруссии порадует вас своим удобным расположением, транспортной доступностью и множеством достопримечательностей.

В планах привлечь большое количество зарубежных спикеров и сделать DevGAMM Minsk самым ярким событием геймдева в Белоруссии!

Следите за новостями в нашем блоге и twitter и первыми узнавайте о новых спикерах, темах докладов и специальных мероприятиях. С нетерпением ждем вас в Минске! Ранняя регистрация уже открыта! Всегда ваша, DevGAMM Team

-8<-------------------------------------------------------

Добавлю от себя:

  1. Очень хорошо, что сбылась давняя мечта минчан захостить ДевГАММ в Минске. Искренне поздравляю вас с этим!
  2. Плохо, что более тысячи людей (а я желаю ДевГАММу, не меньшего успеха) не смогут увидеть дружелюбный, мирный, свободный Киев.
  3. Хорошо, что "мы не покидаем Киев насовсем". Все пройдет :)

Легкого дебага!
Рост

Тэги: 

2014-07-08

14:06:55, Flash-ripper.com
Use Beautiful Fonts IN YOUR designs!

Adobe Typekit that brings thousands of fonts from foundry partners into one library for quick browsing, easy use on the web or on your desktop, and endless typographic inspiration" />

TypeKit is a subscription font service that brings thousands of fonts from foundry partners into one library for quick browsing, easy use on the web or on your desktop, and endless typographic inspiration.


10:09:58, Flash-ripper.com
Подготовка к мини-конференции игроделов в Харькове

В Харькове идет подготовка к конференции по разработке игр. Пишет Вадим Водный (текст и иллюстрация автора):

Игроделы! Все кто уже погрузился в мир разработки игр или только мечтает туда попасть!

Не важно в какой вы должности! Еще больше не важно в какой компании вы работаете!

Бросаю второй клич! Буду рад любым комментариям или ответам в личку!

Для тех кто не в курсе, напоминаю, будем проводить мини конференцию, а точнее независимый сбор игроделов, тех кто любит игры, кто их делает, и тех кто только собирается этим заняться!
^_^

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

Всем желающим принять участие писать мне в личку!
Все бесплатно, безболезненно и крайне идейно)

GameDevConf Kharkiv

Призываю всех флэшеров-игроделов Харькова обратить на это мероприятие пристальное внимание!


2014-05-20

15:23:20, Flash-ripper.com
Электронное правительство Украины будет сделано в Ciklum

Украинское правительство выбрало Ciklum как поставщика технологии для своего нового портала электронного правительства, обеспечивая безопасные онлайн-услуги для граждан и предприятий.

Ciklum, один из ведущих европейских поставщиков аутсорсинга разработки программного обеспечения и ИТ-/ Agile консалтинговых услуг, сотрудничает с правительством Украины в поиске и выборе программных решений для модернизации и автоматизации государственного управления.

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

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

http://www.ciklum.com/ciklum-news/ukrainian-government-chooses-ciklum-im...


2014-05-14

04:40:03, Flash-ripper.com
Дмитрий Ганзин - Flash/Flex разработка
Ищу работу для фрилансера, работаю удаленно или по гибкому графику
Мое резюме: 
Имя: Дмитрий Ганзин
Опыт работы: 11 лет
 
Контакты: 
skype: dganzin
 
октябрь 2012 - май 2014
 
Flex\Flash разработчик. Разработка игры Гномград. Сервер, клиент, мобильная версия
MasterTigra, (mastertigra.com), Россия
 
июнь 2010 - октябрь 2012
 
Flex\Flash разработчик. Разработка социальных игр
GexSoft, (gexsoft.com), Франция
 
июнь 2009 — май 2010
 
Архитектор, консультант, тимлид на проекте Москва 3000
Pipe Studio, (pipestudio.ru), Москва, Харьков(Украина)
 
— занимался разработкой архитектуры Flash клиента
— сформировал ядро и принцип подключения внешних модулей на базе PureMVC
— разработал и реализовал систему кастомизации персонажей
— разработал и реализовал систему рендеринга векторной анимации в растровую, что дало большой прирост производительности
— курировал работу художников по оптимизации графики
 
апрель 2008 — май 2009
 
Flash программист
Project Axelarr, Омск
 
— разрабатывал клиента для игры. Использовал технологии Flex, PureMVC, Fabrication, PaperVision3D и др.
— участвовал в разработке Java сервера
 
май 2007 — апрель 2008
 
Программист
Freelance, Омск
 
— участвовал в разработках клиента для MMO игры
— занимался разработкой онлайн игры zibi.ru, всё полностью кроме дизайна сайта. Курировал художников.
 
февраль 2007 — май 2007
 
C# программист
Funlay, Омск
 
— разрабатывал приложения на C# и Python
 
июнь 2003 — сентябрь 2005
 
Глава отдела Flash разработок
ITPremium
 
— главы отдела флеш разработок
— занимался разработкой и партированием многих online игр
— участвовал в разработках игр онлайн казино, как клиента, так и сервера на Java
— разрабатывал GDP (Game Development Kit) - это внутриконторское SDK для разработки игр
— курировал разработку многих других проектов
 
skype: dganzin

 

Минимальная зарплата: 
$3300

2014-05-12

15:31:49, Flash-ripper.com
Мастер-класс по Away3D от Роба Бейтмена — 17 мая в Москве!

В конце прошлого года в Киевском HackerSpace (спасибо!) прошел мастер-класс по JS-версии Away3D от его создателя, Роба Бейтмена. Всем очень понравилось!

Для тех, кто использует Away3D, этот мастер-класс Роба может быть реально полезен. И вот, 17 мая, на следующий день после DevGAMM в Москве, ОН СОСТОИТСЯ!

Инфа о событии на блоге Away3D: Away3D Typescript training at DevGAMM Moscow

Регистрация:

Через EventBrite или через Timepad (чтобы заплатить в рублях)

С любовью,
Рост

 

 

 

 


2014-05-06

16:38:17, Flash-ripper.com
Свободу узникам Болотной!

Сегодня, 6 мая 2014 года, с 15.00 до 15.30 состоялся пикет консульства Российской Федерации "За Вашу и нашу свободу!".

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

Около 30 харьковчан собрались сегодня , чтобы:

  1. Выразить солидарность участникам акции "Марш миллионов", состоявшейся 6 мая 2012 года в Москве для выражения протеста против инаугурации Владимира Хуйла. Массовое шествие «Марш миллионов» завершилось жестокими силовым разгоном мирной акции протеста, по обвинению в организации массовых беспорядков было задержано около 500 участников акции. Основными лозунгами акции были — «За честную власть! За Россию без Хуйлоа!».
  2. Выразить протест против "Болотного дела" - расследуемого Следственным комитетом РФ уголовного дела о предполагаемых массовых беспорядках (ст. 212 УК РФ) и случаях насилия в отношении представителей органов правопорядка (ст. 318 УК РФ), якобы имевших место во время акции протеста «Марш миллионов» 6 мая 2012 года.
  3. Выразить солидарность и поддержку "узникам Болотной": к настоящему моменту обвинения предъявлены 27-ти участникам манифестации, вина которых заключается в том, что они пытались осуществить свое законное право на участие в протестном выступлении и защитить от полицейского насилия оказавшихся рядом сограждан. 13 из них находятся в тюрьме. 
  4. Требовать амнистию и освобождения всех лиц, обвиняемых или осужденных в связи с их участием в событиях 6 мая 2012 года на Болотной площади Москвы, а также других политзаключённых, экологов и узников совести.

Главными лозунгами пикета были: "За вашу и нашу свободу!" "Свобода политзаключенным!", "Свобода узникам Болотной!", символом акции были белые ленты.

 

 

Каждый из вас, друзья, может помочь политзаключенным! 
Пожалуйста, подпишите эту петицию:


https://secure.avaaz.org/ru/petition/Net_politicheskim_repressiyam/?launch

 

P.S. А в Москве сегодня — снова задержания на Болотной:

 


2014-04-21

11:10:25, Flash-ripper.com
Update: запись онлайн-встречи с Adobe

21 апреля прошла онлайн-встреча Adobe Flash Online Conference #9 (спасибо, Сергей Гончар)! Из Adobe участвовали Chris Campbell, Govinda Gupta, Romil Mittal, Ashok Mathew Kuruvilla и Cheng Liao.

Появилась запись этой встречи: http://gonchar.me/blog/goncharposts/2279


05:38:38, Action Script 3
Как отделить мух от колет?

Рано или поздно любой flex-разработчик понимает, что нужно что-то сделать с собственным “винегретом” в коде, состоящим из mxml-разметки вперемешку с inline-кодом. А, собственно, что с ним не так? Если кратко, то:

  • код трудночитаем, из-за постоянного перехода внутри одного файла от as3 кода к mxml разметке и обратно;
  • сильная связанность (нет возможности легко заменить разметку или реализацию);
  • низкая переиспользуемость кода (трудно перенести код/разметку в другой проект);
  • отсутствует возможность разделить обязанности между разработчиком и дизайнером (кто-нибудь помнит/пользовался Flash Catalyst?, ах да: Development and sales ended on April 23, 2012);
  • сильно разросшийся размер файла;
  • и так далее.


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

<?xml version="1.0" encoding="utf-8"?>   
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"  
    xmlns:s="library://ns.adobe.com/flex/spark"  
    xmlns:mx="library://ns.adobe.com/flex/mx"  
    height="450">  

    <s:layout>  
        <s:VerticalLayout/>  
    </s:layout>  

    <fx:Script> <![CDATA[  
        import spark.events.IndexChangeEvent;  
        private function myChangedHandler(event:IndexChangeEvent):void  
        {  
            var selIndices:Vector.<int> = event.currentTarget.selectedIndices;  
            var selItems:Vector.<Object> = event.currentTarget.selectedItems;  
            var numItems:Number = selIndices.length;  
            selIndicesTA.text = "";  
            selItemsTA.text = "";  
            for (var i:Number = 0; i<numItems; i++)  
            {  
                selIndicesTA.text = selIndicesTA.text + selIndices[i] + "\n";  
                selItemsTA.text = selItemsTA.text + selItems[i] + "\n";  
            }  
        }  
    ]]>  
    </fx:Script>  
 
    <s:List allowMultipleSelection="true" change="myChangedHandler(event);">  
        <mx:ArrayCollection>  
            <fx:String>Flex</fx:String>  
            <fx:String>Flash Builder</fx:String>  
            <fx:String>Flash</fx:String>  
            <fx:String>Director</fx:String>  
            <fx:String>Dreamweaver</fx:String>  
            <fx:String>ColdFusion</fx:String>  
        </mx:ArrayCollection>  
    </s:List>  

    <s:Label text="Selected indices"/>  
    <s:TextArea id="selIndicesTA" height="75"/>  
    <s:Label text="Selected items"/>  
    <s:TextArea id="selItemsTA" height="75"/>
  
</s:Application>

 

Вместо того, чтобы пропагандировать “здоровое кодирование”, а также потому, что не смогла, как обычно, сразу сделать нормально. А, в конце концов, совсем открестилась от flex-а. Возможно, мы перекладываем с больной головы на здоровую, и во всем виновата прокрастинация разработчика. Но и она в основе своей вытекает, хоть и отчасти, из предыдущей проблемы. (Действительно ленивый программист сразу пишет рабочий, красивый и сопровождаемый код).

Не будем о грустном. Так как же можно отделить просо от гречки? Если хорошо поискать, то Adobe предлагает следующие варианты:

  • использовать <fx:Script> блок. Собственно, от его использования мы и пытаемся избавиться;
  • инлайн обработчики событий:

<s:Button label="Convert" 
click="celsius.text=String(Math.round((Number(fahrenheit.text)-32)/1.8 * 10)/10);"/>

 

  • в отдельном as файле: <fx:Script source=”includes/Sample3Script.as”/>.

Много кода в инлайн обработчике не напишешь. Нельзя использовать операторы сравнения. Да и не похож этот вариант на разделение, скорее наоборот. Проходим мимо.

Описывание кода в отдельном as файле ни к чему, кроме головной боли, не ведет. Как минимум, код в пустом (безо всяких package, class и тд) файле выглядит странно, запутывает и приводит в уныние, наверное, все современные IDE. Кто-нибудь сейчас так пишет? Получается, название статьи расходится с её содержанием. Зачем она нужна непонятно (см. абзац “Почему так происходит”).

Вот мы все ругаем Adobe за Flex. Так ведь да, в один прекрасный момент она сама это поняла и переписала часть фреймворка, как надо. Ввела новый жизненный цикл компонентов и отделила логику/поведение компонентов от их внешнего вида и увеличила цифру у фреймворка аж до 4.00. Можно даже почитать, как правильно готовить такие компоненты. Переписать все компоненты сил не хватило, теперь этим занимается Apache Foundation.

Что же делать? И как быть? Наверное, многие уже поняли, к чему я клоню, и вспомнили о старом, добром CodeBehind-е.  Идея этого архитектурного паттерна проста: всю бизнес-логику пишем на чистом as3 (базовый класс), а расположение и внешний вид контролов, описываем, используя mxml-разметку. Все контролы, которые будут использоваться в коде, должны иметь id и быть описаны в базовом классе как публичные переменные с соответствующим типом. Звучит страшно, но на самом деле все просто. Рассмотрим пример:

// BaseControlPanel.as 
public class BaseControlPanel extends Group 
    { 
        public var stopButton : Button; 
        public var startButton: Button; 
        public function BaseControlPanel() 
        { 
            super(); 
        } 
 
 
        /** 
         * @inheritDoc 
         */ 
        override protected function createChildren():void 
        { 
            super.createChildren(); 
            stopButton.addEventListener(MouseEvent.CLICK, onStopButtonClicked); 
        } 
 
 
        /** 
         * Обработчик клика по кнопке старт 
         * @param e 
         */ 
        protected function onStartButtonClicked(e:MouseEvent):void 
        { 
            trace("Start"); 
        } 
 
 
        /** 
         * Обработчик клика по кнопке стоп 
         * @param e 
         */ 
        private function onStopButtonClicked(e:MouseEvent):void 
        { 
            trace("Stop"); 
        } 
    } 
 
// ControlPanelView.mxml 
<?xml version="1.0"?> 
<local:BaseControlPanel xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:local="*" xmlns:layouts="spark.layouts.*" 
                        xmlns:components="spark.components.*"> 
 
    <local:layout> 
        <layouts:HorizontalLayout paddingLeft="5" paddingTop="5"/> 
    </local:layout> 
 
    <!-- Кнопка запуска --> 
    <components:Button id="startButton" label="start" click="onStartButtonClicked(event)"/> 
 
    <!-- Кнопка остановки --> 
    <components:Button id="stopButton" label="stop"/> 
 
</local:BaseControlPanel>

В приведенном примере мы видим два варианта подписки на событие клика по кнопке. Стоп-кнопку мы подписываем на клик mxml файле. Для этого необходимо, чтобы обработчик события был виден, т.е. был либо protected либо public. Старт-кнопку мы подписываем в createChildren, сразу после того, как она создастся. Оба варианта приемлемы. Вариант с подпиской в разметке, как нам кажется, короче, но не так универсален. Если нам нужно будет создать еще один вариант разметки, нам придется еще раз подписывать кнопку на это событие, что избыточно и легко может привести к ошибке, если мы забудем это сделать. С другой стороны, если нам нужно подписаться на это событие не сразу, или подписать вообще другой компонент (который также может послать это событие), то сделать это без изменения as3 кода не получится. А так как именно эту проблему мы и решаем, то вариант с подпиской на событие в разметке в данном случае подходит лучше. Используем тот вариант, который решает нашу задачу лучше.

Таким образом, мы частично решили поставленные в начале статьи задачи, и даже получили некоторые другие преимущества:

  • создание конструктора класса;
  • возможность тестировать логику приложения отдельно от её представления;
  • возможность наследоваться от базовой логики, без необходимости нести с собой mxml-мусор.

Но, как и у любого другого шаблона, у CodeBehind есть не только плюсы, но и минусы:

  • увеличилось количество набираемого кода;
  • увеличилось количество файлов/классов для редактирования (что приводит к частому переключению между вкладками в IDE);
  • использование наследования вместо композиции, что ведет к увеличению иерархии наследования;
  • необходимость в предоставлении ссылок-заглушек при тестировании базовых классов;
  • возможно частичное нарушение инкапсуляции и наследования.

Другим вариантом реализации отделения логики от разметки является приём, называемый CodeFront (или code in front). Идея его (вы наверное и сами догадались) так же проста и кристальна, как и в случае с CodeBehind, и заключается в том, что сначала мы реализуем расположение компонентов, и только потом наполняем их жизнью (добавляем логику). Пример:

// BaseControlPanelView.mxml 
<?xml version="1.0"?> 
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:local="*" xmlns:layouts="spark.layouts.*" 
         xmlns:components="spark.components.*" xmlns:s="library://ns.adobe.com/flex/spark"> 
    <!-- 
        /** 
         * Внешний вид панели управления 
         * Created 18.04.2014 
         * Version 1.0 
         * Copyright (c) 2014 
         * @author ChessMax (www.chessmax.ru) 
         */ 
    --> 
 
 
    <s:layout> 
        <layouts:HorizontalLayout paddingLeft="5" paddingTop="5"/> 
    </s:layout> 
 
 
    <!-- Кнопка запуска --> 
    <components:Button id="startButton" label="start"/> 
 
 
    <!-- Кнопка остановки --> 
    <components:Button id="stopButton" label="stop"/> 
 
 
</s:Group> 
// ControlPanel.as 
public class ControlPanel extends BaseControlPanelView 
    { 
        public function ControlPanel() 
        { 
            super(); 
        } 
 
 
        /** 
         * @inheritDoc 
         */ 
        override protected function createChildren():void 
        { 
            super.createChildren(); 
 
 
            startButton.addEventListener(MouseEvent.CLICK, onStartButtonClicked); 
            stopButton .addEventListener(MouseEvent.CLICK, onStopButtonClicked); 
        } 
 
 
        /** 
         * Обработчик клика по кнопке старт 
         * @param e 
         */ 
        protected function onStartButtonClicked(e:MouseEvent):void 
        { 
            trace("Start"); 
        } 
 
 
        /** 
         * Обработчик клика по кнопке стоп 
         * @param e 
         */ 
        private function onStopButtonClicked(e:MouseEvent):void 
        { 
            trace("Stop"); 
        } 
    }

Используя CodeFront, нам больше нет необходимости описывать все необходимые переменные в классе, чтобы использовать их в логике. Так как мы наследуемся от mxml-разметки, то компилятор делает это за нас. Но теперь мы лишены возможности назначить обработчик события inline-внутри mxml-разметки, так как описан он будет только в наследнике. Также нет возможности полностью заменить layout получившегося компонента, по понятным причинам. Да и перенести логику в другой проект без layout-а теперь не получится. Возможно, поэтому этот вариант гораздо менее популярен, чем CodeBehind.

Заключение.

CodeBehind/CodeFront - архитектурный прием, который позволяет относительно легко сделать код чистым и структуированным, что  легко дает возможность модифицировать его в будущем. Хотя поначалу довольно непросто привыкнуть писать код так, и это сильно раздражает. Даже кажется, что мы делаем слишком много дополнительной работы. Но, как говорится, стоит только начать, а уж когда втянетесь… Становится легче абстрагировать логику от разметки. Гораздо легче наследоваться от чистых AS3 классов, нежели от MXML классов с необходимостью изменять layout. Попробуйте один из перечисленных приемов в своем проекте. И обязательно оставляйте комментарии о своем положительном/отрицательном использовании перечисленных техник.

Почитать:

Code Behind
Code behind in Flex and WPF
Flex and WPF: A comparison – Part 2b
Code-Behind and Flex 2.0 (Partial Classes)
Building components by using code behind
Creating components and enforcing separation of concerns with Flex
Best Practice: Code Behind versus MXML Script Blocks versus View Helper


2014-04-18

14:32:37, Flash-ripper.com
Александр Письменчук - Flash ActionScript 3 разработчик
Ищу постоянную работу в компании с полной занятостью
Мое резюме: 
Кто я:
ActionScript 3 разработчик. Flash занимаюсь с 12.2008 по наст. время (более 5 лет) 
На данный момент работаю на фриланс биржах
 
Чем я занимаюсь:
Программирование функционала flash/air компонентов, сайтов, интерактивов. Больше скажет портфолио.
Портфолио: http://fl.ru/
Все работы: http://www.weblancer.net/
 
Что я ищу:
Работу в г.Киеве. Достойную оплата, интересный проект (не игровой), слаженный коллектив, удобное рабочее время, бесплатные печеньки :). Плюсом будет считаться помощь при переезде или поиске жилья
 
Основные навыки: 
ActionScript, OOP, Air Desktop
Дополнительные навыки можно узнать по запросу
 
Достежения:
Интерактивы для Winston, Camel, Dirol, Vertu. Volvo, игры для FixiClub, Nestle
 
Знание языков:
Английский - начальный, Русский - продвинутый, Украинский - родной
 
Мои контакты можно посмотерть на сайте http://alexvoz.net/

 

Минимальная зарплата: 
$2000
Максимальная зарплата: 
$2500

13:17:21, Flash-ripper.com
Кефирам нужен человек в Киеве

Kefir Games (тюряга) ищет бандеровца девлида в Киеве для работы в центровом офисе. Нужно делать игры, отвечая за качество кода и архитектуры, пасти котов руководить программистами и работать с ТЗ от и до.

Требования:

  • Опыт в социальном AS3-геймдеве от 2 лет, Starling и Adobe AIR.
  • Знать оптимизацию графики и алгоритмов.
  • Практиковать ООП как стиль.
  • Уметь спрашивать и отвечать.
  • Работать с чужим кодом.
  • Собственные движки и библиотеки.

Компания дает хорошую зарплату и там есть куда расти

 
 

2014-04-15

14:39:56, Flash-ripper.com
Generic Animation Format и оптимизация Adobe AIR: записи докладов

12 апреля в Харькове прошел UAFPUG №46. Доклады были записаны на видео:

  1. Запись части блиц-докладов и описание Generic Animation Format от Вадима Митина из GAFMedia.
  2. Запись доклада "Оптимизация Adobe AIR Mobile" от Антона Азарова из Харькова.

Важно: по горячим следам Антон сделал разбор полетов к собственному докладу про AIR. Также во время доклада мы долго обсуждали оптимизацию списков в Adobe AIR, и один из наших онлайн-слушателей, Виталий Кононец прислал ссылку на свой блог по темеОптимизация списков в мобильном приложении. Спасибо, Виталий!

Фото с UAFPUG-46:

Вадим Митин вкратце рассказывает о разработке Generic Animation Format:

Мини-доклад Вадима Митина

Нас было немного: 

Но интересно:

Александр Мостовой

Баги Flash IDE достали!

На встрече мы собрали список самых назойливых багов Adobe Flash IDE. Причешем его и устроим витруальный майдан Адобу. Присылайте свои жалобы на Flash в комменты или на мою почту rostislav.siryk.

Спасибо всем, кто пришел и был с нами онлайн!

Гду будет следующий фпуг?

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

Люблю вас!
Рост

 


Предыдущие 30 | Следующие 30