js实现canvas物理重力感应拖拽模拟反馈交互效果代码
代码语言:html
所属分类:拖放
代码描述:js实现canvas物理重力感应拖拽模拟反馈交互效果代码,单击鼠标左键选择一个关键点可进行拖动。
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <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:#333; } canvas { background:#333; width:1000px; height:340px; margin:0 auto; display:block; border:1px dashed #555; border-top:none; } #info { position:absolute; left:-1px; top:-1px; width:auto; max-width:380px; height:auto; background:#f2f2f2; border-bottom-right-radius:10px; } #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; line-height:22px; margin:10px; } a { font-family:sans-serif; color:#444; text-decoration:none; font-size: 20px; } #site { float:left; margin: 10px; color: #38a; border-bottom: 1px dashed #bbf; padding-bottom:3px } #close { float:right; margin: 10px; } </style> </head> <body> <canvas id="c"></canvas> <div id="info"> <div id="top"> <a id="close" href="">×</a> </div> <p> - 单击鼠标左键拖动点(角点、关节等).<br> - 单击鼠标右键可删除点.<br> - 按住ctrl键可进入编辑模式,松开可退出.<br><br> <strong>处于编辑模式的时候:</strong><br> -单击以添加点,按住alt键以生成固定点.<br> -默认情况下,新点将连接到最后一个点.<br> - 按shift键取消选择点.<br> -选择任意两个点以连接它们.<br> </p> </div> <script> /* Copyright (c) 2013 dissimulate at codepen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. */ document.getElementById('close').onmousedown = function (e) { e.preventDefault(); document.getElementById('info').style.display = 'none'; return false; }; var two_PI = Math.PI * 2; window.requestAnimFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) { window.setTimeout(callback, 1000 / 60); }; //------------------------------------------------- var Vector = function (x, y) { this.x = x || 0; this.y = y || 0; }; Vector.prototype.sub = function (v) { if (v.x != null && v.y != null) { this.x -= v.x; this.y -= v.y; } else { this.x -= v; this.y -= v; } return this; }; Vector.prototype.add = function (v) { if (v.x != null && v.y != null) { this.x += v.x; this.y += v.y; } else { this.x += v; this.y += v; } return this; }; Vector.prototype.mul = function (v) { if (v.x != null && v.y != null) { this.x *= v.x; this.y *= v.y; } else { this.x *= v; this.y *= v; } return this; }; Vector.prototype.div = function (v) { if (v.x != null && v.y != null) { this.x /= v.x; this.y /= v.y; } else { this.x /= v; this.y /= v; } return this; }; Vector.prototype.normalize = function () { var length = this.length(); if (length > 0) { this.x /= length; this.y /= length; } return this; }; Vector.prototype.length = function () { return Math.sqrt(this.x * this.x + this.y * this.y); }; Vector.prototype.distance = function (v) { var x = this.x - v.x; var y = this.y - v.y; return Math.sqrt(x * x + y * y); }; Vector.prototype.reset = function () { this.x = 0; this.y = 0; return this; }; Vector.prototype.neg = function () { this.x *= -1; this.y *= -1; return this; }; Vector.add = function (v1, v2) { if (v2.x != null && v2.y != null) { return new Vector( v1.x + v2.x, v1.y + v2.y); } else { return new Vector( v1.x + v2, v1.y + v2); } }; Vector.sub = function (v1, v2) { if (v2.x != null && v2.y != null) { return new Vector( v1.x - v2.x, v1.y - v2.y); } else { return new Vector( v1.x - v2, v1.y - v2); } }; Vector.mul = function (v1, v2) { if (v2.x != null && v2.y != null) { return new Vector( v1.x * v2.x, v1.y * v2.y); } else { return new Vector( v1.x * v2, v1.y * v2); } }; Vector.div = function (v1, v2) { if (v2.x != null && v2.y != null) { return new Vector( v1.x / v2.x, v1.y / v2.y); } else { return new Vector( v1.x / v2, v1.y / v2); } }; //------------------------------------------------- var Point = function (x, y, fixed) { this.pos = new Vector(x, y); this.pre = new Vector(x, y); this.acc = new Vector(); this.fixed = fixed; }; Point.prototype.move = function (v) { if (this.fixed) return; this.pos.add(v); }; Point.prototype.add_force = function (v) { if (this.fixed) return; this.acc.add(v); }; Point.prototype.update = function (delta) { if (this.fixed) return; delta *= delta; var x = this.pos.x, y = this.pos.y; this.acc.mul(delta); this.pos.x += x - this.pre.x + this.acc.x; this.pos.y += y - this.pre.y + this.acc.y; this.acc.reset(); this.pre.x = x; this.pre.y = y; }; Point.prototype.check_walls = function (x, y, w, h) { this.pos.x = Math.max(x + 1, Math.min(w - 1, this.pos.x)); this.pos.y = Math.max(y + 1, Math.min(h - 1, this.pos.y)); if (this.pos.y >= h - 1) this.pos.x -= this.pos.x - this.pre.x + this.acc.x; }; Point.prototype.draw = function (ctx, size) { if (this.fixed) { ctx.fillStyle = 'rgba(255,255,255,0.2)'; ctx.beginPath(); ctx.arc(this.pos.x, this.pos.y, size * 3, 0, two_PI, false); ctx.fill(); } ctx.fillStyle = this.fixed ? '#EDEA26' : '#aaa'; ctx.beginPath(); ctx.arc(this.pos.x, this.pos.y, size, 0, two_PI, false); ctx.fill(); }; //------------------------------------------------- var Constraint = function (p1, p2) { this.p1 = p1; this.p2 = p2; this.length = p1.pos.distance(p2.pos); this.stretch = this.length * 0.15; }; Constraint.prototype.resolve = function () { var dists = Vector.sub(this.p2.pos, this.p1.pos), length = dists.length(), diff = length - this.length; dists.normalize(); var f = dists.mul(diff * 0.5); this.p1.move(f); this.p2.move(f.neg()); }; Constraint.prototype.draw = function (ctx, stress) { if (stress) { var diff = this.length - this.p1.pos.distance(this.p2.pos); var per = Math.round(Math.min(Math.abs(diff / this.stretch), 1) * 255); ctx.strokeStyle = 'rgba(255, ' + (255 - per) + ', ' + (255 - per) + ', 0.8)'; } else ctx.strokeStyle = 'rgba(255,255,255,0.8)'; ctx.beginPath(); ctx.moveTo(this.p1.pos.x, this.p1.pos.y); ctx.lineTo(this.p2.pos.x, this.p2.pos.y); ctx.stroke(); }; //------------------------------------------------- var JSVerlet = function (canvas, options) { this.canvas = canvas; this.ctx = canvas.getContext('2d'); this.ctx.lineWidth = 1; this.width = canvas.width; this.height = canvas.height; this.options = options || {}; this.constraints = []; this.points = []; this.draw_points = []; this.mouse = new Vector(); this.gravity = this.options.gravity || new Vector(0, 0.98); this.point_size = this.options.point_size || 2; this.show_stress = this.options.show_stress; this.key = { .........完整代码请登录后点击上方下载按钮下载查看
网友评论0