SVG: Посадка на Луну и целевое программирование

Демонстрация SVG с лунным модулем, управляемым с помощью целеориентированного программирования.

На этом сильно стилизованном лунном ландшафте лунный модуль начинает спуск по взлетно-посадочной полосе, показанной зеленым цветом. В этой демонстрации показано, как анимировать объекты в сцене с помощью SVG, используя при этом простоту ориентации цели для определения цели и как ее достичь.

Форму под анимацией можно использовать для выбора начального угла модуля и его положения относительно подиума. Нажмите кнопку Отправить (Submit), чтобы обновить положение модуля, и кнопку Земля (Land), чтобы начать спуск.

Угол (0-180) X (0-500) Y (0-400)

Как это работает...

Лунный модуль и планета Земля - это SVG-файлы, которые загружаются в страницу и добавляются в сцену. Мы загружаем модуль в iframe, потому что хотим расположить его динамически в сцене.

<div style="display:none">
<iframe id="ilander" width="100" height="100" src="code/lunar-lander.svg"></iframe>
</div>

Мы создаем сцену, представляя лунную поверхность и взлетно-посадочную полосу серыми и зелеными прямоугольниками, а к Земле добавляется тег <image>:

<svg id="moon" width="720" height="600">
<rect id="ground" x="0" y="550" width="720" height="50" style="fill:rgb(245,245,245);" />
<rect id="airport" x="300" y="542" width="160" height="8" style="fill:rgb(0,128,0);" /> <image width="518" height="518" transform="translate(500, 60) scale(.2)" xlink:href="code/globe.svg" />
</svg>

Изображение Земли масштабируется до 1/5 с помощью свойства scale и позиционируется с помощью translate.

Затем добавляем themodule image, загруженный в iframe :

function getSVG(oID, gID)
{ 
var ifr = document.getElementById(oID); 
var graphics = ifr.contentWindow || ifr.contentDocument; 
return graphics.document.getElementById(gID);
}

function landscape()
{ 
var moon = document.getElementById("moon"); 

lander = getSVG("ilander", "layer1"); 
lander.setAttribute("transform", "translate(100,200) scale(0.1) rotate(45 50 50)"); 
moon.appendChild(lander);
}

Функция getSVG извлекает изображения, загруженные тегами <iframe>, а функция landscape размещает эти изображения в сцене. Все это подробно объясняется в статье Introduction to SVG: Programmatic Drawing Surface.

Нам нужна функция для перемещения модуля; это роль moveLander ()

function moveLander() {
lander.setAttribute("transform", "translate(" + x + "," + y + ") scale(0.1) rotate(" + angle + " 50 50)");
}

Мы изменяем значение translate свойства transform с помощью координат и угла модуля. Для его перемещения мы определяем цели и способы их достижения. Существует три цели: угол модуля, его положение по оси x и положение по оси y.

Вот код в Скриптоле.

void land()
to angle = 0 for 30, 50
if angle > 0 ? angle - 1
moveLander()
/to

to ((x >= 300) and (x <= 350)) for 30, 20
if x < 300 ? x + 1
if x > 350 ? x - 1
moveLander()
/to

to y = 445 for 30, 20
if y < 445 ? y + 1
moveLander()
/to

return

The scriptol to construct defines each condition to be met. Here, these are the x position between 300 and 350 for the track, y of 445 for the zero height of the module, and its orientation, which must be 0. The maximum delay allowed is 30 seconds. The second number is the delay between two moves.

This is converted to this JavaScript code:

function land()
{
scriptol.goal(function() { return(angle===0)},30*1000,function(){
if(angle>0) { angle-=1; }
moveLander();
}, 50); 

scriptol.goal(function() { return(((x>=300)&&(x<=350)))},30*1000,function(){ 
if(x<300) { x+=1; } 
if(x>350) { x-=1; } 
moveLander(); 
},20); 

scriptol.goal(function() { return(y===445)},30*1000,function(){ 
if(y<445) { y+=1; } 
moveLander(); 
},20);
}

You can download the full source code of the demo with the scriptolbrowser.js library and SVG files:

The landing.html file is generated from the landing.sol file with the command: solj -w landing.