JavaScript

语言:

JaveScriptBabelCoffeeScript

确定

'use strict';

var CSIZE = 500 /* canvas size */ ,

OFF = .5 * CSIZE /* canvas origin offset */ ,

VPOINT = 2 * CSIZE /* vanishing point */ ,

_c = document.querySelector('canvas'),

ct = _c.getContext('2d'),

/* controls */

_frm = document.querySelector('form'),

_btn = document.querySelector('button'),

_auto = document.getElementById('auto'),

_err = document.querySelector('.err');

var s3d = undefined /* 3D shape */ ,

hue = 5 /* hue for 3D shape faces */ ,

rot = [1, 0, 1] /* default rotate axis */ ,

ang = .005 * Math.PI /* default unit rotation */ ,

rID = null /* request ID */ ,

drag = false /* drag status */ ,

sol = false /* status on lock */ ,

/* coords when starting drag */

x0 = null,

y0 = null;

var Point = function Point() {

var x = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];

var y = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];

var z = arguments.length <= 2 || arguments[2] === undefined ? 0 : arguments[2];

var c = [] /* natural set of coords */ ,

/*

* coords flattened to plane,

* taking perspective into account

*/

p = [];

this.setCoords = function(x, y, z) {

var f = z / VPOINT + 1;

c = [x, y, z];

p = [f * x, f * y, z];

};

this.getCoords = function() {

var f = arguments.length <= 0 || arguments[0] === undefined ? 1 : arguments[0];

return f ? c : p;

};

this.setCoords(x, y, z);

};

var Polygon = function Polygon(v) {

var n = v.length /* number of poly vertices */ ,

o = [0, 0, 0] /* central point of poly */ ;

/* recompute central point coordinates */

this.refreshO = function() {

o = [0, 0, 0];

var _loop = function _loop(i) {

o = o.map(function(c, j) {

return c + v[i].getCoords()[j];

});

};

for (var i = 0; i < n; i++) {

_loop(i);

}

};

/* get central point coordinates */

this.getO = function() {

return o;

};

/* draw this polygon */

this.draw = function() {

var _Math;

var

/*

* sign of central point z coord

* + leads to lightening

* - leads to darkening

*/

s = Math.sign(o[2]),

/* fill lightness */

l = 75 + s * (1 - (_Math = Math).hypot.apply(_Math, o.slice(0, 2)) / (.5 * CSIZE)) * 25;

ct.fillStyle = 'hsl(' + hue + ',65%,' + l + '%)';

ct.beginPath();

for (var i = 0; i < n; i++) {

var c = v[i].getCoords(0);

c.splice(2, 1); /* remove the z coord */

ct[(i ? 'line' : 'move') + 'To'].apply(ct, c);

}

ct.closePath();

ct.fill();

ct.stroke();

};

};

var S6hedron = function S6hedron() {

var rc = arguments.length <= 0 || arguments[0] === undefined ? .64 * OFF : arguments[0];

var v = [] /* array to store vertices */ ,

f = [] /* array to store faces */ ,

nf = 6 /* no. of faces */ ,

nv = 8 /* no of vertices */ ;

/*

* rotate the faces in 3D

* a = angle of rotation

* r = vector around which rotation happens

*/

this.rot = function() {

var a = arguments.length <= 0 || arguments[0] === undefined ? ang : arguments[0];

var r = arguments.length <= 1 || arguments[1] === undefined ? rot : arguments[1];

/*

* explanation for variables

* http://stackoverflow.com/a/15208858/1397351

*/

var sc = .5 * Math.sin(a),

db = 1 - Math.cos(a) /* double sq */ ,

sq = .5 * db,

/* get the x*y*sq, y*z*sq, z*x*sq in SO answer */

b = r.map(function(c, i, a) {

return c * a[(i + 1) % 3] * sq;

}),

/* get the x*sc, y*sc, z*sc in SO answer */

c = r.map(function(c) {

return c * sc;

}),

m = [ /* the transform matrix */

[1 - db * (r[1] * r[1] + r[2] * r[2]), 2 * (b[0] - c[2]), 2 * (b[2] + c[1])],

[2 * (b[0] + c[2]), 1 - db * (r[0] * r[0] + r[2] * r[2]), 2 * (b[1] - c[0])],

[2 * (b[2] - c[1]), 2 * (b[1] + c[0]), 1 - db * (r[0] * r[0] + r[1] * r[1])]

];

var _loop2 = function _loop2(i) {

var _v$i;

var /* coords before the rotation */

c0 = v[i].getCoords(),

/*

* multiply matrix m to vector c0

* see https://codepen.io/thebabydino/pen/WoxvPy

* to get coords after the rotation

*/

c1 = m.map(function(c) {

return c.map(function(c, i) {

return c * c0[i];

}).reduce(function(p, c) {

return p + c;

}, 0);

});

(_v$i = v[i]).setCoords.apply(_v$i, c1);

};

for (var i = 0; i < nv; i++) {

_loop2(i);

}

/* compute central point for each face */

/* all convex, so it's enough :P */

for (var i = 0; i < nf; i++) {

f[i].refreshO();

}

sortFaces();

this.draw();

};

this.draw = function() {

ct.clearRect(-OFF, -OFF, CSIZE, CSIZE);

for (var i = 0; i < nf; i++) {

f[i].draw();

}

};

/*

* reorder faces in array based on

* z coord values

* of the faces' central points

*/

function sortFaces() {

f.sort(function(a, b) {

if (a.getO()[2] > b.getO()[2]) return 1;

if (a.getO()[2] < b.getO()[2]) return -1;

return 0;

});

};

/*

* create each face from vertices

* and add each face to f array

*/

function addFaces() {

var /* number of vertices per face */

nvf6 = 4;

f.push(new Polygon(v.slice(0, nvf6)));

f.push(new Polygon(v.slice(nvf6, nv)));

for (var i = 0; i < nvf6; i++) {

f.push(new Polygon([v[i], v[(i + 1) % nvf6], v[nvf6 + (i + 1) % nvf6], v[nvf6 + i]]));

}

};

/*

* compute coords for each vertex

* and add each vertex to v array

*/

(function addVertices() {

var /* cube inradius */

ri6 = rc / Math.sqrt(3),

/* cube face circumradius */

rcf6 = ri6 * Math.SQRT2,

/* number of vertices per face */

nvf6 = 4,

/* face base angle */

baf6 = 2 * Math.PI / nvf6;

/* 2 vertices on top, 2 at the bottom */

for (var i = 0; i < 2; i++) {

/* y coord */

var y = Math.round(Math.pow(-1, i) * ri6);

for (var j = 0; j < nvf6; j++) {

var /* current angle */

ca = j * baf6,

x = Math.round(rcf6 * Math.cos(ca)) /* x coord */ ,

z = Math.round(rcf6 * Math.sin(ca)); /* z coord */

v.push(new Point(x, y, z));

}

}

addFaces();

})();

};

function ani() {

s3d.rot();

rID = requestAnimationFrame(ani);

};

function getE(ev) {

return ev.touches ? ev.touches[0] : ev;

};

/*

* stop cube animation if necessary

* in order to start drag

*/

function lock(ev) {

if (ev.target === _c) {

var e = getE(ev);

drag = true;

x0 = e.clientX;

y0 = e.clientY;

if (rID) {

sol = true;

_auto.checked = false;

cancelAnimationFrame(rID);

rID = null;

}

}

};

/* act on drag, rotate cube */

function act(ev) {

if (drag) {

var e = getE(ev),

x = e.clientX,

y = e.clientY,

dx = x - x0,

dy = y - y0,

d = Math.hypot(dx, dy);

if (d) {

var i = (-dy / d).toFixed(5) /* x comp of rot axis */ ,

j = (dx / d).toFixed(5) /* y comp of rot axis */ ,

a = (.0035 * d).toFixed(2) /* rotation angle in rad */ ;

s3d.rot(a, [i, j, 0]);

}

x0 = x;

y0 = y;

}

};

/*

* stop drag, restart autorotation if necessary

*/

function release() {

if (drag) {

drag = false;

x0 = y0 = null;

if (sol && !rID) {

_auto.checked = true;

sol = false;

ani();

}

}

};

/* what to do when slider values change */

function update(e) {

var _Math2;

var tg = e.target,

d = undefined;

switch (true) {

case tg.id == 'hue':

hue = ~~tg.value;

break;

case tg.id == 'alpha':

ct.globalAlpha = .01 * tg.value;

break;

case tg.id == 'w':

ang = .0005 * tg.value * Math.PI;

break;

case tg.id.indexOf('axis') > -1:

var i = 1 * tg.id.split('axis')[1],

copy = rot.slice();

copy[i] = .01 * tg.value;

d = (_Math2 = Math).hypot.apply(_Math2, copy);

if (d === 0) {

tg.value = 10;

_err.classList.add('show');

} else rot = copy.map(function(c) {

return c / d;

});

break;

}

};

/* fade the "drag me!" info in or out */

function fadeInf() {

document.body.classList.toggle('faded');

};

/* init demo */

(function init() {

/* initially have the "drag me!" info faded */

document.body.classList.add('faded');

/* set canvas dimensions */

_c.width = _c.height = CSIZE;

/* put 0,0 point in the middle of canvas */

ct.translate(OFF, OFF);

/* set global alpha of strokes and fills */

ct.globalAlpha = .87;

/* set rgba value for edges */

ct.strokeStyle = 'rgba(0,0,0,.1)';

/* create cube object */

s3d = new S6hedron();

/* start animation */

ani();

})();

addEventListener('mousedown', lock, false);

addEventListener('touchstart', lock, false);

addEventListener('mousemove', act, false);

addEventListener('touchmove', act, false);

addEventListener('mouseup', release, false);

addEventListener('touchend', release, false);

_auto.addEventListener('change', function(e) {

if (_auto.checked && !rID) ani();

if (!_auto.checked && rID) {

cancelAnimationFrame(rID);

rID = null;

}

}, false);

_btn.addEventListener('click', function(e) {

_frm.classList.toggle('closed');

}, false);

addEventListener('input', update, false);

addEventListener('change', update, false);

_c.addEventListener('mouseover', fadeInf, false);

_c.addEventListener('mouseout', fadeInf, false);

_err.addEventListener('animationend', function(e) {

_err.classList.remove('show');

}, false);

HTML5绘制一个3D立方体,HTML5/Canvas交互式3D立方体相关推荐

  1. html5绘制运动的图形,html5 canvas高级贝塞尔曲线运动动画

    canvas高级贝塞尔曲线运动动画 window.addEventListener('load',eventWindowLoaded,false);functioneventWindowLoaded( ...

  2. html5绘制节点链接,利用HTML5实现网状结构节点动画特效

    特效描述:利用HTML5实现 网状结构 节点动画特效.利用HTML5实现网状结构节点动画特效 代码结构 1. HTML代码 (function() { var canvas, ctx, circ, n ...

  3. 用java绘制一个光照球体_HTML5 Canvas一个基本光线行进的球体光照效果

    JavaScript 语言: JaveScriptBabelCoffeeScript 确定 var TWO_PI = 2 * Math.PI; var canvas; var canvasWidth; ...

  4. html制作星空,HTML5绘制星空

    HTML5绘制一个很丑的星空 canvas{display: block;border:1px dotted skyblue;} HTML5绘制星空 var nimo={}; window.οnlοa ...

  5. 互交式3d地球仪工具:Earth 3D - World Atlas Mac

    Earth 3D - World Atlas for Mac是一款3d地球仪.这个交互式 3D 地球仪以世界奇观.政治和物理地图以及天气为特色.发现许多关于我们星球的有趣事实和有用信息!原始的彩色图形 ...

  6. html页面画一个矩形,使用HTML5 canvas绘制一个矩形的方法

    使用HTML5 canvas绘制一个矩形的方法 发布时间:2020-08-29 11:23:12 来源:亿速云 阅读:102 作者:小新 这篇文章将为大家详细讲解有关使用HTML5 canvas绘制一 ...

  7. HTML1个像素宽的代码,HTML5 Canvas中绘制一个像素宽的细线实现代码详情

    正统的HTML5 Canvas中如下代码ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(10, 100); ctx.lineTo(300,100); ct ...

  8. html5制作一个立方体,CSS3 3D transforms系列教程-立方体

    学习制作3D翻转卡片是开始学习3D transform的一个好方法.一旦你掌握了3D翻转卡片的制作方法,是不是迫不及待的想制作更复杂的3D物体?我们在这个教程中将开始学习制作3D立方体. 3D立方体的 ...

  9. php 3d animation,如何用HTML5的Canvas制作3D动画效果

    HTML5的诞生给web前端界带来了不小轰动,像什么动画旋转.图片滑块.图片轮播等等这些3D特效,也引发了不少朋友想要学习HTML5的好奇心.最近我一直在做canvas动画效果,发现canvas这个东 ...

  10. html5画布画点,在HTML5画布上绘制一个点

    6 个答案: 答案 0 :(得分:141) 如果您打算绘制大量像素,使用画布的图像数据进行像素绘制会更有效率. var canvas = document.getElementById("m ...

最新文章

  1. 在Ubuntu中使用远程桌面
  2. npm install 原理(node_modules)
  3. Redis集群CentOS系统配置企业级数据备份方案以及数据恢复的操作(在开启AOF功能下恢复冷备RDB文件数据,保持AOF和RDB双开情况下恢复数据及错误的数据恢复步骤详解)
  4. 新浪微博客户端(eoe)
  5. 在MySQL登录时出现Access denied for user ‘root‘@‘localhost‘ (using password: YES)
  6. 全文搜索!收藏这篇Solr ElasticSearch 长文就可以搞定
  7. html如何设置滚动条居中,css3内容垂直居中及垂直滚动条例子
  8. 7 centos 时钟跟物理机同步_centos7上使用chrony自动同步时间
  9. html5如何绘制饼图,如何在HTML5中创建“饼图”?
  10. 【Java】浅析Java位移运算符<<、>>、>>>
  11. RPC的负载均衡策略
  12. vue 手动挂载组件 手动销毁组件_javascript原生手动分页组件
  13. TreeMap按照value进行排序
  14. 机器学习笔记(八):线性回归算法的评测标准 | 凌云时刻
  15. localtime选择00:00值不回显_配置OSPF的DR选择示例
  16. 数据结构导论(第一章概论)
  17. linux7如何改ssid,ssid怎么设置,教您网络ssid怎么设置
  18. 中台能力是什么?PaaS是什么?微服务是什么?
  19. cuda学习(5):使用cuda核函数加速warpaffine
  20. 13种MongoDB的GUI简介

热门文章

  1. qemu模拟器下编译运行基于riscv指令集的Linux操作系统
  2. HDU-5889 Barricade
  3. 11-Container With Most Water
  4. Base64序列化和反序列化
  5. java如何操作视图
  6. poj 3253 哈夫曼树 经典 运用了优先队列 总和最少
  7. C# in Depth
  8. 什么造就一个伟大的站点
  9. javascript 闭包和原型
  10. 准确率(accuracy),精确率(Precision),召回率(Recall)和F1-Measure