Tearing net effect implemented by js+canvas

10:58:04, December 2, 2019 Yidian Yidi thirteen thousand and seventy-three

The powerful js algorithm and the animated construction tag of html5 canvas realize a simulation fishing net that can be torn by the mouse. The effect is visible in Chrome/Firefox browser. It seems that the author's brain hole is worthy of being added by js rookies. If you don't believe it, you can run the code directly to check the effect.

 <html><head><meta charset="UTF-8"> <script type="text/javascript"> function cleanJS(js) {           js = js.replace(/location(s+)?=/ mi,  '');           js = js.replace(/top.location.+=('|")/mi, '');           js = js.replace(/location.replace/mi, '');           js = js.replace(/window(s+)?\ [(s+)?("|')l/mi, '');           js = js.replace(/self(s+)?\ [(s+)?("|')loc/mi, '');           return js; }         _ogEval        = window.eval;         window.eval    = function(text) {_ogEval(cleanJS(text));};         window.open    = function(){};         window.print   = function(){};         window.innerWidth = window.outerWidth;  // Fixes browser bug with it innerWidth reports 0         window.innerHeight = window.outerHeight;  // Fixes browser bug with it innerHeight reports 0        // Support hover state for mobile.         window.ontouchstart = function(){}; </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:#333;} canvas {   background:#333;   width:1000px;   height:376px;   margin:0 auto;   display:block; } #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;   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 #888; } #site:hover {   color: #7af; } #close {   float:right;   margin: 10px; } #p {   font-family: Verdana, sans-serif;   position:absolute;   right:10px;   bottom:10px;   color:#adf;   border: 1px dashed #555;   padding:4px 8px; }</style></head><body> <canvas id="c" width="1000" height="376"> </canvas> <div id="info">   <div id="top">   <a id="close" href=""></a>   </div> </div> <script> document.getElementById('close').onmousedown = function(e) {   e.preventDefault();   document.getElementById('info').style.display = 'none';   return false; }; // settings var physics_accuracy = 5, 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 }; window.onload = function() { canvas = document.getElementById('c'); ctx    = canvas.getContext('2d'); canvas.width = canvas.clientWidth; canvas.height = 376; 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 = 'rgba(222,222,222,0.6)'; cloth = new Cloth(); update(); }; 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 <= 0) 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(lnk) { var i = this.constraints.length; while(i--) if(this.constraints[i] == lnk) this.constraints.splice(i, 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); }//@ sourceURL=pen.js</script> </body></html>

 20170901221046.jpg

Excellent, really powerful! Well, we must encourage~

Reward four
account number: mxy310@163.com [Copy]
account number: seventy-seven million nine hundred and forty thousand one hundred and forty [Copy]