Array  break  case  catch  const  continue  default  Date  do Error  else  Function  false  finally  for

function  if  in  instanceof  Infinity  Math  NaN  Number  new  null  Object  Promise  prototype  RegExp

return  String  switch  this  then  throw  try  true  undefined  var  with  while
	
alert(s)
appendChild(tagName)
fillRect()
pow(base, n)
sin(radians)
cos(radians)
random()
isNaN()
test()
sqrt(n)
prompt(s)
parseInt(s) parseFloat(s)
floor(f) 
ceil(f)
charAt(n)
indexOf(substring, offset)
substring(start, end)
replace(pattern, replacement)
toLowerCase(s)
toUpperCase(s)
abs(n)
splice(start, length, newItem1, newItem2, ...)
split(pattern, limit)
toString()
createElement(tagName)

getElementById(id)

getContext(contextType)

removeChild(domElement)

strokeText(text, x, y)

fillText(text, x, y)

measureText(text)

setItem(key, value)

join(delimeter)

round(floatNumber)
	

Программирование 2D графики

Все рассмотренные до сих пор примеры почти не зависят от среды, в которой выполняется JavaScript. Если вам вдруг пришла бы в голову идея запустить эти программки например как сценарий WScript для windows, от вас бы потребовалось только определить четыре функции: alert, prompt, writeln и readln так, чтобы они принимали от пользователя значение или выводили его куда-нибудь. Решения задач по программированию 2D графики будут привязаны к браузерному JavaScript гораздо сильнее. Я буду использовать элемент DOM canvas (холст), но не собираюсь вдаваться в подробности, что такое DOM. Об этом в сети великое множество информации, а я здесь осваиваю азы программирования и информация о DOM, как мне кажется, к азам программирования отношение имеет мало. DOM элемент canvas хорош в контексте освоения азов программирования тем, что имеет многие функции, которые очень похожи на соответствующие функции для отрисовки графических примитивов в других языках программирования, например C++ или Pascal.

Как добавить холст, на котором будем рисовать

Перед тем, как пытаться программировать графику в браузерном JavaScript, надо получить контекст существующего на веб-странице элемента canvas (canvas буквально - холст). В нашем случае на странице такого элемента нет вообще, но мы можем создать новый, чтобы получить его контекст. Контекст будет получен в виде объекта. А у этого объекта уже будут доступны множество методов и свойств, описание которых вы можете видеть на сайте w3schools.com

Вы можете выполнить на нашем сайте этот код:

function createCanvasExample() {
	"use strict"
	var canvas = document.createElement('canvas'),       //Создали "холст"
		context, 
		appConsole = document.getElementById('console'); //наше "окошко" вывода приложения
	canvas.width  = 300;               //ширина холста
	canvas.height = 150;               //высота холста
	appConsole.innerHTML = '';         //удаляем из окна вывода приложения все, что там может быть
	appConsole.appendChild(canvas);    //добавляем в окно вывода приложения наш холст, можно начинать рисовать
	
	context = canvas.getContext("2d");   //Получить контекст рисования
	context.fillStyle = "#FF0000";       //Стиль заливки - красный. Проще говоря, будем рисовать красную фигуру.
	//Рисуем прямоугольник с координатами левого верхнего угла x = 10 и y = 10 
	// пикселей и шириной 100 и 110 пикселей
	context.fillRect(10, 10, 100, 110);  
}

В этом коде много нового. Объект document доступен в JavaScript программе, которая выполняется в браузере, у него есть свои свойства и методы. Меня сейчас интересуют два из них. Первый, createElement служит для того, чтобы создать новый DOM элемент. Так как мне нужен холст, я передаю этому методу как аргумент строку 'canvas'. Полученный в результате вызова объект холста позволяет менять его свойства. Я изменил свойства ширина (width) и высота (height), чтобы иметь возможность видеть то, что я буду рисовать на этом холсте.

Окошко, в котором мы видим вывод наших примеров имеет идентификатор "console". Используя метод объекта document getElementById мы можем получить переменную, с помощью которой можем взаимодействовать с ним. Первым делом я устанавливаю свойство innerHTML равным пустой строке. Это уничтожит все содержимое, которое может быть в этом окошке.

Затем вызываю метод appendChild, который есть у всех DOM элементов-контейнеров, в том числе и у того, на который ссылается наша переменная appConsole. На этом необходимые манипуляции с DOM заканчиваются, элемент холст создан, можно начинать рисование. В этом примере я просто вывожу прямоугольник, чтобы убедится, что все работает.

Для начала мне надо получить контекст рисования. Я делаю это с помощью функции getContext, передавая ей как аргумент строку "2d", чтобы указать, что я буду работать с 2D графикой.

Далее я устанавливаю свойство объекта контекста fillStyle в цвет, который выбрал для цвета прямоугольника и отрисовываю его вызвав метод fillRect.

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

function createCanvasExample() {
	"use strict"
	var canvas = document.createElement('canvas'),       //Создали "холст"
		context, 
		appConsole = document.getElementById('console'); //наше "окошко" вывода приложения
	canvas.width  = appConsole.offsetWidth;               //ширина холста
	canvas.height = appConsole.offsetHeight;               //высота холста
	appConsole.innerHTML = '';         //удаляем из окна вывода приложения все, что там может быть
	appConsole.appendChild(canvas);    //добавляем в окно вывода приложения наш холст, можно начинать рисовать
	
	context = canvas.getContext("2d");   //Получить контекст рисования
	context.fillStyle = "#FF0000";       //Стиль заливки - красный. Проще говоря, будем рисовать красную фигуру.
	//Рисуем прямоугольник с координатами левого верхнего угла x = 10 и y = 10 
	// пикселей и шириной 100 и 110 пикселей
	context.fillRect(0, 0, canvas.width, canvas.height); 
}

Здесь я просто заменил числа значениями ширины и высоты окошка консоли вывода приложения, получив их значения, хранящиеся в свойствах offsetWidth и offsetHeight DOM элемента.

Если надо развернуть ваше графическое приложение на весь экран, можно использовать код:

function createCanvasExample() {
	"use strict"
	var canvas = document.createElement('canvas'),       //Создали "холст"
		context,
		i, firstTextY, text, sz;
	canvas.width  = screen.width;               //ширина холста
	canvas.height = screen.height;              //высота холста
	
	document.body.appendChild(canvas); //добавляем на страницу наш холст, можно начинать рисовать
	//делаем холст "ближе к нам", чтобы он перекрыл все остальное на странице
	canvas.style.zIndex = 5;        
	canvas.style.position = 'absolute';
	canvas.style.top = '0px';
	canvas.style.left = '0px';
	
	canvas.onclick = function () { //при клике удаляем его
		document.body.removeChild(canvas);
	}
	context = canvas.getContext("2d");   //Получить контекст рисования
	context.fillStyle = "#00AA00";       //Стиль заливки - темно-зеленый
	//Рисуем прямоугольник на весь холст
	
	context.fillRect(0, 0, canvas.width, canvas.height);
	context.strokeStyle = '#ffffff';
	context.font = '25px Geneva';
	text = 'Нажмите F11 для перехода в полноэкранный режим',
		firstTextY = Math.round(screen.height / 2);
	context.strokeText(text, Math.round(screen.width / 2 - context.measureText(text).width / 2),firstTextY);
	context.font = '14px Geneva';
	context.fillStyle = '#FFFF00';
	text = 'Кликните для закрытия этого зеленого фона!';
	context.fillText(text, Math.round(screen.width / 2 - context.measureText(text).width / 2),firstTextY + 30);
}

В отличии от предыдущего примера я использовал объект screen для того, чтобы получить ширину и высоту экрана и присвоил эти значения в свойства width и height элемента canvas. Еще одно отличие в том, что созданный элемент canvas добавляется как потомок не DOM элементу который показывает вывод приложения, а элементу DOM документа body, в котором обычно находится все содержимое веб-страницы.

Строки 11 - 14 служат для того, чтобы поместить наш элемент canvas поверх всего остального содержимого страницы, интересующимся подробностями советую погуглить статьи и учебники по css.

Далее, назначаем для обработки клика по холсту анонимную функцию. В ней с помощью метода removeChild удаляем наш холст из документа.

Помимо прямоугольника, на этот раз зеленого, выводим на холсте две надписи разными стилями и цветами. Используем свойства контекста рисования font, strokeStyle и fillStyle для определения размера, семейства и цвета шрифта. После того, как эти параметры заданы, мы можем узнать ширину будущей надписи, хотя она еще не выведена. Для этого используется метод measureText, возвращающая объект, у которого есть свойство width, содержащее ширину текста. Сам текст выводится с помощью методов strokeText и fillText, второй и третий аргументы методов определяют x и y координаты левого верхнего угла надписей.

Я решил не ограничивать себя и использовать весь экран при решении примеров, связанных с графикой. Поэтому стоит оформить этот код в виде функции, так как он сравнительно объемен. При решении примера в коде будет только вызов функции createFullScreenContext.

Конечно, fullScreen здесь достаточно условен, так как пользователь будет вынужден переводить браузер в полноэкранный режим "вручную" нажимая F11, но перевести окно браузера в полноэкранный режим с помощью одного только JavaScript если я не ошибаюсь, нельзя.
function createCanvasExample() {
	"use strict"
	function createFullScreenContext(color, parentElement, zIndex) {
		if (!zIndex) {
			zIndex = 5;  //значение по умолчанию
		}
		if (!color) {     //Стиль заливки по умолчанию - темно-зеленый
			color = '#00AA00';
		}
		if (!parentElement) {
			parentElement = document.body;  //значение по умолчанию
		}
	    var canvas = document.createElement('canvas'),       //Создали "холст"
		    context,
		    i, firstTextY, text, sz;
	        canvas.width  = screen.width;               //ширина холста
	        canvas.height = screen.height;              //высота холста
	
		parentElement.appendChild(canvas); //добавляем на страницу наш холст, можно начинать рисовать
		//делаем холст "ближе к нам", чтобы он перекрыл все остальное на странице
		canvas.style.zIndex = zIndex;
		canvas.style.position = 'absolute';
		canvas.style.top = '0px';
		canvas.style.left = '0px';
	
		context = canvas.getContext("2d");   //Получить контекст рисования
		context.fillStyle = color;  
		//Рисуем прямоугольник на весь холст
		context.fillRect(0, 0, canvas.width, canvas.height);
		return {context:context, canvas:canvas};
	}
	var _2d = createFullScreenContext();
	_2d.canvas.onclick = function() {
		document.body.removeChild(_2d.canvas);
	}
}

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

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

Первая задача

Создать окно в рамке на фоне, заполненном псевдографическим символом #178 зеленого цвета, с текстом из файла. По клавишам управления курсором выполнять скроллинг текста в окне на одну строку вверх или вниз.

Замена текстовым файлам

Здесь у нас небольшая загвоздка: браузерный JavaScript не может работать с текстом из файла, расположенного на вашем компьютере. Однако, некоторая альтернатива у нас есть. Мы не можем с помощью браузерного JavaScript сохранить текст в любом файле на нашем жестком диске (или прочитать из него текст), но мы можем сохранить его в локальном хранилище браузера. Современные браузеры позволяют хранить до десяти мегабайт для каждого сайта в хранилище, Internet Explorer до пяти мегабайт. Доступ к хранилищу возможен через объект localStorage. Используя метод объекта setItem можно сохранить текст под определенным именем, это вобщем-то напоминает работу с текстовыми файлами. Существенная разница заключается в том, что доступ к содержимому такого "файла" возможен только из того браузера, в котором вы его создаете: если вы сохранили текст сказки "Хоббит" используя localStorage.setItem в InternetExplorer, то вызвав localStorage.getItem в Firefox вы не сможете его прочитать. Вы не можете копировать этот "файл", в общем замена настоящим файлам слабоватая, но вполне подходящая для нашей задачи.

Пример создания "псевдофайла" опишу в прокомментированом фрагменте кода далее, добавив при необходимости более развернутые комментарии после описания.

function pseudoFileExample() {
	var appConsole = document.getElementById('console'), //наше "окошко" вывода приложения
		textInput  = document.createElement('textarea'), //Создали элемент для ввода многострочного текста
		nameInput  = document.createElement('input'),    //Создали элемент для ввода однострочного текста
		saveButton = document.createElement('button');   //Создали кнопку "Сохранить"
		saveButtonWrap = document.createElement('p');    //Создали обертку для кнопки "Сохранить"
	textInput.style = "width:99%; resize:none; height:440px;"; //Размеры поля ввода
	nameInput.style = "width:99%";
	saveButtonWrap.style = "text-align:right;";          //Кнопка будет смещена к правому краю
	saveButton.innerHTML = "Сохранить";      //Написали на ней Сохранить
	appConsole.innerHTML = '';               // Очистили DOM элемент, в который будем добавлять наши элементы ввода
	//Добавили наши элементы
	appConsole.appendChild(textInput);       
	appConsole.appendChild(nameInput);
	appConsole.appendChild(saveButtonWrap); 
	saveButtonWrap.appendChild(saveButton); //Кнопку добавили в "обертку", чтобы выровнять ее по правому краю
	
	//пользовательский интерфейс готов, добавим логики
	saveButton.onclick = function() {
		if (nameInput.value && textInput.value) {
			localStorage.setItem(nameInput.value, textInput.value);
		}
	}
}

Прежде, чем сохранить какой-то текст в такой "файл", надо позаботиться о том, чтобы можно было ввести этот текст. К счастью, браузерный JavaScript позволяет создавать на веб-странице всевозможные элементы ввода значений, среди них многострочные и однострочные поля ввода текста и кнопки. С помощью метода createElement я создаю эти элементы, а также создаю элемент- контейнер (с помощью кода createElement('p')). Он мне нужен для того, чтобы сместить кнопку к правому краю, это привычно большинству пользователей компьютеров.

Далее я использую свойство (атрибут) style созданных элементов для того, чтобы задать им размер. Для многострочного поля ввода текста я задал ширину 99% и высоту 420 пикселей, а заодно запретил изменять размеры поля пользователю. Я использовал правила CSS, если вас интересуют все возможности, которые можно получить используя атрибут style, можете воспользоваться поиском и найти себе подходящий справочник по CSS3 или книгу.

Обычно кнопки в подобных формах ввода информации расположены по правому краю. Я использую правило CSS "text-align:right" чтобы содержимое контейнера p, на который ссылается переменная saveButtonWrapper было выровнено по правому краю.

Вас может удивить, что свойство innerHTML используется у одного элемента для создания на нем надписи, а у второго для удаления всего содержимого. Дело в том, что в результате работы метода appendChild, применённого к тому или иному DOM элементу внутри него создается текстовое содержимое - HTML код. Например, вместо:

	var saveButtonWrap = document.createElement('p');
	saveButtonWrap.style = "text-align:right;";
	// ...
	appConsole.appendChild(saveButtonWrap);

можно было бы написать:

	appConsole.innerHTML += '<p style="text-align:right"></p>';

я не делаю этого, так как не хочу касаться темы HTML, чтобы не "распыляться" больше чем необходимо. Однако, обратите внимание, что если вы изучите HTML, вы можете писать более коротко!

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

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

Сохраните какой-нибудь текст с именем my_content. Будем использовать его при решении задачи.

Решение первой задачи

Напомню текст задачи: создать окно в рамке на фоне, заполненном псевдографическим символом #178 зеленого цвета, с текстом из файла. По клавишам управления курсором выполнять скроллинг текста в окне на одну строку вверх или вниз.

Если вы уже успели заинтересоватсья html и css, вам возможно уже известно, что эту задачу можно легко и просто решить их средствами. Однако, здесь меня интересует программирование графики, поэтому я решу эту задачу так, словно никакого html и css не сущетствует.
function window2DExample() {
	var _2d = createFullScreenContext("#FFFFFF"), 
		WIDTH = 640,       //ширина окна с текстом
		HEIGHT = 480,      //высота окна с текстом
		TOP_BORDER_H = 30, //высота верхней рамки окна с текстом
		BORDER = 5,        //толщина рамки окна с текстом
		BORDER_COLOR = "#AA0000", //цвет рамки окна
		WND_BG_COLOR = "#00F0F0", //цвет фона окна
		ctx = _2d.context,   //контекст рисования
		BG_COLOR =  "#00AA00",    //фон холста
		ch = String.fromCharCode(178),//символ, который используется в качестве фона
		SC_WIDTH = screen.width,             //ширина экрана
		SC_HEIGHT = screen.height,			 //высота экрана
		s, i, j, k, y, verticalLimit,		 
		textFontSize = 12,					 //размер шрифта в пикселях
		verticalStart = textFontSize;
		
	//Залить фон
	function drawBg() {
		ctx.fillStyle = BG_COLOR;	
		ctx.font = "12px Geneva";
		//определить, сколько символов поместится в строке в ширину
		s = new Array(101).join(ch);
		while (ctx.measureText(s).width < SC_WIDTH) {
			s += ch;
		}
		//сколько надо строк, чтобы залить фон символом
		verticalLimit = Math.ceil(SC_HEIGHT / textFontSize), y = textFontSize;
		//залить фон символом
		while (y < SC_WIDTH) {
			ctx.fillText(s, 0, y);
			y += textFontSize;
		}
	}
	drawBg();
	//вывести текст
	function _drawText(ctx, _x, _y, _w, _h) {
		var text = localStorage.getItem('my_content'), caretX = _x, caretY = verticalStart + _y, needNextStr = false;
		if (!text) {
			text = 'Надо сохранить в хранилище текст с именем "my_content" воспользовавшись примером "Замена текстовым файлам"';
		}
		ctx.fillStyle = "#FF0000";	
		ctx.font = "12px Geneva";
		s = '';
		//выводим текст
		for (i = 0; i < text.length; i++) {
			s += text.charAt(i);
			if (ctx.measureText(s).width > _w || text.charAt(i) == "\n") {
				s = s.substring(0, s.length - 1);
				//alert(s);
				if (caretY > _y) {
					ctx.fillText(s, caretX, caretY);
				}
				caretY += textFontSize;
				s = text.charAt(i);
			}
			if (caretY > _y + _h) {
				//alert(i);
				return;
			}
		}
		if (s.length && caretY > _y) {
			ctx.fillText(s, caretX, caretY);
		}
	}
	//отрисовать "окно"
	function drawWnd() {
		var w = Math.round( (SC_WIDTH - WIDTH) / 2), h = Math.round( (SC_HEIGHT - HEIGHT) / 2);
		ctx.fillStyle = BORDER_COLOR;
		ctx.fillRect(w, h, WIDTH, HEIGHT );
		ctx.fillStyle = WND_BG_COLOR;
		ctx.fillRect(w + BORDER, h +  TOP_BORDER_H, WIDTH - 2 * BORDER, HEIGHT - TOP_BORDER_H - BORDER);
		_drawText(ctx, w + BORDER, h +  TOP_BORDER_H, WIDTH - 2 * BORDER, HEIGHT - TOP_BORDER_H - BORDER);
	}
	drawWnd();
	
	function moveText(event) {
		if (event.keyCode != 38 && event.keyCode != 40) {
			return true;
		}
		if (event.keyCode == 38) {
			verticalStart += textFontSize;
		}
		if (event.keyCode == 40) {
			verticalStart -= textFontSize;
		}
		ctx.fillStyle  = "#ffffff";
		ctx.fillRect(0, 0, SC_WIDTH, SC_HEIGHT);
		drawBg();
		drawWnd();
		return false;
	}
	
	document.body.onkeydown = moveText;
	
	_2d.canvas.onclick = function() {
		document.body.removeChild(_2d.canvas);
		document.body.onkeydown = null;
	}
	
	//==================================================================
	
	//Вспомогательная функция для создания холста на весь экран
	function createFullScreenContext(color, parentElement, zIndex) {
		if (!zIndex) {
			zIndex = 5;  //значение по умолчанию
		}
		if (!color) {     //Стиль заливки по умолчанию - темно-зеленый
			color = '#00AA00';
		}
		if (!parentElement) {
			parentElement = document.body;  //значение по умолчанию
		}
	    var canvas = document.createElement('canvas'),       //Создали "холст"
		    context,
		    i, firstTextY, text, sz;
	        canvas.width  = screen.width;               //ширина холста
	        canvas.height = screen.height;              //высота холста
	
		parentElement.appendChild(canvas); //добавляем на страницу наш холст, можно начинать рисовать
		//делаем холст "ближе к нам", чтобы он перекрыл все остальное на странице
		canvas.style.zIndex = zIndex;
		canvas.style.position = 'fixed';
		canvas.style.top = '0px';
		canvas.style.left = '0px';
	
		context = canvas.getContext("2d");   //Получить контекст рисования
		context.fillStyle = color;  
		//Рисуем прямоугольник на весь холст
		context.fillRect(0, 0, canvas.width, canvas.height);
		return {context:context, canvas:canvas};
	}
	
	//==================================================================
	
}

В общем-то при решении задачи не использовано ничего нового. Для отрисовки окна я использовал те же функции что и в примерах этой статьи выше - fillRect и fillText. Для получения текста, выводимого в окне я использую метод localStorage.getItem. Чтобы обеспечить прокрутку текста на одну строку я назначил обработку событий нажатия клавиш клавиатуры "вверх" и "вниз" функции moveText, которая перерисовывает все после кажлого нажатия кнопки, смещая текст. Я использую переменную verticalStart чтобы запоминать смещение от начала текста, и я вывожу его только когда очередная строка займет место ниже чем область окна. Функция moveText возвращает false если нажата кнопка "вверх" или "вниз". Это сделано для того, чтобы браузер не прокручивал полосу прокрутки справа, которую вы возможно видите, если работаете в firefox. Но так как необходимо, чтобы браузер нормально реагировал на нажатие этих клавиш после того, как приложение закрыто, в обработке клика на холсте я присваиваю null заместо функции moveText. Можете попробовать не делать этого - браузер перестанет реагировать на нажатия клавишь "вверх" и "вниз" пока вы не обновите страницу.

Тест на новые слова

  • Несохраненный_файл.js
Строка: 0, Символ: 0

  • {name}
  • У вас пока нет файлов
 

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

 

Правильно!

Не забывайте переодически проходить этот тест по мере чтения новых статей.

 

Ошибка!

 

Осталось: 0 сек.

Health:

Score:

 

Что значит:

 

 

 


Информация

Загрузите файл с исходным кодом программы на языке яваскрипт.

Файл должен содержать одну главную функцию, имя которой должно совпадать с именем файла.

Например, файл называется task1.js, имя главной функции должно быть task1.

Все остальные функции должны быть определены внутри главной.

*

Информация

Сохраняемый код должен содержать одну главную функцию.

Например:

function myFirstProgram() {
	//Тут все остальное, включая вспомогательные функции
}
					




Простой пароль
Пароли не совпадают