国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

制作圖片傾斜(tilt)效果

lyning / 1492人閱讀

摘要:上面這段結(jié)構(gòu)經(jīng)過(guò)腳本處理之后,會(huì)被替換成下面的結(jié)構(gòu)腳本分析我們利用了這個(gè)插件對(duì)上面的圖片進(jìn)行處理,來(lái)實(shí)現(xiàn)傾斜效果。

原文來(lái)自:

  

http://tympanus.net/codrops/2015/05/28/image-tilt-effect/

所謂的傾斜效果,我也不知如何用語(yǔ)言描述,那就直接看Demo啦,下面我們會(huì)對(duì)這個(gè)效果的實(shí)現(xiàn)原理逐步分析:
http://codepen.io/CodingMonkeyzh/pen/jPYNyr

文檔結(jié)構(gòu)

對(duì)一個(gè)圖片添加該效果,首先,我們需要一個(gè)具有寬高的容器。DOM 結(jié)構(gòu)非常簡(jiǎn)單。

上面這段結(jié)構(gòu)經(jīng)過(guò)腳本處理之后,會(huì)被替換成下面的結(jié)構(gòu):

腳本分析

我們利用了filtfx.js這個(gè)插件對(duì)上面的圖片進(jìn)行處理, 來(lái)實(shí)現(xiàn)傾斜效果。我在原來(lái)的代碼中加入了一些注釋,來(lái)幫助我們理解。下面我們對(duì)該插件的核心代碼進(jìn)行分析。

function TiltFx(el, options) {
  this.el = el;
  this.options = extend({}, this.options);
  extend(this.options, options);
  this._init();
  this._initEvents();
}

這是構(gòu)造函數(shù),如果我們的文檔中,加入了上面的插件,那么插件會(huì)遍歷文檔中具有tilt-effetimg元素,來(lái)調(diào)用構(gòu)造函數(shù)TiltFx()

function init() {
  // 遍歷所有擁有‘title-effect’類的img元素
  [].slice.call(document.querySelectorAll("img.tilt-effect")).forEach(function(img) {
    new TiltFx(img, JSON.parse(img.getAttribute("data-tilt-options")));
  });
}

TiltFx()具有一個(gè)原型屬性,兩個(gè)原型方法。原型屬性配置了一些默認(rèn)的參數(shù)用于調(diào)用:

/**
 * 默認(rèn)參數(shù)
 */
TiltFx.prototype.options = {
  extraImgs: 2, // 額外的輔助圖片數(shù)量
  opacity: 0.7,
  bgfixed: true, // 底圖是否固定
  movement: {    // 這是一些用于移動(dòng)的參數(shù)
    perspective: 1000,
    translateX: -10,
    translateY: -10, 
    translateZ: 20,
    rotateX: 2,
    rotateY: 2,
    rotateZ: 0
  }
}

第一個(gè)原型方法是_init(),用于初始化DOM結(jié)點(diǎn),生成我們的目標(biāo)DOM結(jié)點(diǎn):

TiltFx.prototype._init = function() {
  this.tiltWrapper = document.createElement("div");
  this.tiltWrapper.className = "tilt";

  // main image element.
  this.tiltImgBack = document.createElement("div");
  this.tiltImgBack.className = "tilt__back";
  this.tiltImgBack.style.backgroundImage = "url(" + this.el.src + ")";
  this.tiltWrapper.appendChild(this.tiltImgBack);

  // image elements limit.
  if (this.options.extraImgs < 1) {
    this.options.extraImgs = 1;
  } else if (this.options.extraImgs > 5) {
    this.options.extraImgs = 5;
  }

  if (!this.options.movement.perspective) {
    this.options.movement.perspective = 0;
  }

  // add the extra image elements.
  this.imgElems = [];
  for (var i = 0; i < this.options.extraImgs; ++i) {
    var el = document.createElement("div");
    el.className = "tilt__front";
    el.style.backgroundImage = "url(" + this.el.src + ")";
    el.style.opacity = this.options.opacity;
    this.tiltWrapper.appendChild(el);
    this.imgElems.push(el);
  }

  if (!this.options.bgfixed) {
    this.imgElems.push(this.tiltImgBack);
    ++this.options.extraImgs;
  }

  // add it to the DOM and remove original img element.
  this.el.parentNode.insertBefore(this.tiltWrapper, this.el);
  this.el.parentNode.removeChild(this.el);

  // tiltWrapper properties: width/height/left/top
  this.view = {
    width: this.tiltWrapper.offsetWidth,
    height: this.tiltWrapper.offsetHeight
  };
};

另外一個(gè)原型方式是用于監(jiān)聽(tīng)鼠標(biāo)事件之類的:

TiltFx.prototype._initEvents = function() {
  var self = this,
    moveOpts = self.options.movement;

  // mousemove event..
  this.tiltWrapper.addEventListener("mousemove", function(ev) {
    requestAnimationFrame(function() {
      // mouse position relative to the document.
      var mousepos = getMousePos(ev),
        // document scrolls.
        docScrolls = {
          left: document.body.scrollLeft + document.documentElement.scrollLeft,
          top: document.body.scrollTop + document.documentElement.scrollTop
        },
        bounds = self.tiltWrapper.getBoundingClientRect(),
        // mouse position relative to the main element (tiltWrapper).
        relmousepos = {
          x: mousepos.x - bounds.left - docScrolls.left,
          y: mousepos.y - bounds.top - docScrolls.top
        };

      // configure the movement for each image element.
      for (var i = 0, len = self.imgElems.length; i < len; ++i) {
        var el = self.imgElems[i],
          rotX = moveOpts.rotateX ? 2 * ((i + 1) * moveOpts.rotateX / self.options.extraImgs) / self.view.height * relmousepos.y - ((i + 1) * moveOpts.rotateX / self.options.extraImgs) : 0,
          rotY = moveOpts.rotateY ? 2 * ((i + 1) * moveOpts.rotateY / self.options.extraImgs) / self.view.width * relmousepos.x - ((i + 1) * moveOpts.rotateY / self.options.extraImgs) : 0,
          rotZ = moveOpts.rotateZ ? 2 * ((i + 1) * moveOpts.rotateZ / self.options.extraImgs) / self.view.width * relmousepos.x - ((i + 1) * moveOpts.rotateZ / self.options.extraImgs) : 0,
          transX = moveOpts.translateX ? 2 * ((i + 1) * moveOpts.translateX / self.options.extraImgs) / self.view.width * relmousepos.x - ((i + 1) * moveOpts.translateX / self.options.extraImgs) : 0,
          transY = moveOpts.translateY ? 2 * ((i + 1) * moveOpts.translateY / self.options.extraImgs) / self.view.height * relmousepos.y - ((i + 1) * moveOpts.translateY / self.options.extraImgs) : 0,
          transZ = moveOpts.translateZ ? 2 * ((i + 1) * moveOpts.translateZ / self.options.extraImgs) / self.view.height * relmousepos.y - ((i + 1) * moveOpts.translateZ / self.options.extraImgs) : 0;

        el.style.WebkitTransform = "perspective(" + moveOpts.perspective + "px) translate3d(" + transX + "px," + transY + "px," + transZ + "px) rotate3d(1,0,0," + rotX + "deg) rotate3d(0,1,0," + rotY + "deg) rotate3d(0,0,1," + rotZ + "deg)";
        el.style.transform = "perspective(" + moveOpts.perspective + "px) translate3d(" + transX + "px," + transY + "px," + transZ + "px) rotate3d(1,0,0," + rotX + "deg) rotate3d(0,1,0," + rotY + "deg) rotate3d(0,0,1," + rotZ + "deg)";
      }
    });
  });

  // reset all when mouse leaves the main wrapper.
  this.tiltWrapper.addEventListener("mouseleave", function(ev) {
    setTimeout(function() {
      for (var i = 0, len = self.imgElems.length; i < len; ++i) {
        var el = self.imgElems[i];
        el.style.WebkitTransform = "perspective(" + moveOpts.perspective + "px) translate3d(0,0,0) rotate3d(1,1,1,0deg)";
        el.style.transform = "perspective(" + moveOpts.perspective + "px) translate3d(0,0,0) rotate3d(1,1,1,0deg)";
      }
    }, 60);

  });

  // window resize
  window.addEventListener("resize", throttle(function(ev) {
    // recalculate tiltWrapper properties: width/height/left/top
    self.view = {
      width: self.tiltWrapper.offsetWidth,
      height: self.tiltWrapper.offsetHeight
    };
  }, 50));
};

我們可以看到,監(jiān)聽(tīng)mousemove的事件處理函數(shù)中的計(jì)算比較復(fù)雜,關(guān)鍵的部分就是在這里:

        var el = self.imgElems[i],
          rotX = moveOpts.rotateX ? 2 * ((i + 1) * moveOpts.rotateX / self.options.extraImgs) / self.view.height * relmousepos.y - ((i + 1) * moveOpts.rotateX / self.options.extraImgs) : 0,
          rotY = moveOpts.rotateY ? 2 * ((i + 1) * moveOpts.rotateY / self.options.extraImgs) / self.view.width * relmousepos.x - ((i + 1) * moveOpts.rotateY / self.options.extraImgs) : 0,
          rotZ = moveOpts.rotateZ ? 2 * ((i + 1) * moveOpts.rotateZ / self.options.extraImgs) / self.view.width * relmousepos.x - ((i + 1) * moveOpts.rotateZ / self.options.extraImgs) : 0,
          transX = moveOpts.translateX ? 2 * ((i + 1) * moveOpts.translateX / self.options.extraImgs) / self.view.width * relmousepos.x - ((i + 1) * moveOpts.translateX / self.options.extraImgs) : 0,
          transY = moveOpts.translateY ? 2 * ((i + 1) * moveOpts.translateY / self.options.extraImgs) / self.view.height * relmousepos.y - ((i + 1) * moveOpts.translateY / self.options.extraImgs) : 0,
          transZ = moveOpts.translateZ ? 2 * ((i + 1) * moveOpts.translateZ / self.options.extraImgs) / self.view.height * relmousepos.y - ((i + 1) * moveOpts.translateZ / self.options.extraImgs) : 0;

        el.style.WebkitTransform = "perspective(" + moveOpts.perspective + "px) translate3d(" + transX + "px," + transY + "px," + transZ + "px) rotate3d(1,0,0," + rotX + "deg) rotate3d(0,1,0," + rotY + "deg) rotate3d(0,0,1," + rotZ + "deg)";
        el.style.transform = "perspective(" + moveOpts.perspective + "px) translate3d(" + transX + "px," + transY + "px," + transZ + "px) rotate3d(1,0,0," + rotX + "deg) rotate3d(0,1,0," + rotY + "deg) rotate3d(0,0,1," + rotZ + "deg)";

這里我們根據(jù)鼠標(biāo)的位置,計(jì)算出了各個(gè)圖層對(duì)應(yīng)的偏移量和旋轉(zhuǎn)角度,然后對(duì)它們進(jìn)行變換即可。
最后mouseleave之后,我們?cè)侔褌€(gè)個(gè)圖層恢復(fù)到初始位置就行了。

Demo:http://codepen.io/CodingMonkeyzh/pen/jPYNyr

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/85778.html

相關(guān)文章

  • 可能是最全的前端動(dòng)效庫(kù)匯總

    摘要:非常的龐大,而且它是完全為設(shè)計(jì)而生的動(dòng)效庫(kù)。它運(yùn)行于純粹的之上,是目前最強(qiáng)健的動(dòng)畫資源庫(kù)之一。可能是創(chuàng)建滾動(dòng)特效最好用的工具,它支持大量的瀏覽器,只要它們支持和特性。可以通過(guò)安裝吊炸天了,接近現(xiàn)實(shí)生活中的物理運(yùn)動(dòng)碰撞慣性動(dòng)畫庫(kù)。 收集日期為2019-02-28,★代表當(dāng)時(shí)的該項(xiàng)目在github的star數(shù)量 Animate.css 56401 ★ 一個(gè)跨瀏覽器的動(dòng)效基礎(chǔ)庫(kù),是許多基礎(chǔ)動(dòng)...

    afishhhhh 評(píng)論0 收藏0
  • 3D全景漫游

    摘要:可選,默認(rèn)值為,設(shè)置為則禁止用戶和全景圖交互導(dǎo)航條不可用。可選,默認(rèn)值為,全景圖在毫秒后會(huì)自動(dòng)進(jìn)行動(dòng)畫。當(dāng)全景圖準(zhǔn)備就緒并且第一張圖片顯示時(shí)的回調(diào)函數(shù)。 3D全景漫游 showImg(http://mmbiz.qpic.cn/mmbiz/cibketMByvrbpDqUQ9LiaBvutnwMehicnO2RZurdl96FLtwqlf6LjWS0Bv8ApQY0YjHdtyFWuzz...

    DesGemini 評(píng)論0 收藏0
  • 頁(yè)面制作HTML+CSS基礎(chǔ)亂燉

    摘要:標(biāo)簽大集合語(yǔ)義化標(biāo)簽頁(yè)面內(nèi)錨點(diǎn)我跳跳到這里來(lái)可用于回到頂部功能。表格中表示行,和表示列。當(dāng)超出時(shí)會(huì)自動(dòng)換行。屬性清除浮動(dòng)通用方案實(shí)際上是添加了一個(gè)看不見(jiàn)的點(diǎn)號(hào)。 1. 里的 一定要放在第一行 ,如果放在了下面可能會(huì)有問(wèn)題。 2.標(biāo)簽大集合 showImg(https://segmentfault.com/img/bVMaUw?w=1366&h=767); 3.HTML5語(yǔ)義化標(biāo)簽...

    ruicbAndroid 評(píng)論0 收藏0
  • 頁(yè)面制作HTML+CSS基礎(chǔ)亂燉

    摘要:標(biāo)簽大集合語(yǔ)義化標(biāo)簽頁(yè)面內(nèi)錨點(diǎn)我跳跳到這里來(lái)可用于回到頂部功能。表格中表示行,和表示列。當(dāng)超出時(shí)會(huì)自動(dòng)換行。屬性清除浮動(dòng)通用方案實(shí)際上是添加了一個(gè)看不見(jiàn)的點(diǎn)號(hào)。 1. 里的 一定要放在第一行 ,如果放在了下面可能會(huì)有問(wèn)題。 2.標(biāo)簽大集合 showImg(https://segmentfault.com/img/bVMaUw?w=1366&h=767); 3.HTML5語(yǔ)義化標(biāo)簽...

    ityouknow 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<