图像旋转使用纯Javascript

时间:2013-01-03 11:41:06

标签: javascript image-rotation

请不要推荐JQUERY - 我正在为学习目的而进行这项运动。

我已经实现了一个JavaScript,它使用10秒的设置间隔在计时器上旋转图像(_elementSlideChange)。此外,我还为此添加了一个幻灯片功能,即7毫秒(_slideImage)。

图像在页面加载时每10秒自动旋转一次,我还提供了下一个和上一个按钮,允许用户手动更改图像。

_elementSlideChange: function () {
  var myString;
  var myText;
  for (var i = 0; i < this._imgArray.length; i++) {
    var imageArr = "url(" + this._imgArray[i].src + ")";
    var imageBg = this._imageHolder.style.background + "";
    if (imageArr == imageBg) {
      if (i == (this._imgArray.length - 1)) {
        myString = "url(" + this._imgArray[0].src + ")";
        myText = this._infoArray[0];
      } else {
        myString = "url(" + this._imgArray[(i + 1)].src + ")";
        myText = this._infoArray[i + 1];
      }
    }
  }
  this._imageNextSlide.style.background = myString;
  this._imageNextSlide.style.background);
  this._infoElement.innerHTML = myText;
  this._myTimer = setInterval(MyProject.Utils.createDelegate(this._slideImage, this),  7);
},
_slideImage: function () {
  if (parseInt(this._imageHolder.style.width) >= 0 && parseInt(this._imageNextSlide.style.width) <= 450) {
    this._imageHolder.style.backgroundPosition = "right";
    this._imageHolder.style.width = (parseInt(this._imageHolder.style.width) - 1) + 'px';
    console.log(this._imageNextSlide.style.background);
    this._imageNextSlide.style.width = (parseInt(this._imageNextSlide.style.width) + 1) + 'px';
  } else {
    console.log("reached 0px");
    if (parseInt(this._imageHolder.style.width) == 0) {
      this._imageHolder.style.background = this._imageNextSlide.style.background;
      this._imageHolder.style.width = 450 + 'px';
      this._imageHolder === this._imageNextSlide;
      this._imageHolder.className = "orginalImage";
      this._imageNextSlide.style.width = 0 + "px";
      this._imageNextSlide = this._dummyImageNextSlide;
      this._imagesElement.appendChild(this._imageHolder);
      this._imagesElement.appendChild(this._imageNextSlide);
      clearInterval(this._myTimer);
    }
    clearInterval(this._myTimer);
    clearInterval(this._elementSlideChange);
  }
}

因此,当用户单击“下一个”箭头按钮时,将触发“单击”的事件侦听器。这将为显示的当前图像创建一个div,并创建一个新的div,它将包含下一个图像。图像幻灯片和旋转正常工作(无论是onLoad还是onClick)。我遇到的问题是,如果我单击“下一步”按钮,当新的div图像滑动到位时,会导致它进入无限循环,因此与要显示的图像相同的div会继续滑入,并且你越多单击“下一步”按钮,图像开始旋转的速度就越快。

我已经尝试为图像旋转和滑块设置一个清晰的间隔,但我确实理解我的代码是错误的,这会导致滑动图像的无限循环。而且我知道我即将完成功能。

任何人都可以告诉我哪里可能出错?或者我应该尝试以另一种方式实现滑动DIV?

再次请不要推荐jQuery。

谢谢你的帮助。

库什

3 个答案:

答案 0 :(得分:0)

好像你想要取消幻灯片上的动画(也许在下一张幻灯片动画时淡出动画,突然取消动画或让它完成并忽略按钮点击)

我个人经常做的是检查动画状态(是的,我使用jquery,但你应该能够测试CSS或定位你用来以相同方式设置动画的值)你甚至可以添加一个动画期间的“活动”类或数据类型,使测试更容易。全局标志也有效。如果有动画,请忽略该按钮。 (对于我的工作......取决于你的意图)

就像我说的,问题可能在于按钮行为而不是动画例程。看看你是如何通过点击按钮来调用它,以及你想要的结果将是有用的。

答案 1 :(得分:0)

为了解决这个问题,我确实重写了整个代码,我有一个下一个和上一个按钮事件监听器。

myProject.Utils.addHandler(this._nextImageElement, "click", myProject.Utils.createDelegate(this._changeImage, this));

两个按钮都会调用相同的功能:

_changeImage: function (e)

在此功能中,我检查功能是否为Transition(更改图像), 我宣布一个布尔var forward = e.target == this._nextImageElement;

然后检查当前指数是否向前?添加1 else减去1

this._currentImageIndex += forward ? 1 : -1;

如果它在Array和forward的末尾为真,则指定this._currentImageIndex重置为0或Array.length - 1如果它是反向的

然后调用另一个赋予'div'滑动效果的函数。在这种情况下,请将其称为this._transitionImage(forward);

在此函数中,将this._inTranstion设置为true。 (因为在这种情况下div正在滑动)。

以下代码解决了我遇到的问题。

this._slideImageElement.style.backgroundImage = "url(\"" + this._imgArray[this._currentImageIndex].src + "\")";

this._slideImageElement.style.backgroundPosition = forward ? "left" : "right";        
this._slideImageElement.style.left = forward ? "auto" : "0px";
this._slideImageElement.style.right = forward ? "0px" : "auto";

上面的代码非常重要,因为对象是将当前Visible“div”的“滑动div”左或右放置给用户,这主要取决于forward变量是true还是false。

var i = 0;

然后通过

开始转换
setInterval( function() {
    this._currentImageElement.style.backgroundPosition = (forward ? -1 : 1) * (i + 1) + "px";
       this._slideImageElement.style.width = (i + 1) + "px";

请注意,转发将确定bgPosition是否会向前移动,如果它的前向为多个-1或+1, 所以举个例子 如果用户单击“下一个按钮”, 前进=真 所以我们要做的第一件事是设置

this._slideImageElement.style.backgroundPosition = "left"

然后

this._slideImageElement.style.left = "auto"
this._slideImageElement.style.right = "0px"

这意味着当滑动图像在其背景位置移动时是LEFT但是div被放置在右边0px; 然后t his._currentImageElement.style.backgroundPosition = -1 * (i + 1) 将currentImageElement的位置向左移动1px

增加slideImage的宽度,在本例中为当前div的 right , 当当前div向左移动时,滑动图像开始从右侧出现。 (默认情况下,将slideImageElement的宽度设置为0px,因此div存在但对用户不可见)。 这使它具有向前移动来自右侧的新图像的幻灯片效果。

this._slideImageElement.style.width = (i + 1) + "px";

然后声明它停止时它是图像宽度。在这种情况下,它将是500px。 if((i = i + 2)== 500){     在这个if语句中重置currentImageElement背景和背景位置“right”或“left”并不重要,只要它已被重置。

清除间隔 再次将过渡设置为false 然后为函数changeImage调用setTimeout,该函数将一直持续到幻灯片完成。

以下显示重置代码,因为这对于防止重复相同的图像非常重要(这解决了我的整个问题)

// set the current image to the "new" current image and reset it's background position
this._currentImageElement.style.backgroundImage = "url(\"" + this._imgArray[this._currentImageIndex].src + "\")";
this._currentImageElement.style.backgroundPosition = "right";

// reset the slide image width
this._slideImageElement.style.width = "0px";

// clear the transition interval and mark as not in transition
clearInterval(this._transitionInterval);
                this._inTransition = false;

// setup the next image timer
this._nextImageTimeout = setTimeout(myProject.Utils.createDelegate(this._changeImage, this), 2500);

}

我提供了详尽的详细信息,因为这样可以更容易理解问题的逻辑,即使您没有遇到同样的问题,这也可以帮助您解决任何问题。

我无法提供JSfiddle,因为我使用Javascript创建了CSS,有不同的方法可以做到这一点,但我想了解正向和反向背后的逻辑,并有一个持续前进的计时器。

答案 2 :(得分:-2)

CSS3过渡怎么样?

transition: all 1s ease 0.5s;

Simple example on JS Fiddle

这会处理动画,因此您只需要使用JavaScript设置目标目的地,即

this.style.left = '100px';

或者

this.style.top = '30px';

CSS3过渡将平滑地滑动元素。

跨浏览器注意!

transition属性可能需要某些浏览器的供应商前缀,我使用的是最新的Firefox版本,您不需要-moz。 Opera也是如此,不需要'-o'。 Internet Exporer 10不需要前缀。您可能需要在Safari / Chrome中使用-webkit,但无需先测试。