引子

   断断续续用了好几天,终于把 impress.js 源码看完,作为刚入门的前端菜鸟,这是我第一次看 js 源码,最初还是比较痛苦的。不过还好,impress.js源码的注释相当清楚,每个函数和事件的作用都写得很详细,这让源码读起来更容易理解,此处手动给大神送糖果~~~接下来就由我给大家分享下 impress.js 效果是如何实现的、以及我们怎么利用它来实现特效。

impress.js的实现

我们在用 impress.js实现特效时,会用到类似下面的代码:

<div id="its" class="step" data-x="900" data-y="3000" data-rotate="90" data-scale="4">

我们看到代码中有data-x,data-y等属性,实际上我们就是通过改变这些属性的值来实现PPT的跳转的。这些属性分别代表:

  • data-x:幻灯片的X坐标

  • data-y:幻灯片的Y坐标

  • data-scale:幻灯片显示的缩放比例

  • data-rotate:幻灯片旋转的度数

  • data-rotate-x:3D使用,设置它相对X轴旋转多少度

  • data-rotate-y:3D使用,设置它相对Y轴旋转多少度

  • data-rotate-z:3D使用,设置它性对Z轴旋转多少度
    我们来看看impress源码中的 rotate函数:

//'rotate'对给定数据构造旋转变换
//默认旋转顺序为X,Y,Z,可以将参数设定为true来倒转顺序
var rotate = function( r, revert ) {var rX = " rotateX(" + r.x + "deg) ",rY = " rotateY(" + r.y + "deg) ",rZ = " rotateZ(" + r.z + "deg) ";
return revert ? rZ + rY + rX : rX + rY + rZ;};​

rotate函数的作用是将rotate对象转换成css使用的字符串。
用户自定义的数据通过data属性读取,并初始化给step对象。对应源码如下

:var data = el.dataset,step = {translate: {//对给定数据构造平移变换x: toNumber( data.x ),y: toNumber( data.y ),z: toNumber( data.z )},rotate: {//对给定数据构造旋转变换x: toNumber( data.rotateX ),y: toNumber( data.rotateY ),z: toNumber( data.rotateZ || data.rotate )},scale: toNumber( data.scale, 1 ),//对给定数据构造缩放变换el: el};​     

我们在编写HTML时,通过改变data的属性值实现页面切换,那么在源码中,又是怎么来实现的呢?
在impress.js源码中,主要通过三个事件来实现impress的运行,它们分别是impress:init,impress:stepenter和impress:stepleave,在了解这些事件之前,先明白 step 这个概念,一个step就相当于PPT中的一页,每切换一页就相当于切换一个step。每一次切换都会触发上面所提到的两个事件:impress:stepenter和impress:stepleave,从而达到页面跳转的效果。

我们在使用 impress.js的时候,需要调用impress.js中的impress().init()函数:`

<script type="text/javascript">impress().init();</script>

init() 函数是 impress 的主初始化函数,它的作用是初始化 impress API ,从而运行impress。在 init() 函数的结尾触发 impress:init事件,这样绑定上去的函数就会全部触发了。以下代码即是触发 impress:init事件:

triggerEvent( root, "impress:init", { api: roots[ "impress-root-" + rootId ] } );};       

Triggerevent()方法:触发指定对象的指定事件,并且立即执行该事件中的脚本。
Triggerevent构造一个事件,该事件以 'eventnam'命名,用detail处理数据,并在el上执行。源码如下:

var triggerEvent = function( el, eventName, detail ) {var event = document.createEvent( "CustomEvent" );event.initCustomEvent( eventName, true, true, detail );el.dispatchEvent( event );};​

接下来我们看看 impress:init事件上绑定了哪些函数:
(1)为step添加一些有用的类:

root.addEventListener( "impress:init", function() {
// STEP CLASSESsteps.forEach( function( step ) {step.classList.add( "future" );//所有尚未展示的 steps 都添加到都添加 `future` 类} );
root.addEventListener( "impress:stepenter", function( event ) {event.target.classList.remove( "past" );event.target.classList.remove( "future" );event.target.classList.add( "present" ); // 当某个step 被展示,`future`类会被移除,并被添加上 `present`类}, false );
root.addEventListener( "impress:stepleave", function( event ) {event.target.classList.remove( "present" );event.target.classList.add( "past" );//当某个step结束时, `present` 又会被替换成`past`类}, false );
}, false );​ 

通过上面的方法,每个 step 都会处于 future, presentpast三个状态中的一个,这样使得我们在切换PPT的时候可以前后任意切换。
上面代码中用到了addEventListener() 方法,该方法用于向指定元素添加事件句柄。语法如下:element.addEventListener(event,function,useCapture);
参数 event:必需,指定事件名,不要使用"on"前缀;
function:指定事件要触发时执行的函数;
useCapture:可选(布尔值),指定事件是否在捕获或者冒泡时执行。
可使用 removeEventListener() 方法来移除 addEventListener() 方法添加的事件句柄。

(2)添加hash变化支持:

root.addEventListener("impress:init", function(){var lastHash = "";  // 将lasthash清空// `#step-id`将被替换成`#/step-id`以防止浏览器在默认状态下滚动至hash表中所保存元素所在位置//// 而且添加hash的操作必须在动画结束以后进行, 因为在Chrome里会导致动画延迟// BUG: http://code.google.com/p/chromium/issues/detail?id=62820root.addEventListener("impress:stepenter", function (event) {window.location.hash = lastHash = "#/" + event.target.id;}, false);window.addEventListener("hashchange", function () {// 当某一step被展示时,location里的hash已经更新(就在上面几行)// 所以hash change事件被触发,我们将在同一step上再一次调用`goto`方法。// 为了避免这一情况,我们将存储上一次 hash 的结果并比较.if (window.location.hash !== lastHash) {goto( getElementFromHash() );}}, false);// 开始// 选择记录在url中的step地址,或者演示文稿的第一张stepgoto(getElementFromHash() || steps[0], 0);}, false);​

window.location.hash: hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部分(从 # 号开始的部分)。
location.hash可以用来获取或设置页面的标签值。
通过 window.location.hash=hash这个语句来调整地址栏的地址,使得浏览器里边的“前进”、“后退”按钮能正常使用。

(3)导航事件
键盘处理导航:
按键被按下时:

// 防止不允许被按下的键被意外按下document.addEventListener("keydown", function ( event ) {if ( event.keyCode === 9 || ( event.keyCode >= 32 && event.keyCode <= 34 ) || (event.keyCode >= 37 && event.keyCode <= 40) ) {event.preventDefault();}}, false);​

preventDefault() 方法阻止元素发生默认的行为。

按键弹起时,触发impress动作(下一张或上一张):

    document.addEventListener("keyup", function ( event ) {if ( event.keyCode === 9 || ( event.keyCode >= 32 && event.keyCode <= 34 ) || (event.keyCode >= 37 && event.keyCode <= 40) ) {switch( event.keyCode ) {case 33: // 上翻页case 37: // 小键盘左case 38: // 小键盘上api.prev();break;case 9: // tab键case 32: // 空格case 34: // 下翻页case 39: // 小键盘右case 40: // 小键盘下api.next();break;}event.preventDefault();}}, false);​处理在当前演示 steps 上产生的单击事件(当前step上是否存在超链接):document.addEventListener("click", function ( event ) {// 事件冒泡处理// 检查单击的目标(及其祖先级容器)是否是超链接var target = event.target;while ( (target.tagName !== "A") &&(target !== document.documentElement) ) {target = target.parentNode;}if ( target.tagName === "A" ) {var href = target.getAttribute("href");// 如果指向某一连接,跳转至这一连接if ( href && href[0] === '#' ) {target = document.getElementById( href.slice(1) );}}if ( api.goto(target) ) {event.stopImmediatePropagation();//如果目标对象件被执行,将阻止剩下事件执行event.preventDefault();}}, false);​
event.stopImmediatePropagation() 方法阻止剩下的事件处理程序被执行,该方法阻止事件在 DOM 树中向上冒泡。
处理在当前演示 steps 上产生的单击事件:document.addEventListener("click", function ( event ) {var target = event.target;// 查找距当前活跃step最近的不活跃stepwhile ( !(target.classList.contains("step") && !target.classList.contains("active")) &&(target !== document.documentElement) ) {target = target.parentNode;}if ( api.goto(target) ) {event.preventDefault();}}, false);
处理触摸屏上上轻击屏幕左边或者右边的事件:document.addEventListener("touchstart", function ( event ) {if (event.touches.length === 1) {var x = event.touches[0].clientX,width = window.innerWidth * 0.3,result = null;if ( x < width ) {result = api.prev();} else if ( x > window.innerWidth - width ) {result = api.next();}if (result) {event.preventDefault();}}}, false);

当窗口大小改变时,重新计算窗口大小:

window.addEventListener("resize", throttle(function () {// 强制激活当前stepapi.goto( document.querySelector(".step.active"), 500 );}, 250), false);   

impress总共有4个API,分别是goto(), init(), next(), prev()。
impress的切换主要通过 goto()来实现,goto API 跳转至以el参数(索引,id或元素名)标记的step 。prev API 按文档顺序跳回上一 step ,next API 按文档顺序跳向下一 step 。




impress.js学习相关推荐

  1. [转] impress.js学习

    引子 断断续续用了好几天,终于把 impress.js 源码看完,作为刚入门的前端菜鸟,这是我第一次看 js 源码,最初还是比较痛苦的.不过还好,impress.js源码的注释相当清楚,每个函数和事件 ...

  2. impress.js 中文版 学习

    impress.js 中文版 学习 从网上的中文版impress.js展示的源代码,后期会看英文的(英语太菜了,看着英文,一脸懵逼,尽量会看英文源码吧.尽量...) 研究impress官网的源码时,我 ...

  3. Impress.js上手 - 抛开PPT、制作Web 3D幻灯片放映

    前言: 如果你已经厌倦了使用PPT设置路径.设置时间.设置动画方式来制作动画特效.那么Impress.js将是你一个非常好的选择. 用它制作的PPT将更加直观.效果也是嗷嗷美观的. 当然,如果用它来装 ...

  4. 【华为云技术分享】【一统江湖的大前端】PPT制作库impress.js

    <一统江湖的大前端>系列是笔者的学习笔记,旨在介绍javascript在非网页开发领域的应用案例和发现各类好玩的js库,不定期更新.今天要介绍的是大前端PPT制作库impress.js. ...

  5. 一统江湖的大前端(1)——PPT制作库impress.js(含附件)

    <一统江湖的大前端>系列是自己的学习笔记,旨在介绍javascript在非网页开发领域的应用案例和发现各类好玩的js库,不定期更新.如果你对前端的理解还是写写页面绑绑事件,那你真的是有点O ...

  6. 如何用impress.js写有逼格的ppt

    概述 这是我学习课程impress让你的内容"舞"起来而做的总结和练手. 你可以点这里在线预览我做的ppt 注意:等加载完了之后,点击空格键翻页! 简化模板 下面是一个简化的模板 ...

  7. 《转》impress.js页面PPT

    impress.js 是国外一位开发者受 Prezi 启发,采用 CSS3 与 JavaScript 语言完成的一个可供开发者使用的表现层框架(演示工具).现在普通开发者可以利用 impress.js ...

  8. impress.js

    介绍一下 impress.js是一个非常炫酷的幻灯片展示框架,依靠CSS3技术. impress.js使用起来非常简单,下面就来简单介绍一下其用法. Start 首先,当然要引入impress.js. ...

  9. 程序员装逼利器之impress.js

    impress.js是一个javascript的第三方类库,可以实现ppt,动画,切换等功能,在所有的web浏览器上均有不错表现,但目前不支持手机浏览器. 下载地址:    https://githu ...

最新文章

  1. Android中实现日期时间选择器(DatePicker和TimePicker)
  2. 12036火车票小工具,希望大家都能顺利回家
  3. html两个框架同时_两个框架的故事
  4. 算法题:输入一个表示整数的字符串,把该字符串转换成整数并输出。例如输入字符串“12345”,则输出整数“12345”
  5. Silverlight 4新控件PivotViewer介绍
  6. 小红帽怎样装图形化界面_纯技术篇:U盘装系统,不再多花冤枉钱
  7. 三甲医院his系统源码_三甲医院科研管理系统是什么,科研成果包括哪些
  8. 数据库系统概论-作业(设计本科生事务管理数据库)
  9. uri和url区别和关联
  10. 利用Matlab App Designer简单设计程序
  11. 进程已结束,退出代码-1073740791(0xC0000409)
  12. div 左中右结构布局问题
  13. [SSL_CHX][2021-10-16]Vigenère密码
  14. 线性回归中常见的一些统计学术语(RSE RSS TSS ESS MSE RMSE R2 Pearson's r)
  15. [乐意黎转载]从零开始学习jQuery (二) 万能的选择器
  16. 盘点国内外那些形式多样的能量采集技术
  17. 输入邮箱判断邮箱是否合法
  18. 嵌入式系统开发期末复习
  19. U3D -- 一些知识点和优秀博客收藏
  20. 高防服务器好,还是游戏盾好?

热门文章

  1. 红帽rhel-9.1安装GCC失败,只因多加了俩空格
  2. 全网最全的Windows下Anaconda2 / Anaconda3里正确下载安装爬虫框架Scrapy(离线方式和在线方式)(图文详解)...
  3. java 画正方体直观图_根据给出的空间几何体的三视图,用斜二侧画法画出它的直观图.正视图侧视图俯视图...
  4. linux系统支持uefi,不支持uefi的老电脑装ubuntu
  5. vue树状结构图(组织架构)
  6. Android中对app应用内存的分配
  7. linux系统设置NTP时间同步
  8. python安装bs4几种方法_Python安装Bs4的多种方法
  9. 特斯拉机器人发布!马斯克:最快明年量产,价格不到14万,搬砖送货都能干...
  10. Linux、Python、计算机网络中的常见知识点