Можно ли рисовать на png-картинке при помощи JSCRIPT

Обсуждение вопросов клиентского программирования.

Модератор: Duncon

Виталик
Сообщения: 33
Зарегистрирован: 03 май 2006, 11:52

Есть такая задача: карта города в формате PNG, нужно на ней векторно соединить несколько точек, проще говоря - нарисовать маршрут движения по городу.

Вопрос: можно ли это сделать при помощи JSCRIPT ? Если можно то как?
Аватара пользователя
Duncon
Сообщения: 2085
Зарегистрирован: 10 окт 2004, 14:11
Откуда: Питер
Контактная информация:

Непомню, помоему нет.. Но вот PHP точно может...
[syntax=Delphi] [/syntax]
Аватара пользователя
Oscar
Сообщения: 963
Зарегистрирован: 29 май 2004, 13:44
Откуда: Мюнхен (рожден в Киеве)
Контактная информация:

Виталик,

значит так, тут:
http://www.kevlindev.com/gui/utilities/js_png/
есть библиотека.

создаёт PNG на JS и рисует, но:

1. работы структуры:

Код: Выделить всё

	var image = document.createElement("IMG");
	image.src = "data:image/png;base64,\n" + png.getBase64();
под ИЕ мне добиться не удалось.

2. прикрутить библиотеку к уже существующей PNG - тоже не получилось,
что можно было бы обойти использовав прозрачность, но

3. Картинка прозрачной у меня не получается :-D

В общем, я бы не советовал так делать.

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

Но если хочется динамической странички ... и таки нужен JavaScript, могу предложить следующий вариант:

Код: Выделить всё

<html>
<head>
<title>test</title>
<script type="text/javascript">

function getPosition(node) {

	var curleft = 0;
	var curtop = 0;

	if (node.offsetParent) {

		while (node.offsetParent) {
			curleft += node.offsetLeft
			curtop += node.offsetTop
			node = node.offsetParent;
		}

	} else if (node.x) {

		curleft += node.x;
		curtop += node.y;

	}


	var toReturn = new Object;
	toReturn.left = curleft;
	toReturn.top = curtop;
	return toReturn;
}

function drawHorizontalLine(x1, y1, x2, y2) {

	for(var x = x1; x < x2; x++) {

		var y = (x - x1)/(x2 - x1)*(y2 - y1) + y1;

		var image = document.createElement("IMG");

		image.style.position = "absolute";
	
		image.style.left = x;
		image.style.top = y;

		image.src = "point.gif";

		root.appendChild(image);

	}

}

function drawVerticalLine(x1, y1, x2, y2) {

	for(var y = y1; y < y2; y++) {

		var x = (y - y1)/(y2 - y1)*(x2 - x1) + x1;

		var image = document.createElement("IMG");

		image.style.position = "absolute";
	
		image.style.left = x;
		image.style.top = y;

		image.src = "point.gif";

		root.appendChild(image);

	}

}

var map = null;
var root = null;

var pathDrawn = 0;

function init() {

	map = document.getElementById("map");
	root = document.getElementById("root");

}

function drawPath() {

	var pos = getPosition(root);

	switch(pathDrawn) {

		case 0:
			drawHorizontalLine(50 + pos.left, 34 + pos.top, 154 + pos.left, 36 + pos.top);
			break;

		case 1:
			drawVerticalLine(50 + pos.left, 34 + pos.top, 38 + pos.left, 130 + pos.top);
			break;

		case 2:
			drawHorizontalLine(38 + pos.left, 130 + pos.top, 114 + pos.left, 128 + pos.top);
			break;

		case 3:
			drawVerticalLine(154 + pos.left, 36 + pos.top, 114 + pos.left, 128 + pos.top);

	}
	
	pathDrawn++;

}

function clearMap() {
	while(root.firstChild != null) {
		root.removeChild(root.firstChild);
	}
	root.appendChild(map);
	pathDrawn = 0;
}
</script>
</head>
<body onLoad="init();">

	<div style="background-color: #000000; font-size: 0; padding: 1px; width: 200px; height: 200px;">
		<div id="root">
			[img]map.gif[/img]
		</div>
	</div>

	<input type="button" value="Draw" onClick="drawPath();">
	<input type="button" value="Clear" onClick="clearMap();">
</body>
</html>
Пример можно посмотреть тут:
http://home.in.tum.de/skrypnyo/developing/paint.html

Идея:
имея gif 1x1 определённого цвета (можно разных цветов, чтоб пути были разные) добавляем HTML элементы <img>, позиционируя их абсолютно.

Должно работать в любом уважающем себя (поддерживающем DOM) браузере.
Проверено на ФФ 1.5, ИЕ 6, Опера 8.5
Виталик
Сообщения: 33
Зарегистрирован: 03 май 2006, 11:52

Спасибо Oscar, беру предложенный пример на вооружение (:
Аватара пользователя
Oscar
Сообщения: 963
Зарегистрирован: 29 май 2004, 13:44
Откуда: Мюнхен (рожден в Киеве)
Контактная информация:

Виталик,

с той библиотекой немного разобрался.

Для начала:
http://www.elf.org/pnglets/ писал(а):There are three possible ways of inserting JavaScript generated graphic data into a web page, none of which work with Internet Explorer
Для ФФ - вот код:

Код: Выделить всё

<html>
<head>
<title>using js png</title>

<script src="js_png.js"></script>

<script type="text/javascript">

PngIndex.prototype.drawLine = function&#40]map.png[/img]
</body>
</html>
В этом случае нужен лишь один новый <img>
http://home.in.tum.de/~skrypnyo/developing/js_png.html

в ИЕ не работает.

----

А вообще, пожалуй, что идеальным, всё же, была бы серверная сторона.
Создаёшь два <img>, один - карта, второй - прозначный (позиционируешь его поверх)

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

Пример:

document.getElementById('transparent').src = "path.php?x1=10&y1=10&x1=100&y2=10";

Серверная сторона рисует прозрачную картинку с линией.
Виталик
Сообщения: 33
Зарегистрирован: 03 май 2006, 11:52

Oscar,
А вообще, пожалуй, что идеальным, всё же, была бы серверная сторона.
Создаёшь два <img>, один - карта, второй - прозначный (позиционируешь его поверх)
Проблема в том, что когда на карту накладываю прозрачный рисунок, то карта всегда накладывается поверх прозрачного фона, так как сама карта грузится с другого сервера а прозрачный фон естественно на локальном сервере.
Аватара пользователя
Oscar
Сообщения: 963
Зарегистрирован: 29 май 2004, 13:44
Откуда: Мюнхен (рожден в Киеве)
Контактная информация:

Виталик,

прозрачный фон нужно сделать:

[img]transparent.gif[/img]

z-index - это "глубина" страницы
у кого он больше, тот и будет сверху.

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

чтобы узнать положение карты (если она, как я полагаю, не абсолютно размещена), можно использовать функцию getPosition(node) из моего первого поста,
запихнув её в init, который будет вызываться при <body onLoad="init();">
Виталик
Сообщения: 33
Зарегистрирован: 03 май 2006, 11:52

Oscar,

вообщем чтобы наложить картинку на картинку и при этом разместить их в ячейке таблицы я сделал так:

<table border=1>
<tr>
<td>
<div id='Layer1' style='position:absolute;z-index:1;'>
[img]1.png[/img]
</div>

<div id='Layer2' style='position:static;z-index:2;'>
[img]2.png[/img]
</div>
</td>
</tr>
</table>

как в таком случае сделать чтобы '2.png' была выше '1.png' ?
Аватара пользователя
Oscar
Сообщения: 963
Зарегистрирован: 29 май 2004, 13:44
Откуда: Мюнхен (рожден в Киеве)
Контактная информация:

Виталик, вторая должна быть "position: absolute" !
Для первой это вовсе не обязательно.
Аватара пользователя
Oscar
Сообщения: 963
Зарегистрирован: 29 май 2004, 13:44
Откуда: Мюнхен (рожден в Киеве)
Контактная информация:

Код: Выделить всё

<script>
function getPosition(node) {

   var curleft = 0;
   var curtop = 0;

   if (node.offsetParent) {

      while (node.offsetParent) {
         curleft += node.offsetLeft
         curtop += node.offsetTop
         node = node.offsetParent;
      }

   } else if (node.x) {

      curleft += node.x;
      curtop += node.y;

   }


   var toReturn = new Object;
   toReturn.left = curleft;
   toReturn.top = curtop;
   return toReturn;
} 

function init() {

	var map = document.getElementById('map');
	var pos = getPosition(map);
	var transparent = document.getElementById('transparent');
	transparent.style.left = pos.left;
	transparent.style.top = pos.top;

}
</script>
<body onload="init();">



<table border=1>
<tr>
<td>
<div id="map">
[img]1.gif[/img]
</div>

<div id='transparent' style='position:absolute;z-index:1;'>
[img]2.gif[/img]
</div>
</td>
</tr>
</table>
Ответить