2012-11-30 5 views
1

조금 작은 div이 사인파를 따라 움직일 수 있기를 희망하는 작은 JavaScript 애니메이션을하고 있으며, 잠시 동안 수평 경로가 잘 작동합니다 (직선 만). Y 축의 수학 공식이 잘못되었다고 확신합니다. 나는 발견 한 몇 가지 예를 가지고 그것을 바로 잡으려고 노력했지만, 그들 중 누구도 나를 위해 일하지 않았다. 내가 시도한 모든 가능성에서, Y 축은 무시되고 작은 상자는 단지 직선으로 수평으로 움직인다.이 자바 스크립트 애니메이션이 사인파 움직임을 만들어서는 안됩니까?

어떻게 해결할 수 있습니까? 운동이 사인파를 따라 이동합니까? jQuery를 사용하거나 HTML 5를 사용하는 것이 더 쉽다는 것을 알고 있지만 원래 코드에서 무엇이 잘못되었는지 궁금해졌습니다. 가능하면이 문제를 해결하는 것이 좋습니다. 여기

function animate() { 
    xnow = item.style.left; 
    item.style.left = parseInt(xnow)+1+'px'; 
    ynow = item.style.top; 
    item.style.top = ynow + (Math.sin((2*Math.PI*xnow)/document.width))*document.heigth; 
    setTimeout(animate,20); 
} 

전체 코드 : JSFiddle

+0

이렇게해도 문제는 해결되지 않지만'height'의 철자가'heigth '로 잘못 표시됩니다. 또한 item.style.top의 결과를 기록하면 값은 항상 400px입니다. – Chase

+0

운영자 ... 감사합니다 .-- 철자가 잘못되었습니다. 어쨌든, 그게 내가 이해하지 못하는 이유, 왜 값이 변하지 않는 ... –

+0

https://developer.mozilla.org/en-US/docs/DOM/document.width – Andreas

답변

7

난 당신의 코드 몇 가지 문제를 참조하십시오 : ###px 당신은 그것을 곱, 그래서에서 parseInt()을 사용할 수 없습니다

  • xnow이 형식의 문자열을 포함 귀하의 Math.sin() 전화.
  • 동일한 코드를 가져 오는 코드는 ynow이고, 코드는 parseInt()입니다.
  • 다른 (전역) 변수를 사용하여 x 및 y 좌표를 숫자로 저장하는 것이 좋습니다. 그리고 div 요소의 좌표를 업데이트 할 때 px을 추가하십시오.
  • 2*Math.PIxnow (정수만 포함)을 곱하면 sin() 함수는 항상 0을 반환합니다. 그래서 여러분은 사인 같은 운동을하지 않을 것입니다. xnow을 사인과 같은 완전한 동작을 수행하는 데 사용할 x 단계의 수로 나눌 필요가 있습니다.
  • Math.sin()은 -1과 +1 사이의 값을 반환하므로 진폭을 곱하여 (더 명확한) 효과.
당신이 그것을 설계 한, 이런 식으로 뭔가 될 것

만큼 그것을 유지하기 위해 는 (완전한 사인을 할 50 X-이동 단계를 수행하고 10 개 픽셀의 진폭 사용) :

function animate() { 
    xnow = parseInt(item.style.left); 
    item.style.left = (xnow+1)+'px'; 
    ynow = parseInt(item.style.top); 
    item.style.top = (ynow+Math.sin(2*Math.PI*(xnow/50))*10) + "px"; 
    setTimeout(animate,20); 
} 

을 언급 한 바와 같이 : (항상 parseInt()을 사용하는 대신) 값을 포함하는 일부 전역 변수를 사용하는 것이 훨씬 낫습니다.

updated JSFiddle example을 참조하십시오.

+0

마지막 점을 이해했는지 확실하지 않습니다. 이 뜻인가요? :'(Math.sin (2 * Math.PI * (xnow/parseInt (document.body.clientWidth))) * document.height' –

1

몇 가지 오류가 있습니다

  • height이 실제로 필요하지 비록 (추가하기 전에 int로 사인
  • 구문 분석 ynow을 복용하기 전에 int로
  • 구문 분석 xnow을 철자가 잘못 참조 아래)
  • item.style.top
  • 에 끝 부분에 "px"을 추가하십시오. 방정식 cou 약간의 조정을 사용하십시오 :

나는 (400 + Math.sin(2*Math.PI*xnow/document.width) * 200) + "px"으로 시작하여 그걸 가지고 놀아볼 것을 제안합니다. 400은 사인파를 기반으로하는 수평 축입니다. 상수 대신 ynow을 사용하면 누적 효과가 발생합니다 (파도가 의도 한 것보다 훨씬 더 커지거나 시간이 지남에 따라 수평축이 변경됩니다).

document.width은 한 전체 기간의 너비입니다. 200은 피크 진폭입니다 (수평에서 피크까지의 거리 - document.height은 양방향에서 화면 밖으로 상자를 밀어냅니다). 현재의 대신이 함수를 연결 한 다음은 숫자의 주위에 재생할 수 있습니다 : 당신은 xnowparseInt()를 사용할 필요가

function animate() { 
    xnow = parseInt(item.style.left); 
    item.style.left = xnow+1+'px'; 
    item.style.top = (400 + Math.sin(2*Math.PI*xnow/document.width) * 200) + "px"; 
    setTimeout(animate,20); 
} 
2

. 또한 올바른 형식의 문자열을 만들기 위해 숫자 끝에 'px'를 추가해야합니다.

function animate() { 
    xnow = parseInt(item.style.left); 
    item.style.left = xnow+1+'px'; 
    item.style.top = 200 + (Math.sin((2*Math.PI*xnow)/200))*document.height+'px'; 
    setTimeout(animate,20); 
} 
7

죄 함수 C 함수의 y 중간이고 Y = A * 죄 (B 형 *의 X) + (C)의 형태 (또는 수평 :

이 코드는 작동 여기서 a는 진폭 (y = c에서 최대 y- 오프셋)이고 b는주기 (x = 2 * pi의 수/파의 수)입니다.

sin 파동이 -a에서 + a로 진동한다는 것을 감안할 때 우리는 (1) 상수이어야하고 2) 상한과 하한 사이의 중간에 오프셋 (c)을 알아야합니다. 당신이 객체가 전체 화면을 통과하려면이를 위해 우리는, C와 같은 값이됩니다

c = document.height/2;

귀하의 진폭을 사용할 수 있습니다. 테스트 결과, 페이지의 맨 아래를지나 가게되었으므로 90 % 만 확인하십시오. 전체 페이지 1의 기간 동안

a = 0.9 * c;

, 당신은 2 * 파이의 비율이 될 것 같은 것을 요인에 의해 B의 곱셈 X를 확인해야합니다. 이 경우 각 반복에

b = 2*Math.PI/document.width;

에서 ynow의 값을 취득 할 필요가 없습니다, 그것은 xnow의 함수이다.그런 다음

ynow = c + a * Math.sin(b * xnow);에 새로운 Y를 계산

xnow = parseInt(item.top.left) + 5;

의 라인을 따라 뭔가를 할 수 있습니다.

그런 다음 항목의 스타일을 설정하십시오.

item.style.top = ynow + 'px';

item.style.left = xnow + 'px';

아무것도 불분명 있다면 알려주세요. 문안 인사.