纯js实现3d相册(附源码)


本文摘自PHP中文网,作者angryTom,侵删。

纯JavaScript实现 旋转木马/3d相册特效(鼠标拖拽旋转)

先来看看效果图

1.png

说一下实现的思路

旋转木马是通过依靠拥有景深(perspective)属性的盒子(此处盒子id起为:perspective)产生向网页内部的延伸感,并让装有图片沿z轴平移后(translateZ(Xpx))的盒子(此处起名为wrap)在拥有景深属性的盒子(perspective)内凭借transform属性产生的3d效果沿盒子(wrap)y轴旋转转动来实现的。

【相关课程推荐:JavaScript视频教程

3d实现过程

首先要知道在js中transform中的xyz轴的含义

2.png

首先设置一个div,为其加上perspective的属性(撑开空间),方便后边观察效果

1

2

3

4

5

/* 场景景深 */

#perspective{

perspective: 700px;/*此属性是实现旋转木马的要点,能产生空间上的距离/延伸感。

在此盒子中放置图片的盒子便可以实现向网页内部延伸的感觉*/

}

2. 其次,设置装有图片盒子的容器wrap,使其居中显示,并加上position:relative的属性,让其内的图片定位。加上transform属性,在之后会用到。

1

2

3

4

5

6

7

8

9

#wrap{

position: relative;

width: 200px;

height: 200px;

margin: 150px  auto;

border:  1px solid black;

transform-style: preserve-3d;  /*实现3d效果的关键步骤,与boxshadow配合使用可以忽略层级问题,之后会说到*/

transform: rotateX(0deg) rotateY(0deg) ;//为盒子的3d效果和旋转效果做准备。

}

加入图片,设置样式,使用position:absolute;使其重叠。以数组的形式获取,并根据其数组长度length来计算图片的旋转角度。

1

2

3

4

5

6

7

8

9

#wrap img{

position: absolute;

width: 200px;

}

<script>

var oImg = document.getElementsByTagName('img');

var Deg = 360/oImg.length;

oWrap = document.getElementById('wrap');  /*顺便拿一下容器*/

</script>

遍历数组,使其沿y轴旋转Deg度。此处使用了原型,使用foreach方法遍历了数组,让其内每个图片都执行了function(el,index)。使用index下标区分开了数组内每个图片需要旋转的不同度数(第一张0°(Deg * 0) 第二张Deg度 (Deg * 1) 第三张(Deg * 2)度…)

1

2

3

4

/*oImg表示数组对象,function(el,index)表示数组内每个对象要执行的函数,index为其下标。*/

Array.prototype.forEach.call(oImg,function(el,index){

el.style.transform = "rotateY("+Deg*index+"deg)";

})

Array.prototype 属性表示 Array 构造函数的原型,并允许我们向所有Array对象添加新的属性和方法。

forEach() 方法对数组的每个元素执行一次提供的函数。

此处值得注意的是,xxx.xx.transform = “rotateY(”+Deg*index+“deg)”;

需要加上deg单位,括号要被双引号包着,也就是说,出来后的结果是transform :rotateY(度数deg);度数表示数字,要避免被转为字符串。

做完上一步操作后,让盒子其内图片沿Z轴平移translateZ(350px)属性便能初步看到3d效果,但此时会发现容器内图片数组出现了层级问题(Zindex)导致了理应在后面的图片能被显示出来。

这里有一种方法能忽略掉这个影响,避开层级问题:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

/*加上沿z扩散*/

<script>

Array.prototype.forEach.call(oImg,function(el,index){

el.style.transform = "rotateY("+Deg*index+"deg)translateZ(350px)"; //沿z轴扩散350px

})

</script>

-------执行完毕后--------加上属性观察效果---------

#wrap{

width: 200px;

height: 200px;

position: relative;

margin:150px auto;

transform-style: preserve-3d;  /*实现3d效果的关键步骤,与boxshadow配合使用可以忽略层级问题*/

}

#wrap img{

position: absolute;

width: 200px;

box-shadow: 0px 0px 1px #000000;  /* 用box-shadow配合transform-style: preserve-3d;可以忽略层级问题 */

}

这时候为装有图片的盒子加上transform:rotateX(-15deg);便能看到较为完整的3d效果了,此时实现盒子绕y轴转动便可实现旋转木马的效果。

实现运动过程

单纯使盒子转动就可以实现旋转木马,可以使用setinterval来不断使其旋转。

如果想使用鼠标拖动实现旋转木马,则需要再加一些代码,使装有盒子的容器(wrap)能够根据鼠标坐标变化绕容器(wrap)自身y轴转动。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

var nowX ,nowY,//当前鼠标坐标

lastX ,lastY ,//上一次鼠标坐标

minusX,minusY ,//距离差

roX = -10,roY = 0;//总旋转度数

window.onmousedown = function(ev){

var ev = ev;//获得事件源

//鼠标移动后当前坐标会变为旧坐标,此处先保存,在算鼠标位移距离差的时候会用到。

lastX = ev.clientX;

lastY = ev.clientY;

this.onmousemove = function(ev){

var ev = ev;//获得事件源

nowX = ev.clientX;nowY = ev.clientY;//获得移动时的当前坐标

minusX = nowX - lastX;//坐标差

minusY = nowY - lastY;//坐标差

//累计差值,如果不累计的话转轮在每次点击-->移动后都会从第一张开始。

roY += minusX;

roX -= minusY;//累计差值

//转动容器的x轴和y轴,使其转动度数(数值,不带单位)等于鼠标坐标差。

oWrap.style.transform = "rotateX("+roX+"deg)"

+"rotateY("+roY+"deg)";

lastX = nowX;lastY = nowY;//移动末期现坐标变为旧坐标

}

this.onmouseup = function(){

this.onmousemove = null;//取消鼠标移动的影响

// this.onmousedown = null;

}

}

}

完整代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title></title>

<style type="text/css">

*{

margin: 0;

padding: 0;

}

body{overflow: hidden;

background: #000000;

}

/* 场景景深 */

#perspective{

perspective: 700px;

}

#wrap{

position: relative;

width: 200px;

height: 200px;

margin: 150px  auto;

border:  1px solid black;

transform-style: preserve-3d;

transform: rotateX(-15deg) rotateY(0deg) ;/*景深可以简写在此属性里*/

}

#wrap img{

position: absolute;

width: 200px;

transform: rotateX(0deg) rotateY(0deg);

box-shadow: 0px 0px 1px #000000;

/* 用box-shadow可以忽略层级问题 */

}

</style>

</head>

<body>

<div id="perspective">

<div id="wrap">

<img src="img3/preview1.jpg" >

<img src="img3/preview2.jpg" >

<img src="img3/preview3.jpg" >

<img src="img3/preview4.jpg" >

<img src="img3/preview5.jpg" >

<img src="img3/preview6.jpg" >

<img src="img3/preview7.jpg" >

<img src="img3/preview8.jpg" >

<img src="img3/preview9.jpg" >

<img src="img3/preview10.jpg" >

<img src="img3/preview11.jpg" >

</div>

</div>

<script type="text/javascript">

window.onload=function(){

var oImg = document.getElementsByTagName('img'),

oWrap = document.getElementById('wrap');

var Deg = 360/(oImg.length);

Array.prototype.forEach.call(oImg,function(el,index){

el.style.transform = "rotateY("+Deg*index+"deg)translateZ(350px)";

// el.style.zIndex = -index;

el.style.transition = "transform 1s "+ index*0.1 +"s";

});

var nowX ,nowY,//当前鼠标坐标

lastX ,lastY ,//上一次鼠标坐标

minusX,minusY ,//距离差

roX = -10,roY = 0;//总旋转度数

window.onmousedown = function(ev){

var ev = ev;//获得事件源

lastX = ev.clientX;lastY = ev.clientY;

this.onmousemove = function(ev){

var ev = ev;//获得事件源

nowX = ev.clientX;nowY = ev.clientY;//获得当前坐标

minusX = nowX - lastX;minusY = nowY - lastY;//坐标差

roY += minusX;//累计差值

roX -= minusY;//累计差值

oWrap.style.transform = "rotateX("+roX+"deg)"

+"rotateY("+roY+"deg)";

lastX = nowX;lastY = nowY;//移动末期现坐标变为旧坐标

}

this.onmouseup = function(){

this.onmousemove = null;//取消鼠标移动的影响

// this.onmousedown = null;

}

}

}

</script>

</body>

</html>

本文来自 js教程 栏目,欢迎学习!

以上就是纯js实现3d相册(附源码)的详细内容,更多文章请关注木庄网络博客

相关阅读 >>

浅谈js函数及闭包

vue可完全替代jq吗

详解js中函数的相关定义与用法

html css js 区别是什么

javascript 中cookie读、写与删除操作(图文教程)

javascript和js之间有区别吗

js 怎么判断数字相等

jquery表单插件jquery.form.js

javascript的重构技巧

js是什么意思?

更多相关阅读请进入《js》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...