воскресенье, 17 февраля 2008 г.

Выпуск 4 - Слайдинг

Слайдинг - это анимированное движение элементов или эффект скроллинга. Используя циклические (или итеративные) функции, и продвигая цровни на малое количество пикселей, можно создать довольно привлекательные анимационные эффекты.

Идея такова:

block.xpos += 5
block.left = block.xpos

То есть мы сдвигаем элемент на 5 пкселей вправо. А если мы оформим это как цикл:

function slide() {
if (block.xpos < 300) {
block.xpos += 5
block.left = block.xpos
setTimeout("slide()",30)
}
}

Здесь if нужен, чтобы остановить анимацию. В данном случае остановка произойдёт, если х-координата больше либо равна 300. Функция setTimeout() - это и есть то, что анимирует передвижение. Не сложно понять, что она воспроизводит выполнение функции slide() через 30 миллисекунд.

Теперь напишем скрипт:

function slide() {
if (block.xpos < 300) {
block.xpos += 5
block.left = block.xpos
setTimeout("slide()",30)
}
}

function restart() {
block.xpos = 50
block.left = block.xpos
}

function moveTo(obj,x,y) {
obj.xpos = x
obj.ypos = y
obj.left = obj.xpos
obj.top = obj.ypos
}

...и HTML-код:

<a href="javascript:slide()">slide</a> - <a href="javascript:moveTo(block,50,100)">restart</a>
<div id="blockDiv" style=""LEFT:" 50px; WIDTH: 30px; CLIP: rect(0px 30px 30px 0px); POSITION: absolute; TOP: 100px; HEIGHT: 30px; BACKGROUND-COLOR: red; layer-background-color: red"></div>

Мы получим следующую картинку:

slide - restart

См. на примере 1.

Движение по диагонали предполагает, что мы изменяем обе координаты одновременно. Добавьте в функцию slide() перед setTimeout() следующие строки:

block.ypos += 3
block.top = block.ypos

А в функцию moveTo() строки

obj.ypos = y
obj.top = obj.ypos

Результат должен функционировать, как в примере 2.

Однако движение по диагонали может быть сделано хитрее. Давайте вспомним курс тригонометрии фредней школы. Предствим себе прямоугольный треугольник. Если его катет равен, например, х, а угол между гипотенузой (сторона напротив прямого угла) и прилежащего катета (горизонтальная сторона) равен а, то длина прилежащего катета равна х*cos(а), а противолежащего катета (вертикальная сторона) - х*sin(а). Пусть х=5. И теперь нам нужны четыре дополнительных свойства в функции инициализации:

object.angle = 30
object.xinc = 5*Math.cos(object.angle*Math.PI/180)
object.yinc = 5*Math.sin(object.angle*Math.PI/180)
object.count = 0

Мы как обычно считаем инкрементацию координат x и y, чтобы определить left и top значения. Угол а необходимо умножать на Math.PI/180 для конвертации градусов в радианы, поскольку синус и косинус считаются для радианов. Свойство count будет использоваться для задания количества итераций функции.

Попробуем этот скрипт в действии:

<SCRIPT>
<!--
ns4 = (document.layers)? true:false
ie4 = (document.all)? true:false

function init() {
if (ns4) block = document.blockDiv
if (ie4) block = blockDiv.style
block.xpos = parseInt(block.left)
block.ypos = parseInt(block.top)
block.angle = 0
block.xinc = 5*Math.cos(block.angle*Math.PI/180)
block.yinc = 5*Math.sin(block.angle*Math.PI/180)
block.count = 0
}

// Must recalculate the xinc and yinc before you move
function go() {
block.angle = document.changeangle.angletext.value
block.xinc = 5*Math.cos(block.angle*Math.PI/180)
block.yinc = 5*Math.sin(block.angle*Math.PI/180)
slide()
}

function slide() {
if (block.count < 20) {
block.xpos += block.xinc
block.ypos -= block.yinc
block.left = block.xpos
block.top = block.ypos
block.count += 1
setTimeout("slide()",30)
}
else block.count = 0
}
function restart() {
block.count = 0
moveTo(block,150,150)
}

function moveTo(obj,x,y) {
obj.xpos = x
obj.ypos = y
obj.left = obj.xpos
obj.top = obj.ypos
}
//-->
</SCRIPT>

<BODY BGCOLOR="#FFFFFF" onLoad="init()">
<FORM NAME="changeangle">

Type in an angle and hit Go:
<BR><INPUT NAME="angletext" TYPE="TEXT" SIZE=4 VALUE="0">
<INPUT TYPE="BUTTON" VALUE="Go" onClick="go()">
<INPUT TYPE="BUTTON" VALUE="Reset" onClick="restart()">
</FORM>

<DIV ID="blockDiv" style="position:absolute; left:50px; top:100px; width:30px; height:30px; clip:rect(0,30,30,0); layer-background-color:red; background-color:red;">
</DIV>

</BODY>

Вот что мы получим:

Type in an angle and hit Go:






Для полную функциональность можно посмотреть в примере 3.