一直从事于后端编程工作, 工作中也经常接触和使用一些前端技术, 但大多数还是用于操作和控制数据与客户端交互工作. 随着互联网技术的发展以及硬件性能的不断提升, 人们对于交互式体验已变得越来越重视, 进而前端技术已经越来越突显出它的重要性, 特别是一些炫酷的特效, 精美的 UI 设计, 都使人眼前一亮, 顿时觉得网站平台都高大上不少, 很博人们眼球, 给人们以很好的视觉冲击, 特别是现在的 css3,HTML5 技术的更新, 使得以更小的代价就可以轻松实现这些效果, 故此, 俺也顿时膜拜起前端技术, 悠然起了兴趣, 跃跃欲试, 随即利用 css3 的新增 3D 特效技术及动画特效功能加原生态 javascript 写了一个随机打乱旋扭的魔方(阶数, 尺寸等都可自定义, 但数值不要太大哦), 在指定的步数后, 魔方按记录的动作, 逆行旋扭重新归位. 随即发布出来与大家分享, 也希望前端的大牛能指点一二, 不甚感激!
html 代码片段
- <!DOCTYPE html>
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>3d 魔方</title>
- <meta charset="utf-8" />
- <script language="javascript" type="text/javascript">
- var cache = {};
- (function (exports) {
- function Cube(opts) {
- opts = opts || {};
- this.parent = opts.parent; // 插入到哪里
- this.browserPrefix = opts.browserPrefix;
- this.width = opts.width;
- this.height = opts.height;
- this.cubZ = opts.cubZ;
- this.face = opts.face;
- this.row = opts.row;
- this.column = opts.column;
- this.offsetX = this.column * (this.width + opts.marginX); //
- this.offsetY = this.row * (this.height + opts.marginY);//
- this.offsetZ = this.face * (this.cubZ + opts.marginZ);//
- this.positiveZ = this.cubZ / 2;
- this.negativeZ = -this.cubZ / 2;
- this.cubFaceInfo = opts.cubFaceInfo;
- this.dimension = opts.dimension;
- this.centerX = (this.dimension * this.width + (this.dimension - 1) * opts.marginX) / 2;
- this.centerY = (this.dimension * this.height + (this.dimension - 1) * opts.marginY) / 2;
- this.centerZ = (this.dimension * this.cubZ + (this.dimension - 1) * opts.marginZ) / 2;
- this.translateX = this.offsetX - this.centerX; // 把中心点设为原点
- this.translateY = this.offsetY - this.centerY; //
- this.translateZ = this.cubZ / 2 + this.offsetZ - this.centerZ; //offsetZ 按上面计算应该跟 x,y 在一个平面上即后面, 但实际上由于要形成立方体, 在 Z 轴上已经后退了 cubZ/2 个距离, 故为和上面保持一致在一个面上, 这里需要再加回 cubZ/2 个距离, 使默认的 xyz 原点都在一个平面上即立方体后面左上角三维坐标系, 以这个点作为参考点平移和设置旋转原点
- this.cubeFace = [];
- this.rotateTransfrom = "";
- this.init();
- }
- Cube.prototype = {
- init: function () {
- this.createCubeBox();
- this.createFront();
- this.createBack();
- this.createTop();
- this.createBottom();
- this.createLeft();
- this.createRight();
- },
- createCubeBox: function () {
- this.Box = document.createElement('div');
- this.Box.style.width = this.width + "px";
- this.Box.style.height = this.height + "px";
- this.Box.style.position = "absolute";
- this.Box.style[this.browserPrefix + "TransformStyle"] = "preserve-3d";
- this.Box.style[this.browserPrefix + "Perspective"] = "0";
- // this.Scene.style[this.browserPrefix + "backfaceVisibility"] = "hidden";
- this.intalTransform = "translateZ(" + this.translateZ + "px) translateX(" + this.translateX + "px) translateY(" + this.translateY + "px)";
- this.Box.style[this.browserPrefix + "Transform"] = this.intalTransform;
- this.Box.style[this.browserPrefix + "TransformOrigin"] = ""+ (-this.translateX) +"px "+ (-this.translateY) +"px "+ (-this.translateZ) +"px";
- this.parent.appendChild(this.Box);
- this.x = window.getComputedStyle(this.Box).getPropertyValue('left');
- this.y = window.getComputedStyle(this.Box).getPropertyValue('top');
- this.matrix3d = window.getComputedStyle(this.Box).getPropertyValue('transform');
- },
- createFace: function () {
- var face = document.createElement('div');
- face.style.margin = 0;
- face.style.position = "absolute";
- face.style.width = this.width + "px";
- face.style.height = this.height + "px";
- return face;
- },
- createFront: function () {
- var face = this.createFace();
- face.style[this.browserPrefix + "Transform"] = "translateZ(" + this.positiveZ + "px)"
- this.cubeFace.push(face);
- this.front = face;
- this.Box.appendChild(face);
- },
- createBack: function () {
- var face = this.createFace();
- face.style[this.browserPrefix + "Transform"] = "translateZ(" + this.negativeZ + "px)";
- this.cubeFace.push(face);
- this.back = face;
- this.Box.appendChild(face);
- },
- createTop: function () {
- var face = this.createFace();
- face.style[this.browserPrefix + "Transform"] = "rotateX(90deg) translateZ(" + this.positiveZ + "px)";
- this.cubeFace.push(face);
- this.top = face;
- this.Box.appendChild(face);
- },
- createBottom: function () {
- var face = this.createFace();
- face.style[this.browserPrefix + "Transform"] = "rotateX(90deg) translateZ(" + this.negativeZ + "px)";
- this.cubeFace.push(face);
- this.bottom = face;
- this.Box.appendChild(face);
- },
- createLeft: function () {
- var face = this.createFace();
- face.style[this.browserPrefix + "Transform"] = "rotateY(90deg) translateZ(" + this.negativeZ + "px)";
- this.cubeFace.push(face);
- this.left = face;
- this.Box.appendChild(face);
- },
- createRight: function () {
- var face = this.createFace();
- face.style[this.browserPrefix + "Transform"] = "rotateY(90deg) translateZ(" + (this.positiveZ) + "px)";
- this.cubeFace.push(face);
- this.right = face;
- this.Box.appendChild(face);
- }
- }
- exports.magicCube = function (opts) {
- opts = opts || {};
- this.parent = opts.parent || document.getElementsByTagName('body')[0];
- this.dimension = opts.dimension || 3; // 魔方级数
- this.cubWidth = opts.cubWidth || 50; // 单个立方体宽度
- this.cubHeight = opts.cubHeight || 50; // 单个立方体高度
- this.marginLeft = opts.marginLeft || 0;// 水平方向间距
- this.marginTop = opts.marginLeft || 0; // 上下方向间距
- this.marginZ = opts.marginZ || 0; // 前后方向间距
- this.cubZ = opts.cubZ || 50; // 单个立方体 Z 轴距离
- this.sceneWidth = opts.sceneWidth; //3d 场景宽度
- this.sceneHeight = opts.sceneHeight; //3d 场景高度
- this.Perspective = opts.Perspective || 0; // 投影值
- this.cubFaceInfo = opts.cubFaceInfo || { front: { backGround: "rgba(0,255,255,.5)" }, back: { backGround: "rgba(153,204,255,.5)" }, left: { backGround: "rgba(128,0,128,.5)" }, right: { backGround: "rgba(255,0,255,.5)" }, top: { backGround: "rgba(255,153,204,.5)" }, bottom: { backGround: "rgba(0,204,255,.5)" }, inner: { backGround: "rgba(100,100,100,.5)" } }; // 立方体面信息
- this.angle = opts.angle || 90; // 转动的角度
- this.rollbackPoint = opts.rollbackPoint || 10;// 回滚的步数
- this.faceCount = this.dimension * this.dimension; // 每面立方体个数
- this.count = this.dimension * this.dimension * this.dimension; // 立方体总个数
- this.cubes = [];
- this.browserPrefix = "";
- this.isRunning = 0;
- this.timer = null;
- this.rotateFace;// 转动的 3 维坐标系方向
- this.moveDirect = true;// 正向随机动作还是回归, 默认为正向
- this.cubeMoveQueue = [];
- this.rollMoveStack = [];// 动作回归的堆栈
- this.init();
- };
- magicCube.prototype = {
- init: function () {
- this.start();
- },
- create3dScene: function () {
- this.Scene = document.createElement('div');
- //this.Scene.className = "cube";
- var width = this.sceneWidth || this.clientWidth,
- height = this.sceneHeight || this.clientHeight;
- this.Scene.style.width = width + "px";
- this.Scene.style.height = height + "px";
- this.Scene.style.left = "50%";
- this.Scene.style.top = "50%";
- this.Scene.style.position = "relative";
- this.Scene.style[this.browserPrefix + "TransformStyle"] = "preserve-3d";
- this.Scene.style[this.browserPrefix + "Perspective"] = this.Perspective + "px";
- // this.Scene.style[this.browserPrefix + "backfaceVisibility"] = "hidden";
- this.Scene.style[this.browserPrefix + "Transform"] = "rotateX(-30deg) rotateY(30deg)";
- this.parent.appendChild(this.Scene);
- },
- create: function (face, row, column) {
- return new Cube({
- parent: this.Scene,
- dimension: this.dimension,
- width: this.cubWidth,
- height: this.cubHeight,
- cubZ: this.cubZ,
- face: face,
- row: row,
- column: column,
- browserPrefix: this.browserPrefix,
- cubFaceInfo: this.cubFaceInfo,
- marginX: this.marginLeft,
- marginY: this.marginTop,
- marginZ: this.marginZ,
- dimension: this.dimension
- });
- },
- createMagicCube: function (index) {
- var face = 0, row = 0, column = 0;
- for (var i = 0; i <this.count; i++) {
- this.cubes.push(this.create(face, row, column));
- this.cubes[this.cubes.length - 1].index = this.cubes.length - 1;
- column++;
- if ((i + 1) % this.dimension === 0) {
- row++;
- column = 0;
- }
- if ((i + 1) % this.faceCount === 0) {
- face++;
- row = 0;
- }
- }
- },
- drawBackGroundColor: function () {
- for (var face in this.cubFaceInfo) {
- if (face == "inner") {
- this.setInnerBKColor(this.cubFaceInfo[face].backGround);
- }
- else {
- var cube = this.getCubesByFace(face);
- for (var i = 0, len = cube.length; i < len; i++) {
- cube[i][face].style.background = this.cubFaceInfo[face].backGround;
- }
- }
- }
- },
- setInnerBKColor: function (color) {
- for (var i = 0; i < this.count; i++) {
- for (var j = 0; j < 6; j++) {
- if (this.cubes[i].cubeFace[j].style.background == "") {
- this.cubes[i].cubeFace[j].style.background = color;
- }
- }
- }
- },
- getZFace: function (zIndex) {
- var zFace = [];
- if (zIndex < 1 || zIndex> this.dimension)
- return null;
- for (var i = (zIndex - 1) * this.faceCount; i <zIndex * this.faceCount; i++) {
- zFace.push(this.cubes[i]);
- }
- return zFace;
- },
- getXFace: function (xIndex) {
- var xFace = [];
- if (xIndex < 1 || xIndex> this.dimension)
- return null;
- for (var i = 0; i <this.count; i++) {
- if (i % this.dimension == 0)
- xFace.push(this.cubes[i + xIndex - 1]);
- }
- return xFace;
- },
- getYFace: function (yIndex) {
- var yFace = [];
- if (yIndex < 1 || yIndex> this.dimension)
- return null;
- for (var i = 0; i <this.count; i++) {
- if (i % this.faceCount == (yIndex - 1) * this.dimension) {
- for (var j = 0; j < this.dimension; j++)
- yFace.push(this.cubes[i + j]);
- }
- }
- return yFace;
- },
- getSideCubes: function (cubes, circleIndex) {
- var sides = [], top = [], left = [], bottom = [], right = [];
- if (circleIndex < 0 || circleIndex> this.dimension / 2 - 1)
- return null;
- for (var i = 0, count = this.dimension - circleIndex * 2; i <count; i++) {
- top.push(cubes[circleIndex * this.dimension + circleIndex + i]);
- left.push(cubes[circleIndex * this.dimension + circleIndex + i * this.dimension]);
- bottom.push(cubes[(this.dimension - 1 - circleIndex) * this.dimension + circleIndex + i]);
- right.push(cubes[circleIndex * this.dimension + circleIndex + i * this.dimension + (this.dimension - (circleIndex * 2) - 1)]);
- }
- sides.push(this.orderByDesc(top));
- sides.push(left);
- sides.push(bottom);
- sides.push(this.orderByDesc(right));
- return sides;
- },
- getCubesByFace: function (face) {
- switch (face) {
- case "front": return this.getZFace(this.dimension);
- case "back": return this.getZFace(1);
- case "left": return this.getXFace(1);
- case "right": return this.getXFace(this.dimension);
- case "top": return this.getYFace(1);
- case "bottom": return this.getYFace(this.dimension);
- }
- },
- moveMagicCube: function () {
- if (this.cubes.length < 1) return;
- //var cubes = this.getYFace(2);
- //for (var i = 0, len = cubes.length; i < len; i++) {
- // cubes[i].Box.className = "rotate";
- //}
- // 随机产生 3D 转动方向
- this.isRunning = 0;
- var direct = this.random(1, 3), rotateDirect = "", getFaceFun;
- // direct=3;
- switch (direct) {
- case 1: rotateDirect = "rotateX"; getFaceFun = this.getXFace; break;
- case 2: rotateDirect = "rotateY"; getFaceFun = this.getYFace; break;
- case 3: rotateDirect = "rotateZ"; getFaceFun = this.getZFace; break;
- }
- this.rotateFace = rotateDirect;
- this.cubeRotateStatus = [];
- for (var i = 1; i <= this.dimension; i++) {
- var status = this.random(0, 2);
- this.cubeRotateStatus.push(status);
- switch (status) {
- case 0: break;// 不转动
- case 1: this.rotateBox(this.angle, rotateDirect, i, getFaceFun.call(this, i)); break;// 正向转动 90
- case 2: this.rotateBox(-this.angle, rotateDirect, i, getFaceFun.call(this, i)); break;// 反向转动 90
- }
- }
- var flag = false;
- for (var i = 0, len = this.cubeRotateStatus.length; i < len; i++) {
- if (this.cubeRotateStatus[i]) {
- flag = true;
- break;
- }
- }
- if (!flag) {// 一个都没转的情况 则强制补充一个
- var index = this.random(1, this.dimension);
- this.rotateBox(this.angle, rotateDirect, index, getFaceFun.call(this, index)); // 正向转动 90
- this.cubeRotateStatus[index - 1] = 1;// 全都不转动 默认选出一个 使其正向转动指定度数
- }
- setTimeout(this.timerFun, 100);
- this.rollMoveStack.push({ rotateFace: this.rotateFace, cubeRotateStatus: this.cubeRotateStatus });// 记录动作状态
- if (this.rollMoveStack.length == this.rollbackPoint)// 判断当达到阀值时切换动作方向为回归
- this.moveDirect = false;
- },
- moveRollBackCube: function () {
- var record = this.rollMoveStack.pop(), getFaceFun;
- this.rotateFace = record.rotateFace;
- this.isRunning = 0;
- switch (record.rotateFace) {
- case "rotateX": getFaceFun = this.getXFace; break;
- case "rotateY": getFaceFun = this.getYFace; break;
- case "rotateZ": getFaceFun = this.getZFace; break;
- }
- this.cubeRotateStatus = [];
- for (var i = 0, len = record.cubeRotateStatus.length; i < len; i++) {
- var dimensionIndex = i+1, status = record.cubeRotateStatus[i];
- if (status == 1) {
- this.cubeRotateStatus.push(2);//1 变 2,2 变 1
- this.rotateBox(-this.angle, record.rotateFace, dimensionIndex, getFaceFun.call(this, dimensionIndex)); // 反向转动 90
- }
- else if (status == 2) {
- this.cubeRotateStatus.push(1);//1 变 2,2 变 1
- this.rotateBox(this.angle, record.rotateFace, dimensionIndex, getFaceFun.call(this, dimensionIndex)); // 反向转动 90
- }
- else {
- this.cubeRotateStatus.push(0);
- }
- }
- setTimeout(this.timerFun, 100);
- if (this.rollMoveStack.length == 0)// 判断当达到 0 时切换动作为正向随机
- this.moveDirect = true;
- },
- intersect: function (source, target) {
- var data = [];
- for (var i = 0, len = source.length; i < len; i++) {
- var index = target.indexOf(source[i]);
- if (index>= 0)
- data.push(source[i])
- }
- return data;
- },
- orderByDesc: function (datas) {
- var temp;
- for (var i = 0; i <datas.length - 1; i++) {
- for (var j = i + 1; j < datas.length; j++) {
- if (parseFloat(datas[i].index) < parseFloat(datas[j].index)) {
- temp = datas[i];
- datas[i] = datas[j];
- datas[j] = temp;
- }
- }
- }
- return datas;
- },
- getSideBackGround: function (sideFaces, face) {
- var backGrounds = [];
- for (var i = 0, len = sideFaces.length; i < len; i++) {
- backGrounds.push(sideFaces[i][face].style.background);
- }
- return backGrounds;
- },
- setRotateDirectSideBackGround: function (faceCubes, sideFace, offset, status) {
- var oldSides = this.getSideCubes(faceCubes, 0), backColor = [];
- var offsetNIndex, offsetPIndex;
- for (var j = 0; j < 4; j++) {
- offsetPIndex = (j - offset + 4) % 4;
- offsetNIndex = (j + offset) % 4;
- if (this.rotateFace == "rotateY") {
- if (status == 1)// 正向
- {
- backColor[j] = this.getSideBackGround(oldSides[offsetPIndex], sideFace[offsetPIndex]);
- }
- else// 反向
- {
- backColor[j] = this.getSideBackGround(oldSides[offsetNIndex], sideFace[offsetNIndex]);
- }
- }
- else {
- if (status == 2)// 正向
- {
- backColor[j] = this.getSideBackGround(oldSides[offsetPIndex], sideFace[offsetPIndex]);
- }
- else// 反向
- {
- backColor[j] = this.getSideBackGround(oldSides[offsetNIndex], sideFace[offsetNIndex]);
- }
- }
- }
- for (var j = 0; j < 4; j++) {
- for (var k = 0; k < oldSides[j].length; k++) {
- oldSides[j][k][sideFace[j]].style.background = backColor[j][k];
- }
- }
- },
- setRotateOtherDirectSideBackGround: function (faceCubes, otherFace, offset, status) {
- var oldSides = [], backColor = [];
- var offsetNIndex, offsetPIndex;
- for (var i = 0; i <= parseInt(this.dimension / 2) - 1; i++) {
- oldSides = this.getSideCubes(faceCubes, i), backColor = [];
- for (var j = 0; j < 4; j++) {
- offsetPIndex = (j - offset + 4) % 4;
- offsetNIndex = (j + offset) % 4;
- if (this.rotateFace == "rotateY") {
- if (status == 1)// 正向
- {
- backColor[j] = this.getSideBackGround(oldSides[offsetPIndex], otherFace);
- }
- else// 反向
- {
- backColor[j] = this.getSideBackGround(oldSides[offsetNIndex], otherFace);
- }
- }
- else {
- if (status == 2)// 正向
- {
- backColor[j] = this.getSideBackGround(oldSides[offsetPIndex], otherFace);
- }
- else// 反向
- {
- backColor[j] = this.getSideBackGround(oldSides[offsetNIndex], otherFace);
- }
- }
- }
- for (var j = 0; j < 4; j++) {
- for (var k = 0; k < oldSides[j].length; k++) {
- oldSides[j][k][otherFace].style.background = backColor[j][k];
- }
- }
- }
- },
- animationEnd: function () {
- var offset = this.angle / 90, faceCubes = [], otherFace;
- var zSideFace = ["top", "left", "bottom", "right"], xSideFace = ["back", "top", "front", "bottom"], ySideFace = ["back", "left", "front", "right"], sideFace = [];
- for (var i = 0, len = this.cubeRotateStatus.length; i < len; i++) {
- var status = this.cubeRotateStatus[i];
- if (status) {
- var dimensionIndex = i + 1;
- switch (this.rotateFace) {
- case "rotateX": faceCubes = this.getXFace(dimensionIndex); sideFace = xSideFace; if (dimensionIndex == 1) otherFace = "left"; else if (dimensionIndex == this.dimension) otherFace = "right"; break;
- case "rotateY": faceCubes = this.getYFace(dimensionIndex); sideFace = ySideFace; if (dimensionIndex == 1) otherFace = "top"; else if (dimensionIndex == this.dimension) otherFace = "bottom"; break;
- case "rotateZ": faceCubes = this.getZFace(dimensionIndex); sideFace = zSideFace; if (dimensionIndex == 1) otherFace = "back"; else if (dimensionIndex == this.dimension) otherFace = "front"; break;
- }
- this.setRotateDirectSideBackGround(faceCubes, sideFace, offset, status);
- if (dimensionIndex == 1 || dimensionIndex == this.dimension)
- this.setRotateOtherDirectSideBackGround(faceCubes, otherFace, offset, status);
- }
- }
- // console.info(this.rollMoveStack.length + "," + this.moveDirect);
- if (this.moveDirect)
- this.moveMagicCube();
- else
- this.moveRollBackCube();
- // alert("运行结束");
- },
- bindAnimationEvent: function () {
- var loopMove = function () {
- cache.magicCube.isRunning--;// 由于按组转动, 顾要等组成员都完成再进行新的动画
- if (cache.magicCube.isRunning == 0)
- cache.magicCube.animationEnd();
- }
- for (var i = 0; i < this.count; i++) {
- this.prefixedEvent(this.cubes[i].Box, "AnimationEnd", loopMove, true);
- }
- cache.magicCube = this;// 缓存, 避免内存泄露
- },
- rotateBox: function (angle, rotateDirect, faceIndex, cubes) {
- if (cubes != null) {
- var startStatus = rotateDirect + "(0deg)", endStatus = rotateDirect + "(" + angle + "deg)";
- // this.changeAnimationStatus("mydhua", startStatus, endStatus)
- for (var i = 0, len = cubes.length; i < len; i++) {
- var ruleName = "roateRule" + faceIndex + i;
- this.isRunning++;// 组成员转动统计
- //if (cubes[i].rotateTransfrom != "")
- // startStatus = cubes[i].rotateTransfrom;
- cubes[i].rotateTransfrom = endStatus;
- if (this.findKeyframesRule(ruleName) == null)
- this.createKeyframesRule(ruleName, cubes[i].intalTransform + "" + startStatus, cubes[i].intalTransform +" " + endStatus);
- else
- this.changeAnimationStatus(ruleName, cubes[i].intalTransform + "" + startStatus, cubes[i].intalTransform +" " + endStatus);
- cubes[i].Box.style[this.browserPrefix + "AnimationName"] = "none";
- this.cubeMoveQueue.push({ cube: cubes[i], rule: ruleName });
- }
- }
- },
- findKeyframesRule: function (rule) {
- var ruleName = this.browserPrefix == ""?"KEYFRAMES_RULE": this.browserPrefix.toUpperCase() +"_KEYFRAMES_RULE";
- var ss = document.styleSheets;
- for (var i = 0; i < ss.length; ++i) {
- for (var j = 0; j < ss[i].cssRules.length; ++j) {
- if (ss[i].cssRules[j].type == window.CSSRule[ruleName] && ss[i].cssRules[j].name == rule) { return ss[i].cssRules[j]; }
- }
- }
- return null;
- },
- createKeyframesRule: function (rule, startStatus, endStatus) {
- var prefix = this.browserPrefix == ""?"" : "-" + this.browserPrefix + "-";
- var sheet;
- if (document.styleSheets.length < 1)
- sheet = this.createSheets();
- else
- sheet = document.styleSheets[0];
- var selectorText = "@" + prefix + "keyframes" + rule;
- var cssText = "0% {" + prefix + "transform:" + startStatus + "; } 100% {" + prefix + "transform:" + endStatus + "; }"
- if (sheet.insertRule) {
- sheet.insertRule(selectorText + "{" + cssText + "}", 0);
- } else if (sheet.addRule) {// 兼容 IE
- sheet.addRule(selectorText, cssText, 0);
- }
- },
- removeKeyframeRule: function (keyframes) {
- var length = keyframes.cssRules.length;
- var keyframeString = [];
- for (var i = 0; i < length; i++) {
- keyframeString.push(keyframes.cssRules[i].keyText);
- }
- // 移除动画帧规则
- for (var i = 0, j = length; i < j; i++) {
- if (this.browserPrefix == "webkit" || this.browserPrefix == "Moz")
- keyframes.deleteRule(keyframeString[i]);
- else
- keyframes.deleteRule(i); // 兼容 IE
- }
- },
- changeAnimationStatus: function (animationName, startStatus, endStatus) {
- var keyframes = this.findKeyframesRule(animationName);
- this.removeKeyframeRule(keyframes);
- // 重新设置帧规则
- var prefix = this.browserPrefix == ""?"" : "-" + this.browserPrefix + "-";
- keyframes.appendRule("0% {" + prefix + "transform:" + startStatus + "; }");
- keyframes.appendRule("100% {" + prefix + "transform:" + endStatus + "; }");
- },
- createSheets: function () {
- // 创建 <style> 标签
- var style = document.createElement("style");
- // 可以添加一个媒体 (/ 媒体查询, media query) 属性
- // style.setAttribute("media", "screen")
- // style.setAttribute("media", "only screen and (max-width : 1024px)")
- // 对 WebKit hack :(
- style.appendChild(document.createTextNode(""));
- // 将 <style> 元素加到页面中
- document.head.appendChild(style);
- return style.sheet;
- },
- prefixedEvent: function (element, type, callback, isAdd) {
- var pfx = ["webkit", "moz", "MS", "o", ""];
- for (var p = 0; p <pfx.length; p++) {
- if (!pfx[p]) type = type.toLowerCase();
- if (isAdd)
- element.addEventListener(pfx[p] + type, callback, false);
- else
- element.removeEventListener(pfx[p] + type, callback, false);
- }
- },
- start: function () {
- this.css();
- this.prefix();
- this.create3dScene();
- this.createMagicCube();
- this.drawBackGroundColor();
- this.bindAnimationEvent();// 绑定动画播放完成事件
- this.moveMagicCube(); // 立即开始动画
- // this.timer = setInterval(this.timerFun, 100);
- },
- timerFun: function () {
- var _this = cache.magicCube;
- if (_this.isRunning>= _this.dimension) {
- for (var i = 0, len = _this.cubeMoveQueue.length; i <len; i++) {
- var animation = _this.cubeMoveQueue.shift();
- animation.cube.Box.style[_this.browserPrefix + "Animation"] = animation.rule + "2s linear 1"; // Chrome, Safari 和 Opera 代码
- }
- }
- },
- css: function () {
- var d = document,
- doc = d.documentElement,
- body = d.body;
- this.clientWidth = doc.clientWidth;
- this.clientHeight = doc.clientHeight;
- if (d.compatMode != "CSS1Compat") {
- this.clientWidth = body.clientWidth;
- this.clientHeight = body.clientHeight;
- }
- // console.log(this.width +'////'+ this.height)
- },
- random: function (min, max) {
- return (Math.random() * (max - min + 1) + min)>> 0;
- },
- prefix: function () {
- var N = navigator.appName, ua = navigator.userAgent, tem;
- var M = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
- if (M && (tem = ua.match(/version\/([\.\d]+)/i)) != null) M[2] = tem[1];
- M = M ? [M[1], M[2]] : [N, navigator.appVersion, '-?'];
- M = M[0];
- if (M == "Chrome") { this.browserPrefix = "webkit"; }
- if (M == "Firefox") { this.browserPrefix = "Moz"; }
- if (M == "Safari") { this.browserPrefix = "webkit"; }
- if (M == "MSIE") { this.browserPrefix = "ms"; }
- }
- };
- }(window));
- </script>
- </head>
- <body style="background-color:black;width:100%;height:650px">
- <script>
- var cube = new magicCube({ parent: null, dimension: 3, cubWidth: 100, cubHeight: 100, marginLeft: 10, marginTop: 10, marginZ: 10, cubZ: 100 });
- </script>
- </body>
- </html>
注: 在此基础上可以加上鼠标控制事件, 可以直接通过鼠标控制器任意方向的旋扭, 也可以稍加改进用于炫酷展示图片! 后续有时间我将加上这些功能, 与大家再次分享!
来源: http://www.qdfuns.com/article/22725/96d12151797e491e278e5e8f592903f3.html