Модераторы: Sardar, Aliance
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Пробегающий кружок по графику, проблемы с отрисовкой 
:(
    Опции темы
Ciber SLasH
Дата 25.5.2005, 07:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург

Репутация: 24
Всего: 67



Сваял скрипт, в котором пробегает шарик (gif-ка) по графику синуса.
Но вся проблема в том, что он не работает в IE, а работает в Опере. Нужно чтоб и там и сям работало. smile

Код

<html>
<head>
<meta http-equiv=Content-Type content='text/html; charset=windows-1251'>
</head>

<body>
<center>
<h3>Движение по траектории синуса</h3>
<button onClick=draw()>Вперёд</button><br><br>
<div id=graph style='position: absolute; left: 10%; width: 80%; height: 80%; background: navy'></div>
</center>

<script language='JavaScript'>
/*** Отбрасывание дробной части ***/
function trunc(fNum) {
var i, ST = fNum.toString()

  i = ST.indexOf('.')
  return (i > 0) ? parseInt(ST.substring(0, i)) : fNum
}

cnv = document.getElementById('graph')

Xmax = 6  // наибольшее значение X
Ymax = 2  // наибольшее значение Y

// Область для графика
mx = cnv.offsetWidth - 14
my = cnv.offsetHeight

// Точка отсчёта (начало координат)
cx = 0
cy = trunc(my / 2)

sx = (mx-cx) / Xmax  // масштабирование по X
sy = (my-cy) / Ymax  // масштабирование по Y

function putPixel(X, Y) {
var xx,yy,n  // xx - преобразование координаты X; yy - преобразование координаты Y

  xx = trunc(X*sx) + cx
  yy = trunc(cy - Y*sy)

  for (n = 0; n < 50000; n++) {}  // задержка
  cnv.innerHTML = '<img id=point src=d.gif style="position: absolute; left: ' + xx + '; top: ' + yy + '">'
}

function draw() {
var X,Y, step

  step = Xmax / (mx-cx) * 10  // шаг графика
  X = 0
  while (X <= Xmax) {
    Y = Math.sin(/*Math.PI / 180 **/ X)
    putPixel(X, Y)
    X += step
  }
  document.getElementById('point').removeNode(false)  // удаляем "шарик"
}
</script>
</body>
</html>

И ещё вопрос: а как вычислять координаты gif-точки, если ей поставить свойство position в relative и запихнуть DIV в таблицу ?
Если было бы так:
Код

<table id=cnvTB width=80% height=80%>
<tr><td><div id=graph style=height:100%></div>
</table>
<!--
cnvTB = document.getElementById('cnvTB')
mx = cnvTB.offsetWidth - 14
my = cnvTB.offsetHeight
-->


Это сообщение отредактировал(а) Ciber SLasH - 26.5.2005, 15:03

Присоединённый файл ( Кол-во скачиваний: 6 )
Присоединённый файл  d.gif
PM   Вверх
Aliance
Дата 25.5.2005, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 55
Всего: 137



Лично мне в ИЕ6 (SP2) писалось, что сценарий может тормозить процессов.
Попробуй область уменьшить...

Затем куча мелких недочетов:
  • переменные объвлены как глобальные (нет var)
  • отсутствубют точки с запятой

Цитата(Ciber @ 25.5.2005, 08:06)
а как вычислять координаты gif-точки, если ей поставить свойство position в relative и запихнуть DIV в таблицу ?

div`у пропиши id="test", и по document.getElementById('test') вычисляй...
PM MAIL WWW ICQ Skype   Вверх
Ciber SLasH
Дата 26.5.2005, 04:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург

Репутация: 24
Всего: 67



Всё-таки так и не смог нормально сделать отрисовку при задании position: relative...
Подправил чють скрипт:
Код

<html>
<head>
<meta http-equiv=Content-Type content='text/html; charset=windows-1251'>
</head>

<body>
<center>
<h3>Движение по траектории синуса</h3>
<button onClick=draw()>Вперёд</button><br><br>
<table width=80% height=80% cellspacing=0 cellpadding=0 style=background:navy>
<tr><td><div id=graph style=height:100%></div>
</table>
</center>

<script language='JavaScript'>
/*** Отбрасывание дробной части ***/
function trunc(fNum) {
var i, ST = fNum.toString()

  i = ST.indexOf('.')
  return (i > 0) ? parseInt(ST.substring(0, i)) : fNum
}

cnv = document.getElementById('graph')

Xmax = 6  // наибольшее значение X
Ymax = 2  // наибольшее значение Y

// Область для графика
mx = cnv.offsetWidth - 14
my = cnv.offsetHeight

// Точка отсчёта (начало координат)
cx = 0
cy = my / 2

sx = (mx-cx) / Xmax  // масштабирование по X
sy = (my-cy) / Ymax  // масштабирование по Y

function putPixel(X, Y, i) {
var xx,yy,n, content  // xx - преобразование координаты X; yy - преобразование координаты Y

  xx = trunc(X*sx + cx) - i*14
  yy = trunc(cy - Y*sy)

//  for (n = 0; n < 50000; n++) {}  // задержка
  content = '<img id=point' + i + ' src=d.gif width=14 height=14 style="position: relative; left: ' + xx + '; top: ' + yy + '">'
  cnv.innerHTML += content

/*  pt = document.getElementById('point' + i)
  alert('X: ' + X + '; Y: ' + Y + '\n\n' +
//        'X*sx: ' + X*sx + '; trunc(X*sx): ' + trunc(X*sx) + '\n' +
//        'Y*sy: ' + Y*sy + '; trunc(Y*sy): ' + trunc(Y*sy) + '\n\n' +
        'xx: ' + xx + ' (' + trunc(X*sx + cx) + '); yy: ' + yy + '\n\n' +
        'pt' + i + ':\n' +
        '  offsetParent.tagName: ' + pt.offsetParent.tagName + '\n' +
        '  offsetLeft: ' + pt.offsetLeft + '\n' +
        '  offsetTop: ' + pt.offsetTop + '\n\n' +
        'content: \n\n' + content)
*/
}

function draw() {
var X,Y, step, i

  step = Xmax / (mx-cx) * 10  // шаг графика
  i = X = 0
  while (X <= Xmax) {
    Y = Math.sin(X)
    putPixel(X, Y, i)
    X += step
    i++
  }
//  document.getElementById('point').removeNode(false)  // удаляем "шарик"
}
</script>
</body>
</html>

Как бы теперь сделать правильную отрисовку при position: relative ?

Need Help !!

ЗЫ: количество шагов уменьшил (step = <...> * 10) в 10 раз, глобальные переменные испоьзуются в 2-х функциях (не переписывать же их 2 раза), точки с запятой -- нафик, и без них всё работает (знаю что могут обламаться всякие парсеры, но до этого мне ещё далеко, а я люблю минимализм -- меньше символов -- меньше вес страницы).

Это сообщение отредактировал(а) Ciber SLasH - 26.5.2005, 15:06
PM   Вверх
Aliance
Дата 26.5.2005, 13:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 55
Всего: 137



Цитата(Ciber @ 26.5.2005, 05:07)
глобальные переменные испоьзуются в 2-х функциях

А вне функции их не задать? Тогда они будут глобальными...

Цитата(Ciber @ 26.5.2005, 05:07)
не переписывать же их 2 раза), точки с запятой -- нафик, и без них всё работает (знаю что могут обламаться всякие парсеры, но до этого мне ещё далеко, а я люблю минимализм -- меньше символов -- меньше вес страницы).

С такими задатками далеко не уйдешь smile

Это сообщение отредактировал(а) Aliance - 26.5.2005, 13:33
PM MAIL WWW ICQ Skype   Вверх
Ciber SLasH
Дата 26.5.2005, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург

Репутация: 24
Всего: 67



Выяснил, что при position: relative координата left отсчитывается от предыдущего элемента, поэтому приходится при вычислении новой left-координаты рисунка отнимать занимаемую ширину предыдущих рисунков. Т.е. left: x - (i * <ширина рисунка>).

C учётом этого переписал скрипт и отредактировал предыдущий пост, дабы не выкладывать снова тот же скрипт в новом посту.

Но появились другие баги (для понимания при отладке раскомментировать коммент в функции putPixel):
1) не понятно почему document.getElementById('point' + i).offsetParent.tagName указывает на BODY а не на DIV
2) теперь график рисуется правильно, но только до 56-го прохода, дальше offsetLeft контейнера принимает отрицательные значения, что и приводит к неправильной отрисовки. Хотя по идеи положительные значения offsetLeft контейнера должны продолжаться вплоть до конца DIV-а...

ещё интересные вещи творятся если:
1) из xx не вычитать (i*14)
2) а в IMG поставить в стиле вместо left -- right
PM   Вверх
Sardar
Дата 27.5.2005, 02:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



1) потому что offsetParent и parentNode это не одно и тоже, первый это блочный элемент с которого начинается отсчёт координат потомков, второе это родительский узел элемента.

2) посмотри это, наваял за пол часа: http://forum.vingrad.ru/index.php?act=ST&f=188&t=53487 smile


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Ciber SLasH
Дата 27.5.2005, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург

Репутация: 24
Всего: 67



10x Sardarу за плоттер, при просмотре исходника я понял почему мой график глючил -- нужно было реализовать нормальную задержку через setInterval() и кой-чего подправить с позицией.

Я всё-таки оставил свой вариант графика (он более понятен).
Вот переделанный скрипт (он лишь заточен на движение по синусу, остальное пока не нужно):
Код

<html>
<head>
<meta http-equiv=Content-Type content='text/html; charset=windows-1251'>
</head>

<body>
<center style=height:100%>
<h3>Движение по траектории синуса</h3>
<button onClick=draw()>Вперёд</button><br><br>
<!-- Контейнер для графика -->
<div id=graph style='position: relative; width: 80%; height: 80%; background: navy'></div>
</center>

<script language='JavaScript'>
cnv = document.getElementById('graph')

Xmax = 2*Math.PI  // наибольшее значение X (1 период)
Ymax = 2          // наибольшее значение Y

// Область для графика
mx = cnv.offsetWidth - 14
my = cnv.offsetHeight

// Точка отсчёта (начало координат)
cx = 0
cy = Math.floor(my / 2)

sx = (mx-cx) / Xmax  // масштабирование по X
sy = (my-cy) / Ymax  // масштабирование по Y

function draw() {
// X,Y - координаты графика в Декартовой системе; step - шаг графика; timer - время повтора отрисовки
var X,Y, step, timer

  step = Xmax / ((mx-cx) / 14)
  X = 0
  timer = setInterval(putPixel, 1)  // повторяем отрисовку каждые 10 мс

    /* Отрисовка одной точки */
    function putPixel() {
    var xx,yy

      if (X > Xmax) {        // если точка графика вылазит за область отрисовки
        clearTimeout(timer)  // снимаем таймер
        //document.getElementById('point').removeNode(false)  // удаляем "шарик"
        return
      }
      Y = Math.sin(X)  // вычисляем Y-координату графика функции синуса

      xx = Math.floor(X*sx + cx)  // преобразование координаты X
      yy = Math.floor(cy - Y*sy)  // преобразование координаты Y

      // Вставляем элемент IMG в контейнер для графика
      cnv.innerHTML += '<img id=point src=d.gif style="position: absolute; left: ' + xx + '; top: ' + yy + '">'

      X += step  // увеличиваем шаг графика
    }
}
</script>
</body>
</html>

Если раскомментировать 45 строку, а в 54-й вместо оператора += поставить просто =, то вместо отрисовки графика будет движение по графику.

Кстати этот скрипт есть модификация одной лабы на Паскале:
Код

program sinus;
uses Crt, Graph;
{$I ..\InitGr.inc}
const
  A = 1;         { амплитуда }
  F = 1000;      { частота }
  T = 1/F;       { период }
  M = 5;         { количество периодов }
  Xmax = M * T;  { наибольшее значение Х. Xmax=x2-x1=M*T-0=M*T }
  Ymax = 2;      { наибольшее значение Y. Ymax=y2-y1=1-(-1)=2 }
  cx = 10;       { Х-координата начала отсчёта }
  cy = 240;      { Y-координата начала отсчёта }
  sx = (640-cx) / Xmax;  { масштабирование по оси X }
  sy = (480-cy) / Ymax;  { масштабирование по оси Y }

{*** Преобразование матем. коор. X в граф. коор. X ***}
function CoordX(X: Extended): Integer;
var
  RezX: LongInt;
begin
  RezX := Trunc(X * sx) + cx;
  if RezX > $FFFF then
    RezX := Integer(RezX);
  if RezX < cx then
    RezX := cx
  else if RezX > 640 then
    RezX := 640;
  CoordX := RezX
end;

{*** Преобразование матем. коор. Y в граф. коор. Y ***}
function CoordY(Y: Extended): Integer;
var
  RezY: LongInt;
begin
  RezY := cy - Trunc(Y * sy);
  if RezY > $FFFF then
    RezY := Integer(RezY);
  if RezY < 0 then
    RezY := 0
  else if RezY > 480 then
    RezY := 480;
  CoordY := RezY
end;
{############################################################################}
var
  X,Y, step: Extended;
begin
  graphInit;
  SetColor(13);
  MoveTo(cx, cy);
  step := Xmax / (640-cx);
  X := step;
  while X <= Xmax do
  begin
    { Y = A*sin(wt + fi);        w = 2*Pi/T = 2*Pi*F;        F = 1/T
      где: A - амплитуда; w - круговая частота; T - период; F - частота;
      wt + fi - фаза колебаний; fi - фаза в начальный момент времени (t=0) }
    Y := A*Sin(2*Pi*F*X);
    LineTo(CoordX(X), CoordY(Y));
    X := X + step
  end;
  SetColor(15);
  Line(cx,cy,       640,cy);
  Line(cx,0,        cx,480);
  repeat until KeyPressed;
  graphClose
end.


ЗЫ: хотел выделить += и = жирным стилем -- не получилось. Хоть и стоит:
Код
[b]+=[/b]


Это сообщение отредактировал(а) Ciber SLasH - 27.5.2005, 18:29
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0532 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.