原生JS,运动的小人
今天突然想起来,不知道在什么网站上看的一个纯纯的原生JS写的效果,运动的小人,所以在这里给大家分享一下代码:
并说明:
这不是本人写的,而是我在浏览网站是无意中发现的,现在已经不记得是哪个网站了,但是要说明,这不是本人的代码,求大神现身吧!!
先看效果图:先是统一动作
后随机动作:
并且鼠标可任意拉扯小人进行拖拽,拽到最上方时,鼠标不松手,即可会有两只小人从屏幕上方掉下来,一直是被你鼠标托上去那只,一直是
比拖的那只大两倍大小人!!
来看代码:
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title>The Last Experience</title>
<style>
html {
overflow: hidden;
} body {
position: absolute;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
background: #000;
} canvas {
position: absolute;
width: 100%;
height: 100%;
background: #000;
}
</style> </head> <body> <script>
'use strict'; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Robot = function () {
function Robot(color, light, size, x, y, struct) {
_classCallCheck(this, Robot); this.points = [];
this.links = [];
this.frame = 0;
this.dir = 1;
this.size = size;
this.color = Math.round(color);
this.light = light; // ---- points ----
var id = 0;
for (var _iterator = struct.points, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
var _ref; if (_isArray) {
if (_i >= _iterator.length) break;
_ref = _iterator[_i++];
} else {
_i = _iterator.next();
if (_i.done) break;
_ref = _i.value;
} var p = _ref; this.points.push(new Point(id++, size * p[0] + x, size * p[1] + y, p[2]));
} // ---- links ----
for (var _iterator2 = struct.links, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
var _ref2; if (_isArray2) {
if (_i2 >= _iterator2.length) break;
_ref2 = _iterator2[_i2++];
} else {
_i2 = _iterator2.next();
if (_i2.done) break;
_ref2 = _i2.value;
} var l = _ref2; var p0 = this.points[l[0]];
var p1 = this.points[l[1]];
var dx = p0.x - p1.x;
var dy = p0.y - p1.y;
this.links.push(new Link(this, p0, p1, Math.sqrt(dx * dx + dy * dy), l[2] * size / 3, l[3], l[4]));
}
} Robot.prototype.update = function update() { // ---- beat ----
if (++this.frame % 20 === 0) this.dir = -this.dir; // ---- create giants ----
if (dancerDrag && this === dancerDrag && this.size < 16 && this.frame > 600) {
dancerDrag = null;
dancers.push(new Robot(this.color, this.light * 1.25, this.size * 2, pointer.x, pointer.y - 100 * this.size * 2, struct));
dancers.sort(function (d0, d1) {
return d0.size - d1.size;
});
} // ---- update links ----
for (var _iterator3 = this.links, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
var _ref3; if (_isArray3) {
if (_i3 >= _iterator3.length) break;
_ref3 = _iterator3[_i3++];
} else {
_i3 = _iterator3.next();
if (_i3.done) break;
_ref3 = _i3.value;
} var link = _ref3; var p0 = link.p0;
var p1 = link.p1;
var dx = p0.x - p1.x;
var dy = p0.y - p1.y;
var dist = Math.sqrt(dx * dx + dy * dy); if (dist) { var tw = p0.w + p1.w;
var r1 = p1.w / tw;
var r0 = p0.w / tw;
var dz = (link.distance - dist) * link.force;
dx = dx / dist * dz;
dy = dy / dist * dz;
p1.x -= dx * r0;
p1.y -= dy * r0;
p0.x += dx * r1;
p0.y += dy * r1;
}
} // ---- update points ----
for (var _iterator4 = this.points, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
var _ref4; if (_isArray4) {
if (_i4 >= _iterator4.length) break;
_ref4 = _iterator4[_i4++];
} else {
_i4 = _iterator4.next();
if (_i4.done) break;
_ref4 = _i4.value;
} var point = _ref4; // ---- drag ----
if (this === dancerDrag && point === pointDrag) { point.x += (pointer.x - point.x) * 0.1;
point.y += (pointer.y - point.y) * 0.1;
} // ---- dance ----
if (this !== dancerDrag) { point.fn && point.fn(16 * Math.sqrt(this.size), this.dir);
} // ---- verlet integration ----
point.vx = point.x - point.px;
point.vy = point.y - point.py;
point.px = point.x;
point.py = point.y;
point.vx *= 0.995;
point.vy *= 0.995;
point.x += point.vx;
point.y += point.vy + 0.01;
} for (var _iterator5 = this.links, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
var _ref5; if (_isArray5) {
if (_i5 >= _iterator5.length) break;
_ref5 = _iterator5[_i5++];
} else {
_i5 = _iterator5.next();
if (_i5.done) break;
_ref5 = _i5.value;
} var link = _ref5; var p1 = link.p1; // ---- ground ----
if (p1.y > canvas.height * ground - link.size * 0.5) {
p1.y = canvas.height * ground - link.size * 0.5;
p1.x -= p1.vx;
p1.vx = 0;
p1.vy = 0;
} // ---- borders ----
if (p1.id === 1 || p1.id === 2) {
if (p1.x > canvas.width - link.size) p1.x = canvas.width - link.size;else if (p1.x < link.size) p1.x = link.size;
}
}
}; Robot.prototype.draw = function draw() { for (var _iterator6 = this.links, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) {
var _ref6; if (_isArray6) {
if (_i6 >= _iterator6.length) break;
_ref6 = _iterator6[_i6++];
} else {
_i6 = _iterator6.next();
if (_i6.done) break;
_ref6 = _i6.value;
} var link = _ref6; if (link.size) { var dx = link.p1.x - link.p0.x;
var dy = link.p1.y - link.p0.y;
var a = Math.atan2(dy, dx);
var d = Math.sqrt(dx * dx + dy * dy); // ---- shadow ----
ctx.save();
ctx.translate(link.p0.x + link.size * 0.25, link.p0.y + link.size * 0.25);
ctx.rotate(a);
ctx.drawImage(link.shadow, -link.size * 0.5, -link.size * 0.5, d + link.size, link.size);
ctx.restore(); // ---- stroke ----
ctx.save();
ctx.translate(link.p0.x, link.p0.y);
ctx.rotate(a);
ctx.drawImage(link.image, -link.size * 0.5, -link.size * 0.5, d + link.size, link.size);
ctx.restore();
}
}
}; return Robot;
}(); var Link = function Link(parent, p0, p1, dist, size, light, force) {
_classCallCheck(this, Link); // ---- cache strokes ----
function stroke(color, axis) { var image = document.createElement('canvas');
image.width = dist + size;
image.height = size;
var ict = image.getContext('2d');
ict.beginPath();
ict.lineCap = "round";
ict.lineWidth = size;
ict.strokeStyle = color;
ict.moveTo(size * 0.5, size * 0.5);
ict.lineTo(size * 0.5 + dist, size * 0.5);
ict.stroke();
if (axis) {
var s = size / 10;
ict.fillStyle = "#000";
ict.fillRect(size * 0.5 - s, size * 0.5 - s, s * 2, s * 2);
ict.fillRect(size * 0.5 - s + dist, size * 0.5 - s, s * 2, s * 2);
}
return image;
} this.p0 = p0;
this.p1 = p1;
this.distance = dist;
this.size = size;
this.light = light || 1.0;
this.force = force || 0.5;
this.image = stroke("hsl(" + parent.color + " ,30%, " + parent.light * this.light + "%)", true);
this.shadow = stroke("rgba(0,0,0,0.5)");
}; var Point = function Point(id, x, y, fn, w) {
_classCallCheck(this, Point); this.id = id;
this.x = x;
this.y = y;
this.w = w || 0.5;
this.fn = fn || null;
this.px = x;
this.py = y;
this.vx = 0;
this.vy = 0;
}; var Canvas = function () {
function Canvas() {
var _this = this; _classCallCheck(this, Canvas); this.elem = document.createElement('canvas');
this.ctx = this.elem.getContext('2d');
document.body.appendChild(this.elem);
this.resize();
window.addEventListener('resize', function () {
return _this.resize();
}, false);
} Canvas.prototype.resize = function resize() { this.width = this.elem.width = this.elem.offsetWidth;
this.height = this.elem.height = this.elem.offsetHeight;
ground = this.height > 500 ? 0.85 : 1.0;
}; return Canvas;
}(); var Pointer = function () {
function Pointer(canvas) {
var _this2 = this; _classCallCheck(this, Pointer); this.x = 0;
this.y = 0;
this.canvas = canvas; window.addEventListener('mousemove', function (e) {
return _this2.move(e);
}, false);
canvas.elem.addEventListener('touchmove', function (e) {
return _this2.move(e);
}, false);
window.addEventListener('mousedown', function (e) {
return _this2.down(e);
}, false);
window.addEventListener('touchstart', function (e) {
return _this2.down(e);
}, false);
window.addEventListener('mouseup', function (e) {
return _this2.up(e);
}, false);
window.addEventListener('touchend', function (e) {
return _this2.up(e);
}, false);
} Pointer.prototype.down = function down(e) { this.move(e); for (var _iterator7 = dancers, _isArray7 = Array.isArray(_iterator7), _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) {
var _ref7; if (_isArray7) {
if (_i7 >= _iterator7.length) break;
_ref7 = _iterator7[_i7++];
} else {
_i7 = _iterator7.next();
if (_i7.done) break;
_ref7 = _i7.value;
} var dancer = _ref7; for (var _iterator8 = dancer.points, _isArray8 = Array.isArray(_iterator8), _i8 = 0, _iterator8 = _isArray8 ? _iterator8 : _iterator8[Symbol.iterator]();;) {
var _ref8; if (_isArray8) {
if (_i8 >= _iterator8.length) break;
_ref8 = _iterator8[_i8++];
} else {
_i8 = _iterator8.next();
if (_i8.done) break;
_ref8 = _i8.value;
} var point = _ref8; var dx = pointer.x - point.x;
var dy = pointer.y - point.y;
var d = Math.sqrt(dx * dx + dy * dy);
if (d < 60) {
dancerDrag = dancer;
pointDrag = point;
dancer.frame = 0;
}
}
}
}; Pointer.prototype.up = function up(e) {
dancerDrag = null;
}; Pointer.prototype.move = function move(e) { var touchMode = e.targetTouches,
pointer = undefined;
if (touchMode) {
e.preventDefault();
pointer = touchMode[0];
} else pointer = e;
this.x = pointer.clientX;
this.y = pointer.clientY;
}; return Pointer;
}(); // ---- init ---- var ground = 1.0;
var canvas = new Canvas();
var ctx = canvas.ctx;
var pointer = new Pointer(canvas);
var dancerDrag = null;
var pointDrag = null; // ---- main loop ---- function run() { requestAnimationFrame(run);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#222";
ctx.fillRect(0, 0, canvas.width, canvas.height * 0.15);
ctx.fillRect(0, canvas.height * 0.85, canvas.width, canvas.height * 0.15); for (var _iterator9 = dancers, _isArray9 = Array.isArray(_iterator9), _i9 = 0, _iterator9 = _isArray9 ? _iterator9 : _iterator9[Symbol.iterator]();;) {
var _ref9; if (_isArray9) {
if (_i9 >= _iterator9.length) break;
_ref9 = _iterator9[_i9++];
} else {
_i9 = _iterator9.next();
if (_i9.done) break;
_ref9 = _i9.value;
} var dancer = _ref9; dancer.update();
dancer.draw();
}
} // ---- robot structure ---- var struct = { points: [[0, -4, function (s, d) {
this.y -= 0.01 * s;
}], [0, -16, function (s, d) {
this.y -= 0.02 * s * d;
}], [0, 12, function (s, d) {
this.y += 0.02 * s * d;
}], [-12, 0], [12, 0], [-3, 34, function (s, d) {
if (d > 0) {
this.x += 0.01 * s;
this.y -= 0.015 * s;
} else {
this.y += 0.02 * s;
}
}], [3, 34, function (s, d) {
if (d > 0) {
this.y += 0.02 * s;
} else {
this.x -= 0.01 * s;
this.y -= 0.015 * s;
}
}], [-28, 0, function (s, d) {
this.x += this.vx * 0.035;
this.y -= 0.001 * s;
}], [28, 0, function (s, d) {
this.x += this.vx * 0.035;
this.y -= 0.001 * s;
}], [-3, 64, function (s, d) {
this.y += 0.02 * s;
if (d > 0) {
this.y -= 0.01 * s;
} else {
this.y += 0.05 * s;
}
}], [3, 64, function (s, d) {
this.y += 0.02 * s;
if (d > 0) {
this.y += 0.05 * s;
} else {
this.y -= 0.01 * s;
}
}], [0, -4.1]], links: [[3, 7, 12, 0.5], [1, 3, 24, 0.5], [1, 0, 18, 0.5], [0, 11, 60, 0.8], [5, 9, 16, 0.5], [2, 5, 32, 0.5], [1, 2, 50, 1], [6, 10, 16, 1.5], [2, 6, 32, 1.5], [4, 8, 12, 1.5], [1, 4, 24, 1.5]]
}; // ---- instanciate robots ----
var dancers = []; for (var i = 0; i < 6; i++) {
dancers.push(new Robot(i * 360 / 7, 80, 4, (i + 2) * canvas.width / 9, canvas.height * ground - 295, struct));
} run();
</script> </body>
</html>
我还没研究透彻!!这位大神 不会是外国人吧??
原生JS,运动的小人的更多相关文章
- 原生js运动框架
function getStyle(obj,name){ if(obj.currentStyle) { return obj.currentStyle[name]; } else { return g ...
- 使用原生JS实现一个风箱式的demo,并封装了一个运动框架
声明,该DEMO依托于某个培训机构中,非常感谢这个培训结构.话不多说,现在开始改demo的制作. 首先,在前端的学习过程中,轮播图是我们一定要学习的,所以为了更加高效的实现各种轮播图,封装了一个运动的 ...
- 原生js实现一个DIV的碰撞反弹运动,并且添加重力效果
继上一篇... 原生js实现一个DIV的碰撞反弹运动,并且添加重力效果 关键在于边界检测,以及乘以的系数问题,实现代码并不难,如下: <!DOCTYPE html> <html la ...
- 原生js实现一个DIV的碰撞反弹运动
原生js实现一个DIV的碰撞反弹运动: 关键在于DIV的边界检测,进而改变运动方向,即可实现碰撞反弹效果. <!DOCTYPE html> <html lang="en& ...
- 原生js动画效果(源码解析)
在做页面中,多数情况下都会遇到页面上做动画效果,大部分都是用jquery来实现动画,今天正好看到一篇原生js实现动画效果的代码,特分享在此. 原文地址:http://www.it165.net/pro ...
- 利用tween,使用原生js实现模块回弹动画效果
最近有一个需求,就是当屏幕往下一定像素时,下方会有一个隐藏的模块马上显现出来,向上运动后带有回弹效果.然后屏幕滚回去时这个模块能够原路返回 其实这个效果css3就可以很轻松实现,但是公司要求最低兼容i ...
- 原生JS面向对象思想封装轮播图组件
原生JS面向对象思想封装轮播图组件 在前端页面开发过程中,页面中的轮播图特效很常见,因此我就想封装一个自己的原生JS的轮播图组件.有了这个需求就开始着手准备了,代码当然是以简洁为目标,轮播图的各个功能 ...
- 原生js判断css动画结束 css 动画结束的回调函数
原文:原生js判断css动画结束 css 动画结束的回调函数 css3 的时代,css3--动画 一切皆有可能: 传统的js 可以通过回调函数判断动画是否结束:即使是采用CSS技术生成动画效果,Jav ...
- js___原生js轮播
原生js轮播 作为一名前端工程师,手写轮播图应该是最基本掌握的技能,以下是我自己原生js写的轮播,欢迎指点批评: 首先css代码 a{text-decoration:none;color:#3DBBF ...
随机推荐
- redis存储的数据类型
key-velue数据结构存储 key 只能是字符串 value 有5种数据leixing. 字符串 string 哈希 hash 列表 list 集合 set 有序集合 zset
- NASA的10条代码编写原则
NASA的10条代码编写原则 作者: Gerard J. Holzmann 来源: InfoQ 原文链接 英文原文:NASA's 10 Coding Rules for Writing Safety ...
- AC自动机模板题
AC自动机学习博客 AC自动机理解要点: 1)fail指针指向的是每个节点,在字典树上和这个节点后缀相同的最长单词,每次都这样匹配,必定不会漏过答案. 2)字典树建立后,会在bfs求fail阶段把字典 ...
- DES加密之强制更新下载分离器
数据加密算法(Data Encryption Algorithm,DEA)是一种对称加密算法,很可能是使用最广泛的密钥系统,特别是在保护金融数据的安全中,最初开发的DEA是嵌入硬件中的.通常,自动取款 ...
- Comparison of Symbolic Deep Learning Frameworks
http://blog.revolutionanalytics.com/2016/08/deep-learning-part-1.html Deep Learning Part 1: Comparis ...
- 浅谈Supermap iClient for JavaScript 弹窗类
地图作为信息的载体和呈现方式,是GIS的重要组成部分,它是一个浏览信息的窗口,在信息日益发达的今天 ,各种地图应用如雨后春笋一般出现在大众眼前,而不是像以往一样太过局限于专业的领域.而弹窗,是作为地图 ...
- SqlHelper中SqlHelperParameterCache类的用法介绍
SqlHelper类中提供了三种可以用来管理SqlParameter参数的共享方法.下面来一一讲解: 1.CacheParameterSet 将SqlParameter参数数组存储到本地缓存中 2.G ...
- input输入提示历史记录
一般便于用户的输入习惯,我们都会提示历史消息,让用户有更好的使用体验,以前可能比较多朋友会用js来实现,现在HTML5的datalist可以轻松帮我们实现这个功能!只需以下几行代码 <!doct ...
- Azure SQL Federation(联合)
说Federation(联合)之前,先说下,表的垂直分割 和 水平分割----------------------------------------------------------------- ...
- [PY3]——创建多值映射字典?/defaultdict默认字典/setdefault()
Defaultdict 默认字典 collections 模块中的 defaultdict(默认字典),可以用来构造“一个键映射多个值”这样的字典 如果你想保持元素的插入顺序就应该使用list, 如果 ...