<!DOCTYPE html>
<!-- saved from url=(0062)http://www.17sucai.com/preview/1266961/2018-06-13/lv/demo.html -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>简单的绳状物理学</title>
<style>
html {
overflow: hidden;
touch-action: none;
content-zooming: none;
font-family: sans-serif;
font-size: 12px;
}
body {
position: absolute;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
text-align: center;
color: #FFF;
}
#canvas {
/* position: absolute;
top: 0; right: 0; left: 0;
margin: auto; */
margin: auto;
margin-bottom: 1em;
max-width: 100%;
height: auto;
/* background:#000; */
}</style>
<meta name="__hash__" content="275829474f87fbfcdfddf5857585c550_185d749c27a6936a0789742a59838118" /></head>
<body>
<canvas id="canvas" width="900" height="500"></canvas>
<script>
"use strict";
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
console.clear();
var TWOPI = Math.PI * 2;
function distance(x1, y1, x2, y2) {
var dx = x1 - x2;
var dy = y1 - y2;
return Math.sqrt(dx * dx + dy * dy);
}
var gravity = 0.5;
// VNode class
var VNode = function () {
function VNode(node) {
_classCallCheck(this, VNode);
this.x = node.x || 0;
this.y = node.y || 0;
this.oldX = this.x;
this.oldY = this.y;
this.w = node.w || 2;
this.angle = node.angle || 0;
this.gravity = node.gravity || gravity;
this.mass = node.mass || 1.0;
this.color = node.color;
this.letter = node.letter;
this.pointerMove = node.pointerMove;
this.fixed = node.fixed;
}
// verlet integration
_createClass(VNode, [{
key: 'integrate',
value: function integrate(pointer) {
if (this.lock && (!this.lockX || !this.lockY)) {
this.lockX = this.x;
this.lockY = this.y;
}
if (this.pointerMove && pointer && distance(this.x, this.y, pointer.x, pointer.y) < this.w + pointer.w) {
this.x += (pointer.x - this.x) / (this.mass * 18);
this.y += (pointer.y - this.y) / (this.mass * 18);
} else if (this.lock) {
this.x += (this.lockX - this.x) * this.lock;
this.y += (this.lockY - this.y) * this.lock;
}
if (!this.fixed) {
var x = this.x;
var y = this.y;
this.x += this.x - this.oldX;
this.y += this.y - this.oldY + this.gravity;
this.oldX = x;
this.oldY = y;
}
}
}, {
key: 'set',
value: function set(x, y) {
this.oldX = this.x = x;
this.oldY = this.y = y;
}
// draw node
}, {
key: 'draw',
value: function draw(ctx) {
if (!this.color) {
return;
}
// ctx.globalAlpha = 0.8;
ctx.translate(this.x, this.y);
ctx.rotate(this.angle);
ctx.fillStyle = this.color;
ctx.beginPath();
if (this.letter) {
ctx.globalAlpha = 1;
ctx.rotate(Math.PI / 2);
ctx.rect(-7, 0, 14, 1);
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = 'bold 75px "Bebas Neue", monospace';
ctx.fillStyle = '#000';
ctx.fillText(this.letter, 0, this.w * .25 + 4);
ctx.fillStyle = this.color;
ctx.fillText(this.letter, 0, this.w * .25);
} else {
ctx.globalAlpha = 0.2;
ctx.rect(-this.w, -this.w, this.w * 2, this.w * 2);
// ctx.arc(this.x, this.y, this.w, 0, 2 * Math.PI);
}
ctx.closePath();
ctx.fill();
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
}]);
return VNode;
}();
// constraint class
var Constraint = function () {
function Constraint(n0, n1, stiffness) {
_classCallCheck(this, Constraint);
this.n0 = n0;
this.n1 = n1;
this.dist = distance(n0.x, n0.y, n1.x, n1.y);
this.stiffness = stiffness || 0.5;
this.firstRun = true;
}
// solve constraint
_createClass(Constraint, [{
key: 'solve',
value: function solve() {
var dx = this.n0.x - this.n1.x;
var dy = this.n0.y - this.n1.y;
var newAngle = Math.atan2(dy, dx);
this.n1.angle = newAngle;
var currentDist = distance(this.n0.x, this.n0.y, this.n1.x, this.n1.y);
var delta = this.stiffness * (currentDist - this.dist) / currentDist;
dx *= delta;
dy *= delta;
if (this.firstRun) {
this.firstRun = false;
if (!this.n1.fixed) {
this.n1.x += dx;
this.n1.y += dy;
}
if (!this.n0.fixed) {
this.n0.x -= dx;
this.n0.y -= dy;
}
return;
}
var m1 = this.n0.mass + this.n1.mass;
var m2 = this.n0.mass / m1;
m1 = this.n1.mass / m1;
if (!this.n1.fixed) {
this.n1.x += dx * m2;
this.n1.y += dy * m2;
}
if (!this.n0.fixed) {
this.n0.x -= dx * m1;
this.n0.y -= dy * m1;
}
}
// draw constraint
}, {
key: 'draw',
value: function draw(ctx) {
ctx.globalAlpha = 0.9;
ctx.beginPath();
ctx.moveTo(this.n0.x, this.n0.y);
ctx.lineTo(this.n1.x, this.n1.y);
ctx.strokeStyle = "#fff";
ctx.stroke();
}
}]);
return Constraint;
}();
var Rope = function () {
function Rope(rope) {
_classCallCheck(this, Rope);
var x = rope.x,
y = rope.y,
length = rope.length,
points = rope.points,
vertical = rope.vertical,
fixedEnds = rope.fixedEnds,
startNode = rope.startNode,
letter = rope.letter,
endNode = rope.endNode,
stiffness = rope.stiffness,
constrain = rope.constrain,
gravity = rope.gravity,
pointerMove = rope.pointerMove;
this.stiffness = stiffness || 1;
this.nodes = [];
this.constraints = [];
if (letter === ' ') {
return this;
}
var dist = length / points;
for (var i = 0, _last = points - 1; i < points; i++) {
var size = letter && i === _last ? 15 : 2;
var spacing = dist * i + size;
var node = new VNode({
w: size,
mass: .1, //(i === last ? .5 : .1),
fixed: fixedEnds && (i === 0 || i === _last)
});
node = i === 0 && startNode || i === _last && endNode || node;
node.gravity = gravity;
//node.pointerMove = pointerMove;
if (i === _last && letter) {
node.letter = letter;
node.color = 'pink';
node.pointerMove = true;
}
node.oldX = node.x = x + (!vertical ? spacing : 0);
node.oldY = node.y = y + (vertical ? spacing : 0);
this.nodes.push(node);
}
constrain ? this.makeConstraints() : null;
}
_createClass(Rope, [{
key: 'makeConstraints',
value: function makeConstraints() {
for (var i = 1; i < this.nodes.length; i++) {
this.constraints.push(new Constraint(this.nodes[i - 1], this.nod
评论0