>  기사  >  웹 프론트엔드  >  캡슐화된 모션 프레임워크의 실제 구현에서 슬라이딩 포커스 캐러셀 다이어그램에 대한 설명

캡슐화된 모션 프레임워크의 실제 구현에서 슬라이딩 포커스 캐러셀 다이어그램에 대한 설명

小云云
小云云원래의
2018-01-15 14:24:281577검색

이 글에서는 주로 무브먼트 프레임을 캡슐화하고 좌우, 상하로 슬라이드하는 포커스 캐러셀 다이어그램(예제)을 소개합니다. 편집자님이 꽤 좋다고 생각하셔서 지금 공유하고 모두에게 참고용으로 드리고자 합니다. 편집자를 따라 살펴보겠습니다. 모두에게 도움이 되기를 바랍니다.

이 글에서는범용 균일 모션 프레임워크 구축(예제 설명)에서 균일 모션 프레임워크를 캡슐화합니다. 이 프레임워크를 기반으로 버퍼 모션 효과를 추가한 다음 모션 프레임을 사용하여 슬라이드(위, 위로, 아래, 왼쪽, 오른쪽).

버퍼 이동에는 일반적으로 두 가지 일반적인 표현이 있습니다. 예를 들어 p를 0에서 500으로 이동하도록 하는 경우, 이벤트가 트리거될 때 하나는 매우 빠르며, 이벤트가 트리거될 때 다른 하나는 느리다가 천천히 빨라집니다. 먼저 감속하는 속도를 알아봅시다. 일반적인 방법은 운전하는 것입니다. 예를 들어 자동차가 고속도로에서 막 내리면 120km/h가 되고 진입로에 들어서면 40km/h가 됩니다. 40km/h에서 멈춰서 40km/h로 바뀌는데, 120km/h->40km/h, 또는 40km->0km/h에서는 속도가 먼저 느려졌다가 느려질 수 있습니다. 이런 모션을 프로그램으로 표현할 수 있나요?

목표 거리(500) - 현재 거리(200) / 계수(예: 12)를 사용하여 속도의 느린 변화를 달성할 수 있습니다. 현재 거리는 시작점에 있고 분자는 분자입니다. (500 - 0)이 가장 크므로 속도가 가장 큽니다. 현재 거리가 500에 가까우면 분자가 가장 작고 분할 후의 속도도 가장 작습니다.


<style>
 p{
  width: 200px;
  height: 200px;
  background:red;
  position: absolute;
  left: 0px;
 }
 </style>
 <script>
 window.onload = function(){
  var oBtn = document.querySelector( "input" ),
  oBox = document.querySelector( &#39;#box&#39; ),
  speed = 0, timer = null;
  oBtn.onclick = function(){
  timer = setInterval( function(){
   speed = ( 500 - oBox.offsetLeft ) / 8;
   oBox.style.left = oBox.offsetLeft + speed + &#39;px&#39;;
  }, 30 );
  }
 }
 </script>
</head>
<body>
 <input type="button" value="动起来">
 <p id="box"></p>
</body>

그러나 p는 고분고분하게 500px의 목표 위치에서 멈추지 않고 결국 497.375px에서 멈추게 됩니다. 현재 속도와 현재 값을 확인해보면 이유를 알 수 있습니다

속도는 항상 0.375에서 멈추고, 현재 얻은 거리는 497px에서 멈춥니다. 여기에 문제가 있습니다. p가 497.375px에서 멈추지 않나요? 소수점 0.375 없이 어떻게 얻을 수 있나요? 컴퓨터는 부동 소수점 숫자를 처리할 때 정밀도가 손실됩니다. 별도로 작은 테스트를 할 수 있습니다.


<p id="box"></p>
 <script>
 var oBox = document.querySelector( &#39;#box&#39; );
 alert( oBox.offsetLeft );
 </script>

이 코드로 얻은 왼쪽 오프셋은 인라인 스타일로 작성된 30.2px가 아닌 30px임을 알 수 있습니다. 현재 위치를 구할 때 소수점은 반올림하기 때문에 속도는 항상 0.375px에서 멈추고, 위치는 항상 497에서 멈춥니다. 따라서 목표에 도달하려면 속도를 1로 변경하고 속도를 반올림해야 합니다. up ( Math .ceil ), 속도를 1로 변경할 수 있고 p도 500에 도달할 수 있습니다


oBtn.onclick = function(){
 timer = setInterval( function(){
 speed = ( 500 - oBox.offsetLeft ) / 8;
 if( speed > 0 ) {
  speed = Math.ceil( speed );
 }
 console.log( speed, oBox.offsetLeft );
 oBox.style.left = oBox.offsetLeft + speed + &#39;px&#39;;
 }, 30 );
}

두 번째 질문, p의 위치가 900이면, 즉 900에서 500으로 이동합니다. , 그런 방법이 있나요? 수요는 어떻습니까? 하나쯤은 있을 텐데요, 캐러셀 사진은 오른쪽에서 왼쪽으로 이렇게 보입니다.


<style>
 #box{
  width: 200px;
  height: 200px;
  background:red;
  position: absolute;
  left: 900px;
 }
 </style>
 <script>// <![CDATA[
 window.onload = function(){
  var oBtn = document.querySelector( "input" ),
  oBox = document.querySelector( &#39;#box&#39; ),
  speed = 0, timer = null;
  oBtn.onclick = function(){
  timer = setInterval( function(){
   speed = ( 500 - oBox.offsetLeft ) / 8;
   if( speed > 0 ) {
   speed = Math.ceil( speed );
   }
   oBox.style.left = oBox.offsetLeft + speed + &#39;px&#39;;
  }, 30 );
  }
 }
 // ]]></script>
</head>
<body>
 <input type="button" value="动起来">
 <p id="box"></p>
</body>

최종 목표는 503.5px에서 멈춥니다. 이때 속도는 음수입니다. 반대 방향의 속도는 -1로 변경해야 목표에 도달합니다. , 따라서 반내림(Math.floor)


oBtn.onclick = function(){
 timer = setInterval( function(){
 speed = ( 500 - oBox.offsetLeft ) / 8;
 if( speed > 0 ) {
  speed = Math.ceil( speed );
 }else {
  speed = Math.floor( speed );
 }
 console.log( speed, oBox.offsetLeft );
 oBox.style.left = oBox.offsetLeft + speed + &#39;px&#39;;
 }, 30 );
}

방향을 사용합니다. 그런 다음 이 버퍼 모션을 균일 모션 프레임에 통합하면 다음과 같이 됩니다.


function css(obj, attr, value) {
 if (arguments.length == 3) {
 obj.style[attr] = value;
 } else {
 if (obj.currentStyle) {
  return obj.currentStyle[attr];
 } else {
  return getComputedStyle(obj, false)[attr];
 }
 }
}

function animate(obj, attr, fn) {
 clearInterval(obj.timer);
 var cur = 0;
 var target = 0;
 var speed = 0;
 obj.timer = setInterval(function () {
 var bFlag = true;
 for (var key in attr) {
  if (key == &#39;opacity &#39;) {
  cur = css(obj, &#39;opacity&#39;) * 100;
  } else {
  cur = parseInt(css(obj, key));
  }
  target = attr[key];
  speed = ( target - cur ) / 8;
  speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
  if (cur != target) {
  bFlag = false;
  if (key == &#39;opacity&#39;) {
   obj.style.opacity = ( cur + speed ) / 100;
   obj.style.filter = "alpha(opacity:" + ( cur + speed ) + ")";
  } else {
   obj.style[key] = cur + speed + "px";
  }
  }
 }
 if (bFlag) {
  clearInterval(obj.timer);
  fn && fn.call(obj);
 }
 }, 30 );
}

이 균일 모션 프레임을 사용하면 다음과 같습니다. 슬라이드쇼를 할 예정입니다:

상단 및 하단 슬라이드용 HTML 스타일 파일:


<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>slide - by ghostwu</title>
 <link rel="stylesheet" href="css/slide3.css" rel="external nofollow" >
 <script src="js/animate.js"></script>
 <script src="js/slide.js"></script>
</head>
<body>
<p id="slide">
 <p id="slide-img">
 <p id="img-container">
  <img src="./img/1.jpg" alt="">
  <img src="./img/2.jpg" alt="">
  <img src="./img/3.jpg" alt="">
  <img src="./img/4.jpg" alt="">
  <img src="./img/5.jpg" alt="">
 </p>
 </p>
 <p id="slide-nums">
 <ul>
  <li class="active"></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
 </ul>
 </p>
</p>
</body>
</html>

slide3.css 파일:


* {
 margin: 0;
 padding: 0;
}
li {
 list-style-type: none;
}
#slide {
 width: 800px;
 height: 450px;
 position: relative;
 margin:20px auto;
}
#slide-img {
 position: relative;
 width: 800px;
 height: 450px;
 overflow: hidden;
}
#img-container {
 position: absolute;
 left: 0px;
 top: 0px;
 height: 2250px;
 /*font-size:0px;*/
}
#img-container img {
 display: block;
 float: left;
}
#slide-nums {
 position: absolute;
 right:10px;
 bottom:10px;
}
#slide-nums li {
 float: left;
 margin:0px 10px;
 background: white;
 width: 20px;
 height: 20px;
 text-align: center;
 line-height: 20px;
 border-radius:10px;
 text-indent:-999px;
 opacity:0.6;
 filter:alpha(opacity:60);
 cursor:pointer;
}
#slide-nums li.active {
 background: red;
}

animate.js 파일:


function css(obj, attr, value) {
 if (arguments.length == 3) {
 obj.style[attr] = value;
 } else {
 if (obj.currentStyle) {
  return obj.currentStyle[attr];
 } else {
  return getComputedStyle(obj, false)[attr];
 }
 }
}

function animate(obj, attr, fn) {
 clearInterval(obj.timer);
 var cur = 0;
 var target = 0;
 var speed = 0;
 obj.timer = setInterval(function () {
 var bFlag = true;
 for (var key in attr) {
  if (key == &#39;opacity &#39;) {
  cur = css(obj, &#39;opacity&#39;) * 100;
  } else {
  cur = parseInt(css(obj, key));
  }
  target = attr[key];
  speed = ( target - cur ) / 8;
  speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
  if (cur != target) {
  bFlag = false;
  if (key == &#39;opacity&#39;) {
   obj.style.opacity = ( cur + speed ) / 100;
   obj.style.filter = "alpha(opacity:" + ( cur + speed ) + ")";
  } else {
   obj.style[key] = cur + speed + "px";
  }
  }
 }
 if (bFlag) {
  clearInterval(obj.timer);
  fn && fn.call(obj);
 }
 }, 30 );
}

slide.js 파일:


window.onload = function () {
 function Slide() {
 this.oImgContainer = document.getElementById("img-container");
 this.aLi = document.getElementsByTagName("li");
 this.index = 0;
 }

 Slide.prototype.bind = function () {
 var that = this;
 for (var i = 0; i < this.aLi.length; i++) {
  this.aLi[i].index = i;
  this.aLi[i].onmouseover = function () {
  that.moveTop( this.index );
  }
 }
 }

 Slide.prototype.moveTop = function (i) {
 this.index = i;
 for( var j = 0; j < this.aLi.length; j++ ){
  this.aLi[j].className = &#39;&#39;;
 }
 this.aLi[this.index].className = &#39;active&#39;;
 animate( this.oImgContainer, {
  "top" : -this.index * 450,
  "left" : 0
 });
 }
 
 var oSlide = new Slide();
 oSlide.bind();

}

왼쪽 슬라이드 스타일과 오른쪽 슬라이드 스타일만 변경하시면 됩니다

스타일 파일 :


* {
 margin: 0;
 padding: 0;
}
li {
 list-style-type: none;
}
#slide {
 width: 800px;
 height: 450px;
 position: relative;
 margin:20px auto;
}
#slide-img {
 position: relative;
 width: 800px;
 height: 450px;
 overflow: hidden;
}
#img-container {
 position: absolute;
 left: 0px;
 top: 0px;
 width: 4000px;
}
#img-container img {
 display: block;
 float: left;
}
#slide-nums {
 position: absolute;
 right:10px;
 bottom:10px;
}
#slide-nums li {
 float: left;
 margin:0px 10px;
 background: white;
 width: 20px;
 height: 20px;
 text-align: center;
 line-height: 20px;
 border-radius:10px;
 text-indent:-999px;
 opacity:0.6;
 filter:alpha(opacity:60);
 cursor:pointer;
}
#slide-nums li.active {
 background: red;
}

js 호출 파일 :


window.onload = function () {
 function Slide() {
 this.oImgContainer = document.getElementById("img-container");
 this.aLi = document.getElementsByTagName("li");
 this.index = 0;
 }

 Slide.prototype.bind = function () {
 var that = this;
 for (var i = 0; i < this.aLi.length; i++) {
  this.aLi[i].index = i;
  this.aLi[i].onmouseover = function () {
  that.moveLeft( this.index );
  }
 }
 }

 Slide.prototype.moveLeft = function (i) {
 this.index = i;
 for( var j = 0; j < this.aLi.length; j++ ){
  this.aLi[j].className = &#39;&#39;;
 }
 this.aLi[this.index].className = &#39;active&#39;;
 animate( this.oImgContainer, {
  "left" : -this.index * 800
 });
 }
 
 var oSlide = new Slide();
 oSlide.bind();

}

관련 추천 :

유니버설 만드는 방법 균일 모션 프레임워크

JS 캡슐화 모션 프레임워크 작성 방법

버퍼링 모션 프레임을 구현하는 JavaScript의 예

위 내용은 캡슐화된 모션 프레임워크의 실제 구현에서 슬라이딩 포커스 캐러셀 다이어그램에 대한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.