Advertisement
Guest User

Ткань

a guest
Mar 20th, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 9.14 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html lang="en" >
  3.  
  4. <head>
  5.   <meta charset="UTF-8">
  6.   <title>Ткань</title>
  7.  
  8.  
  9.  
  10.       <link rel="stylesheet" href="css/style.css">
  11. <style>
  12. * {
  13.     margin: 0;
  14.     overflow: hidden;
  15.     -webkit-user-select: none;
  16.     -moz-user-select: none;
  17.     -ms-user-select: none;
  18.     -o-user-select: none;
  19.     user-select: none;
  20. }
  21. body {
  22.     background: #F2F2F2;
  23. }
  24. #c {
  25.     display: block;
  26.     margin: 20px auto 0;
  27. }
  28. #info {
  29.     position: absolute;
  30.     left: -1px;
  31.     top: -1px;
  32.     width: auto;
  33.     max-width: 420px;
  34.     height: auto;
  35.     background: #f2f2f2;
  36.     border-bottom-right-radius: 10px;
  37.     border:1px solid #333;
  38. }
  39. #top {
  40.     background: #fff;
  41.     width: 100%;
  42.     height: auto;
  43.     position: relative;
  44.     border-bottom: 1px solid #eee;
  45. }
  46. p {
  47.     font-family: Arial, sans-serif;
  48.     color: #666;
  49.     text-align: justify;
  50.     font-size: 16px;
  51.     margin: 10px 16px;
  52. }
  53. #github, #twitter {
  54.   color:#3377ee;
  55.   font-family: Helvetica, Arial, sans-serif;
  56.   font-size: 19px;
  57.   margin: 0 auto;
  58.   text-align: center;
  59.   text-decoration:none;
  60. }
  61. #net {
  62.   text-align:center;
  63.   white-space:nowrap;
  64.   font-size:19px;
  65.   background:rgba(0,0,0,0.1);
  66.   padding:8px 12px;
  67.   border-radius:8px;
  68.   display:block;
  69.   color:#888;
  70. }
  71. #net > span {
  72.   color:#3377ee;
  73.   font-family: Helvetica, Arial, sans-serif;
  74.   font-size: 14px;
  75.   display: block;
  76.   margin: 0 auto;
  77.   text-align: center;
  78.   text-decoration:none;
  79. }
  80. a {
  81.     font-family: sans-serif;
  82.     color: #444;
  83.     text-decoration: none;
  84.     font-size: 20px;
  85. }
  86. #site {
  87.     float: left;
  88.     margin: 10px;
  89.     color: #ff9900;
  90.   border-bottom: 1px dashed #ccc;
  91.   padding-bottom:3px
  92. }
  93. #site:hover {
  94.     color: #ffaa11;
  95. }
  96. #close {
  97.     float: right;
  98.     margin: 10px;
  99. }
  100. #p {
  101.     font-family: Verdana, sans-serif;
  102.     position: absolute;
  103.     right: 10px;
  104.     bottom: 10px;
  105.     color: #4099ff;
  106.     border: 1px dashed #4099ff;
  107.     padding: 4px 8px;
  108. }
  109.  
  110. #irc {
  111.   display: block;
  112.    text-align: center;
  113.   margin-top:4px;
  114.     color: #333;
  115. }
  116.  
  117. #irc a {
  118.   color: #3377ee;
  119.   font-size: 17px
  120. }
  121.  
  122. #irc-info {
  123.   display: block;
  124.   text-align: center;
  125.   font-size: 14px;
  126.   margin-top: -10px;
  127.   color: #828282;
  128.   margin-bottom:4px
  129. }
  130.  
  131. #new {
  132.   width: 100%;
  133.   text-align: center;
  134.   font-size: 18px;
  135.   font-family: Helvetica;
  136. }
  137.  
  138. #new a {
  139.   font-size: 26px;
  140.   color: #4099ff;
  141. }
  142. </style>
  143.  
  144. </head>
  145.  
  146. <body>
  147.  
  148.   <canvas id="c"></canvas>
  149.  
  150.  
  151. <div id="info">
  152.   <div id="top">
  153.     <a id="close" href="">&times;</a>
  154.   </div>
  155.   <p>
  156.     <br>- Оторвите ткань мышью
  157.     <br>
  158.     <br>- Щелкните правой кнопкой мыши и перетащите, чтобы разрезать ткань
  159.     <br>
  160.     <br>
  161.     <br><a id="github" target="_blank" href="https://vk.com/dima.durov">VK</a>&nbsp;&nbsp;&bull;&nbsp;&nbsp;<a id="twitter" target="_blank" href="https://vk.com/dima.durov">DimaDurov</a>
  162.     <br>
  163.   </p>
  164. </div>
  165.  
  166.   <script>
  167.     document.getElementById('close').onmousedown = function(e) {
  168.   e.preventDefault();
  169.   document.getElementById('info').style.display = 'none';
  170.   return false;
  171. };
  172.  
  173. // settings
  174.  
  175. var physics_accuracy  = 3,
  176.     mouse_influence   = 20,
  177.     mouse_cut         = 5,
  178.     gravity           = 1200,
  179.     cloth_height      = 30,
  180.     cloth_width       = 50,
  181.     start_y           = 20,
  182.     spacing           = 7,
  183.     tear_distance     = 60;
  184.  
  185.  
  186. window.requestAnimFrame =
  187.     window.requestAnimationFrame ||
  188.     window.webkitRequestAnimationFrame ||
  189.     window.mozRequestAnimationFrame ||
  190.     window.oRequestAnimationFrame ||
  191.     window.msRequestAnimationFrame ||
  192.     function (callback) {
  193.         window.setTimeout(callback, 1000 / 60);
  194. };
  195.  
  196. var canvas,
  197.     ctx,
  198.     cloth,
  199.     boundsx,
  200.     boundsy,
  201.     mouse = {
  202.         down: false,
  203.         button: 1,
  204.         x: 0,
  205.         y: 0,
  206.         px: 0,
  207.         py: 0
  208.     };
  209.  
  210. var Point = function (x, y) {
  211.  
  212.     this.x      = x;
  213.     this.y      = y;
  214.     this.px     = x;
  215.     this.py     = y;
  216.     this.vx     = 0;
  217.     this.vy     = 0;
  218.     this.pin_x  = null;
  219.     this.pin_y  = null;
  220.    
  221.     this.constraints = [];
  222. };
  223.  
  224. Point.prototype.update = function (delta) {
  225.  
  226.     if (mouse.down) {
  227.  
  228.         var diff_x = this.x - mouse.x,
  229.             diff_y = this.y - mouse.y,
  230.             dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y);
  231.  
  232.         if (mouse.button == 1) {
  233.  
  234.             if (dist < mouse_influence) {
  235.                this.px = this.x - (mouse.x - mouse.px) * 1.8;
  236.                this.py = this.y - (mouse.y - mouse.py) * 1.8;
  237.            }
  238.  
  239.        } else if (dist < mouse_cut) this.constraints = [];
  240.    }
  241.  
  242.    this.add_force(0, gravity);
  243.  
  244.    delta *= delta;
  245.    nx = this.x + ((this.x - this.px) * .99) + ((this.vx / 2) * delta);
  246.    ny = this.y + ((this.y - this.py) * .99) + ((this.vy / 2) * delta);
  247.  
  248.    this.px = this.x;
  249.    this.py = this.y;
  250.  
  251.    this.x = nx;
  252.    this.y = ny;
  253.  
  254.    this.vy = this.vx = 0
  255. };
  256.  
  257. Point.prototype.draw = function () {
  258.  
  259.    if (!this.constraints.length) return;
  260.  
  261.    var i = this.constraints.length;
  262.    while (i--) this.constraints[i].draw();
  263. };
  264.  
  265. Point.prototype.resolve_constraints = function () {
  266.  
  267.    if (this.pin_x != null && this.pin_y != null) {
  268.  
  269.        this.x = this.pin_x;
  270.        this.y = this.pin_y;
  271.        return;
  272.    }
  273.  
  274.    var i = this.constraints.length;
  275.    while (i--) this.constraints[i].resolve();
  276.  
  277.    this.x > boundsx ? this.x = 2 * boundsx - this.x : 1 > this.x && (this.x = 2 - this.x);
  278.     this.y < 1 ? this.y = 2 - this.y : this.y > boundsy && (this.y = 2 * boundsy - this.y);
  279. };
  280.  
  281. Point.prototype.attach = function (point) {
  282.  
  283.     this.constraints.push(
  284.         new Constraint(this, point)
  285.     );
  286. };
  287.  
  288. Point.prototype.remove_constraint = function (constraint) {
  289.  
  290.     this.constraints.splice(this.constraints.indexOf(constraint), 1);
  291. };
  292.  
  293. Point.prototype.add_force = function (x, y) {
  294.  
  295.     this.vx += x;
  296.     this.vy += y;
  297. };
  298.  
  299. Point.prototype.pin = function (pinx, piny) {
  300.     this.pin_x = pinx;
  301.     this.pin_y = piny;
  302. };
  303.  
  304. var Constraint = function (p1, p2) {
  305.  
  306.     this.p1     = p1;
  307.     this.p2     = p2;
  308.     this.length = spacing;
  309. };
  310.  
  311. Constraint.prototype.resolve = function () {
  312.  
  313.     var diff_x  = this.p1.x - this.p2.x,
  314.         diff_y  = this.p1.y - this.p2.y,
  315.         dist    = Math.sqrt(diff_x * diff_x + diff_y * diff_y),
  316.         diff    = (this.length - dist) / dist;
  317.  
  318.     if (dist > tear_distance) this.p1.remove_constraint(this);
  319.  
  320.     var px = diff_x * diff * 0.5;
  321.     var py = diff_y * diff * 0.5;
  322.  
  323.     this.p1.x += px;
  324.     this.p1.y += py;
  325.     this.p2.x -= px;
  326.     this.p2.y -= py;
  327. };
  328.  
  329. Constraint.prototype.draw = function () {
  330.  
  331.     ctx.moveTo(this.p1.x, this.p1.y);
  332.     ctx.lineTo(this.p2.x, this.p2.y);
  333. };
  334.  
  335. var Cloth = function () {
  336.  
  337.     this.points = [];
  338.  
  339.     var start_x = canvas.width / 2 - cloth_width * spacing / 2;
  340.  
  341.     for (var y = 0; y <= cloth_height; y++) {
  342.  
  343.        for (var x = 0; x <= cloth_width; x++) {
  344.  
  345.            var p = new Point(start_x + x * spacing, start_y + y * spacing);
  346.  
  347.            x != 0 && p.attach(this.points[this.points.length - 1]);
  348.            y == 0 && p.pin(p.x, p.y);
  349.            y != 0 && p.attach(this.points[x + (y - 1) * (cloth_width + 1)])
  350.  
  351.            this.points.push(p);
  352.        }
  353.    }
  354. };
  355.  
  356. Cloth.prototype.update = function () {
  357.  
  358.    var i = physics_accuracy;
  359.  
  360.    while (i--) {
  361.        var p = this.points.length;
  362.        while (p--) this.points[p].resolve_constraints();
  363.    }
  364.  
  365.    i = this.points.length;
  366.    while (i--) this.points[i].update(.016);
  367. };
  368.  
  369. Cloth.prototype.draw = function () {
  370.  
  371.    ctx.beginPath();
  372.  
  373.    var i = cloth.points.length;
  374.    while (i--) cloth.points[i].draw();
  375.  
  376.    ctx.stroke();
  377. };
  378.  
  379. function update() {
  380.  
  381.    ctx.clearRect(0, 0, canvas.width, canvas.height);
  382.  
  383.    cloth.update();
  384.    cloth.draw();
  385.  
  386.    requestAnimFrame(update);
  387. }
  388.  
  389. function start() {
  390.  
  391.    canvas.onmousedown = function (e) {
  392.        mouse.button  = e.which;
  393.        mouse.px      = mouse.x;
  394.        mouse.py      = mouse.y;
  395.        var rect      = canvas.getBoundingClientRect();
  396.        mouse.x       = e.clientX - rect.left,
  397.        mouse.y       = e.clientY - rect.top,
  398.        mouse.down    = true;
  399.        e.preventDefault();
  400.    };
  401.  
  402.    canvas.onmouseup = function (e) {
  403.        mouse.down = false;
  404.        e.preventDefault();
  405.    };
  406.  
  407.    canvas.onmousemove = function (e) {
  408.        mouse.px  = mouse.x;
  409.        mouse.py  = mouse.y;
  410.        var rect  = canvas.getBoundingClientRect();
  411.        mouse.x   = e.clientX - rect.left,
  412.        mouse.y   = e.clientY - rect.top,
  413.        e.preventDefault();
  414.    };
  415.  
  416.    canvas.oncontextmenu = function (e) {
  417.        e.preventDefault();
  418.    };
  419.  
  420.    boundsx = canvas.width - 1;
  421.    boundsy = canvas.height - 1;
  422.  
  423.    ctx.strokeStyle = '#888';
  424.  
  425.    cloth = new Cloth();
  426.  
  427.    update();
  428. }
  429.  
  430. window.onload = function () {
  431.  
  432.    canvas  = document.getElementById('c');
  433.    ctx     = canvas.getContext('2d');
  434.  
  435.    canvas.width  = 560;
  436.    canvas.height = 350;
  437.  
  438.    start();
  439. };
  440.  </script>
  441.  
  442.     <script  src="js/index.js"></script>
  443.  
  444.  
  445.  
  446.  
  447. </body>
  448.  
  449. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement