将图像映射到 JS 布料上并创建滑块

Mapping image onto JS cloth and creating a slider

这是网站的所有代码,它有很多错误,比如卡在中间的页脚。所以我的想法是以映射到我拥有的 JS 的图像格式创建 11 种不同的组织,有点我不知道该怎么做。[![sample tissue][1]][1]

我想创建一个滑块,当您单击它切换到下一个集合的集合编号时,它会起作用。

此外,所有链接在悬停时仅采用大小而不采用列宽。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>$</title>
 <link rel="stylesheet" href="normalize.css">
  <style type="text/css">
    * {
    margin: 0;
    overflow: hidden;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    -o-user-select: none;
    user-select: none;
    font-family: sans-serif;
}
body {
}
#c {
    display: block;
    margin: 20px auto 0;
}
#info {
    position: absolute;
    left: -1px;
    top: -1px;
    width: auto;
    max-width: 420px;
    height: auto;
    background: #f8f8f8;
    border-bottom-right-radius: 10px;
    border:1px solid #ccc;
}
#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: 0px 16px;
}
#github, #twitter {
  color:#3377ee;
  font-family: Helvetica, Arial, sans-serif;
  font-size: 14px;
  margin: 0 auto;
  text-align: center;
  text-decoration:none;
}
.center {
  text-align: center;
}
#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;
}


.bull {
  opacity: 0.3;
  margin: 0 6px;
  font-size: 14px;
}

.row {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  border-bottom: 1px solid black;
}

.column {
  flex-basis: 100%;
  border-right: 1px solid black;
}

@media screen and (min-width: 800px) {
  .column {
    flex: 1;
  }
}

@media screen and (min-width: 800px) {
  ._25 {
    flex: 2.5;
  }
  ._55 {
    flex: 5.5;
  }
  ._20 {
    flex: 2;
  }
}
 a:link {
  text-decoration: none;
}

 a:visited {
  text-decoration: none;
  color: black;
}

a:hover {
  text-decoration: none;
  color: white;
background: black;}

 a:active {
  text-decoration: none;
    color: white;
background: black;
}
  </style>
</head>
<body>
<div class="row">
  <div class="column">
    <a href="">Rakṣas Sari collection</a>
  </div>
  <div class="column">
   <a href=""> Concept</a>
  </div>
  <div class="column">
   <a href=""> Process</a>
  </div>
</div>
<div class="row">
  <div class="column">
   <a href=""> Red Collection N°1</a>
  </div>
  <div class="column">
   <a href=""> Collection N°2</a>
  </div>
  <div class="column">
   <a href=""> Collection N°3</a>
  </div>
  <div class="column">
   <a href=""> Collection N°4</a>
  </div>
  <div class="column">
  <a href="">  Collection N°5</a>
  </div>
  <div class="column">
  <a href="">  Collection N°6</a>
  </div>
  <div class="column">
   <a href=""> Collection N°7</a>
  </div>
  <div class="column">
   <a href=""> Collection N°8</a>
  </div>
  <div class="column">
  <a href="">  Collection N°9</a>
  </div>
  <div class="column">
   <a href=""> Collection N°10</a>
  </div>
  <div class="column">
   <a href=""> Collection N°11</a>
  </div>
</div>
<div class="row">
  <div class="column _25">
    Project photoshoot
  </div>
  <div class="column _55">
    <canvas id="c"></canvas>


  <div id="top">
    <a id="close" href="">Reset tissue</a>
  </div>
  </div>
  <div class="column _20">
    Red is a celebratory color. It commemorates a couple’s union. It symbolizes love, sensuality, and passion. That’s why it features prominently in auspicious occasions, such as weddings, festivals, and births. As red also signifies chastity, it is the color of choice for brides. 
  </div>
</div>



  
<footer>
  <div class="row">
  <div class="column">
    ©Copyright Angelo Barbattini
  </div>
  <div class="column">
   ECAL 2022
  </div>
</div>
</footer style="position: fixed;bottom: 0;">
<!--div id="new">
  Wobble some <a target="_blank" href="https://codepen.io/dissimulate/details/dJgMaO">jelly</a> <span class="bull">&bull;</span>
  Check out my <a target="_blank" href="https://www.instagram.com/abro_oks/">instagram!</a>
</div-->
<script type="text/javascript">
  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) * 0.99 + (this.vx / 2) * delta;
  ny = this.y + (this.y - this.py) * 0.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;

  var round = 400;
  this.vx = ~~(this.vx * round) / round;
  this.vy = ~~(this.vy * round) / round;
};

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(0.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>
</body>
</html>```


  [1]: https://i.stack.imgur.com/Celmj.jpg

提问者的重点是让实际图像看起来像 material 随风移动的问题。

执行此操作的代码将 canvas 分成小的矩形元素,并根据给定的 'physics' 的要求移动每个元素(例如 gravity/wind 的值)。

原文只是为每个区域绘制网格线。我们需要的是将原始图像中的等效矩形复制到该点。

此代码段通过向有关每个点的信息添加 origx/y 来实现此目的,以便我们知道在哪里可以找到原始矩形。

它将图像放入一个 img 元素中(重要的是要等到它加载后再对其进行更多操作)然后将其复制到具有与以下尺寸相同的 off-screen canvas将容纳 material 的那个。当我们需要将 'mini image' 放置在给定点时,将检查此 canvas。

警告:这段代码(即使没有引入图像)也非常占用处理器资源。在一台功能强大且配备良好 GPU 的笔记本电脑上,它占用了 CPU 的大约 19%,而且占用的 GPU 也不少,而且风扇还在呼呼作响。即使没有鼠标移动也是如此。代码可以通过彻底查看来完成,例如在用户 activity 完成时停止计时器,并可能降低帧速率(给定代码中为 60fps)。我不建议将它放在网页中并留在那里 运行 - 它会耗尽电池电量。

<html xmlns="http://www.w3.org/1999/xhtml">

<head>
  <title></title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <!-- 
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    -->

  <script type="text/javascript" src=""></script>
  <link rel="stylesheet" type="text/css" href="">

  <style type="text/css">
    body {}
    
    .wrapper {}
    
    * {
      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: 100%;
      height: 376px;
      margin: 0 auto;
      display: block;
      border: solid red 2px;
    }
    
    #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>
  <img src="https://i.stack.imgur.com/Celmj.jpg" style="margin-top: -2000px; position: absolute;">
  <canvas width="1360" height="376" style="margin-top: -2000px; position: absolute;"></canvas>
  <script type="text/javascript">
    /*
    Copyright (c) 2013 lonely-pixel.com, Stuffit at codepen.io (http://codepen.io/stuffit)

    View this and others at http://lonely-pixel.com

    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.
    */


    const mycanvas = document.querySelector('canvas');
    const mycontext = mycanvas.getContext('2d');

    // settings


    var physics_accuracy = 5,
      mouse_influence = 20,
      mouse_cut = 6,
      gravity = 900,
      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() {
      // ADDED TO BRING IN THE IMAGE
      mycontext.clearRect(0, 0, mycanvas.width, mycanvas.height);
      mycontext.drawImage(document.querySelector('img'), 0, 0, 1180, 376);


      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)';
      ctx.strokeStyle = 'magenta';
      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 = [];
      //added - remember where this point was originally so we can get the right bit of the img
      this.origx = x;
      this.origy = y;
    };

    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;
    };
    let num = 0;
    Constraint.prototype.draw = function() {

      ctx.drawImage(mycanvas, this.p1.origx, this.p1.origy, spacing, spacing, this.p1.x, this.p1.y, spacing + 1, spacing + 1);
    };

    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.clearRect(0, 0, canvas.width, canvas.height);
      ctx.beginPath();

      var i = cloth.points.length;
      while (i--) cloth.points[i].draw();

      ctx.stroke();
    };

    function update() {

      cloth.update();
      cloth.draw();

      requestAnimFrame(update);
    }
  </script>

</head>

<body>

  <canvas id="c" width="800" height="376"> </canvas>




</body>

</html>

注意:可以通过右键单击 'tear' material 并且此功能可能需要删除 - 除非您希望用户破坏布料的外观:)