Team:UCLA/sams extra css
From 2014.igem.org
(Difference between revisions)
Samichaels (Talk | contribs) |
Samichaels (Talk | contribs) |
||
Line 1: | Line 1: | ||
<html> | <html> | ||
+ | <canvas id="c"></canvas> | ||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> | <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> | ||
- | < | + | <style> |
- | + | * { | |
- | + | margin: 0; | |
- | + | overflow: hidden; | |
- | + | -webkit-user-select: none; | |
- | } | + | -moz-user-select: none; |
+ | -ms-user-select: none; | ||
+ | -o-user-select: none; | ||
+ | user-select: none; | ||
+ | } | ||
+ | body { | ||
+ | background: #F2F2F2; | ||
+ | } | ||
+ | #c { | ||
+ | display: block; | ||
+ | margin: 20px auto 0; | ||
+ | } | ||
+ | #info { | ||
+ | position: absolute; | ||
+ | left: -1px; | ||
+ | top: -1px; | ||
+ | width: auto; | ||
+ | max-width: 420px; | ||
+ | height: auto; | ||
+ | background: #f2f2f2; | ||
+ | border-bottom-right-radius: 10px; | ||
+ | border:1px solid #333; | ||
+ | } | ||
+ | #top { | ||
+ | background: #fff; | ||
+ | width: 100%; | ||
+ | height: auto; | ||
+ | position: relative; | ||
+ | border-bottom: 1px solid #eee; | ||
+ | } | ||
+ | p { | ||
+ | font-family: Arial, sans-serif; | ||
+ | color: #666; | ||
+ | text-align: justify; | ||
+ | font-size: 16px; | ||
+ | margin: 10px; | ||
+ | } | ||
+ | #github { | ||
+ | color:#3377ee; | ||
+ | font-family: Helvetica, Arial, sans-serif; | ||
+ | font-size: 19px; | ||
+ | display: block; | ||
+ | margin: 0 auto; | ||
+ | text-align: center; | ||
+ | text-decoration:none; | ||
+ | } | ||
+ | #net { | ||
+ | text-align:center; | ||
+ | white-space:nowrap; | ||
+ | font-size:19px; | ||
+ | background:rgba(0,0,0,0.1); | ||
+ | padding:8px 12px; | ||
+ | border-radius:8px; | ||
+ | display:block; | ||
+ | color:#888; | ||
+ | } | ||
+ | #net > span { | ||
+ | color:#3377ee; | ||
+ | font-family: Helvetica, Arial, sans-serif; | ||
+ | font-size: 14px; | ||
+ | display: block; | ||
+ | margin: 0 auto; | ||
+ | text-align: center; | ||
+ | text-decoration:none; | ||
+ | } | ||
+ | a { | ||
+ | font-family: sans-serif; | ||
+ | color: #444; | ||
+ | text-decoration: none; | ||
+ | font-size: 20px; | ||
+ | } | ||
+ | #site { | ||
+ | float: left; | ||
+ | margin: 10px; | ||
+ | color: #ff9900; | ||
+ | border-bottom: 1px dashed #ccc; | ||
+ | padding-bottom:3px | ||
+ | } | ||
+ | #site:hover { | ||
+ | color: #ffaa11; | ||
+ | } | ||
+ | #close { | ||
+ | float: right; | ||
+ | margin: 10px; | ||
+ | } | ||
+ | #p { | ||
+ | font-family: Verdana, sans-serif; | ||
+ | position: absolute; | ||
+ | right: 10px; | ||
+ | bottom: 10px; | ||
+ | color: #4099ff; | ||
+ | border: 1px dashed #4099ff; | ||
+ | padding: 4px 8px; | ||
+ | } | ||
+ | </style> | ||
- | + | <script> | |
+ | document.getElementById('close').onmousedown = function(e) { | ||
+ | e.preventDefault(); | ||
+ | document.getElementById('info').style.display = 'none'; | ||
+ | return false; | ||
+ | }; | ||
+ | // settings | ||
- | + | var physics_accuracy = 3, | |
- | + | mouse_influence = 20, | |
+ | mouse_cut = 5, | ||
+ | gravity = 1200, | ||
+ | cloth_height = 30, | ||
+ | cloth_width = 50, | ||
+ | start_y = 20, | ||
+ | spacing = 7, | ||
+ | tear_distance = 60; | ||
- | + | ||
- | + | window.requestAnimFrame = | |
- | + | window.requestAnimationFrame || | |
- | + | window.webkitRequestAnimationFrame || | |
- | + | window.mozRequestAnimationFrame || | |
- | + | window.oRequestAnimationFrame || | |
- | + | window.msRequestAnimationFrame || | |
+ | function (callback) { | ||
+ | window.setTimeout(callback, 1000 / 60); | ||
+ | }; | ||
+ | |||
+ | var canvas, | ||
+ | ctx, | ||
+ | cloth, | ||
+ | boundsx, | ||
+ | boundsy, | ||
+ | mouse = { | ||
+ | down: false, | ||
+ | button: 1, | ||
+ | x: 0, | ||
+ | y: 0, | ||
+ | px: 0, | ||
+ | py: 0 | ||
+ | }; | ||
+ | |||
+ | var Point = function (x, y) { | ||
+ | |||
+ | this.x = x; | ||
+ | this.y = y; | ||
+ | this.px = x; | ||
+ | this.py = y; | ||
+ | this.vx = 0; | ||
+ | this.vy = 0; | ||
+ | this.pin_x = null; | ||
+ | this.pin_y = null; | ||
+ | |||
+ | this.constraints = []; | ||
+ | }; | ||
+ | |||
+ | Point.prototype.update = function (delta) { | ||
+ | |||
+ | if (mouse.down) { | ||
+ | |||
+ | var diff_x = this.x - mouse.x, | ||
+ | diff_y = this.y - mouse.y, | ||
+ | dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y); | ||
+ | |||
+ | if (mouse.button == 1) { | ||
+ | |||
+ | if (dist < mouse_influence) { | ||
+ | this.px = this.x - (mouse.x - mouse.px) * 1.8; | ||
+ | this.py = this.y - (mouse.y - mouse.py) * 1.8; | ||
} | } | ||
+ | |||
+ | } else if (dist < mouse_cut) this.constraints = []; | ||
+ | } | ||
+ | |||
+ | this.add_force(0, gravity); | ||
+ | |||
+ | delta *= delta; | ||
+ | nx = this.x + ((this.x - this.px) * .99) + ((this.vx / 2) * delta); | ||
+ | ny = this.y + ((this.y - this.py) * .99) + ((this.vy / 2) * delta); | ||
+ | |||
+ | this.px = this.x; | ||
+ | this.py = this.y; | ||
+ | |||
+ | this.x = nx; | ||
+ | this.y = ny; | ||
+ | |||
+ | this.vy = this.vx = 0 | ||
+ | }; | ||
+ | |||
+ | Point.prototype.draw = function () { | ||
+ | |||
+ | if (!this.constraints.length) return; | ||
+ | |||
+ | var i = this.constraints.length; | ||
+ | while (i--) this.constraints[i].draw(); | ||
+ | }; | ||
+ | |||
+ | Point.prototype.resolve_constraints = function () { | ||
+ | |||
+ | if (this.pin_x != null && this.pin_y != null) { | ||
+ | |||
+ | this.x = this.pin_x; | ||
+ | this.y = this.pin_y; | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | var i = this.constraints.length; | ||
+ | while (i--) this.constraints[i].resolve(); | ||
+ | |||
+ | this.x > boundsx ? this.x = 2 * boundsx - this.x : 1 > this.x && (this.x = 2 - this.x); | ||
+ | this.y < 1 ? this.y = 2 - this.y : this.y > boundsy && (this.y = 2 * boundsy - this.y); | ||
+ | }; | ||
+ | |||
+ | Point.prototype.attach = function (point) { | ||
+ | |||
+ | this.constraints.push( | ||
+ | new Constraint(this, point) | ||
+ | ); | ||
+ | }; | ||
+ | |||
+ | Point.prototype.remove_constraint = function (constraint) { | ||
+ | |||
+ | this.constraints.splice(this.constraints.indexOf(constraint), 1); | ||
+ | }; | ||
+ | |||
+ | Point.prototype.add_force = function (x, y) { | ||
+ | |||
+ | this.vx += x; | ||
+ | this.vy += y; | ||
+ | }; | ||
+ | |||
+ | Point.prototype.pin = function (pinx, piny) { | ||
+ | this.pin_x = pinx; | ||
+ | this.pin_y = piny; | ||
+ | }; | ||
+ | |||
+ | var Constraint = function (p1, p2) { | ||
+ | |||
+ | this.p1 = p1; | ||
+ | this.p2 = p2; | ||
+ | this.length = spacing; | ||
+ | }; | ||
+ | |||
+ | Constraint.prototype.resolve = function () { | ||
+ | |||
+ | var diff_x = this.p1.x - this.p2.x, | ||
+ | diff_y = this.p1.y - this.p2.y, | ||
+ | dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y), | ||
+ | diff = (this.length - dist) / dist; | ||
+ | |||
+ | if (dist > tear_distance) this.p1.remove_constraint(this); | ||
+ | |||
+ | var px = diff_x * diff * 0.5; | ||
+ | var py = diff_y * diff * 0.5; | ||
+ | |||
+ | this.p1.x += px; | ||
+ | this.p1.y += py; | ||
+ | this.p2.x -= px; | ||
+ | this.p2.y -= py; | ||
+ | }; | ||
+ | |||
+ | Constraint.prototype.draw = function () { | ||
+ | |||
+ | ctx.moveTo(this.p1.x, this.p1.y); | ||
+ | ctx.lineTo(this.p2.x, this.p2.y); | ||
+ | }; | ||
+ | |||
+ | var Cloth = function () { | ||
+ | |||
+ | this.points = []; | ||
+ | |||
+ | var start_x = canvas.width / 2 - cloth_width * spacing / 2; | ||
+ | |||
+ | for (var y = 0; y <= cloth_height; y++) { | ||
+ | |||
+ | for (var x = 0; x <= cloth_width; x++) { | ||
+ | |||
+ | var p = new Point(start_x + x * spacing, start_y + y * spacing); | ||
+ | |||
+ | x != 0 && p.attach(this.points[this.points.length - 1]); | ||
+ | y == 0 && p.pin(p.x, p.y); | ||
+ | y != 0 && p.attach(this.points[x + (y - 1) * (cloth_width + 1)]) | ||
+ | |||
+ | this.points.push(p); | ||
} | } | ||
- | } | + | } |
- | + | }; | |
+ | Cloth.prototype.update = function () { | ||
+ | |||
+ | var i = physics_accuracy; | ||
+ | |||
+ | while (i--) { | ||
+ | var p = this.points.length; | ||
+ | while (p--) this.points[p].resolve_constraints(); | ||
+ | } | ||
+ | |||
+ | i = this.points.length; | ||
+ | while (i--) this.points[i].update(.016); | ||
+ | }; | ||
+ | |||
+ | Cloth.prototype.draw = function () { | ||
+ | |||
+ | ctx.beginPath(); | ||
+ | |||
+ | var i = cloth.points.length; | ||
+ | while (i--) cloth.points[i].draw(); | ||
+ | |||
+ | ctx.stroke(); | ||
+ | }; | ||
+ | |||
+ | function update() { | ||
+ | |||
+ | ctx.clearRect(0, 0, canvas.width, canvas.height); | ||
+ | |||
+ | cloth.update(); | ||
+ | cloth.draw(); | ||
+ | |||
+ | requestAnimFrame(update); | ||
+ | } | ||
+ | |||
+ | function start() { | ||
+ | |||
+ | canvas.onmousedown = function (e) { | ||
+ | mouse.button = e.which; | ||
+ | mouse.px = mouse.x; | ||
+ | mouse.py = mouse.y; | ||
+ | var rect = canvas.getBoundingClientRect(); | ||
+ | mouse.x = e.clientX - rect.left, | ||
+ | mouse.y = e.clientY - rect.top, | ||
+ | mouse.down = true; | ||
+ | e.preventDefault(); | ||
+ | }; | ||
+ | |||
+ | canvas.onmouseup = function (e) { | ||
+ | mouse.down = false; | ||
+ | e.preventDefault(); | ||
+ | }; | ||
+ | |||
+ | canvas.onmousemove = function (e) { | ||
+ | mouse.px = mouse.x; | ||
+ | mouse.py = mouse.y; | ||
+ | var rect = canvas.getBoundingClientRect(); | ||
+ | mouse.x = e.clientX - rect.left, | ||
+ | mouse.y = e.clientY - rect.top, | ||
+ | e.preventDefault(); | ||
+ | }; | ||
+ | |||
+ | canvas.oncontextmenu = function (e) { | ||
+ | e.preventDefault(); | ||
+ | }; | ||
+ | |||
+ | boundsx = canvas.width - 1; | ||
+ | boundsy = canvas.height - 1; | ||
+ | |||
+ | ctx.strokeStyle = '#888'; | ||
+ | |||
+ | cloth = new Cloth(); | ||
+ | |||
+ | update(); | ||
+ | } | ||
+ | |||
+ | window.onload = function () { | ||
+ | |||
+ | canvas = document.getElementById('c'); | ||
+ | ctx = canvas.getContext('2d'); | ||
+ | |||
+ | canvas.width = 560; | ||
+ | canvas.height = 350; | ||
+ | |||
+ | start(); | ||
+ | }; | ||
+ | </script> | ||
</html> | </html> |
Revision as of 21:21, 8 August 2014