canvas图片生成各种拼图裁切分解代码

代码语言:html

所属分类:其他

代码描述:canvas图片生成各种拼图裁切分解代码

代码标签: canvas 图片 生成 各种 拼图 裁切 分解 代码

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  

  
  
  
<style>
body {
      font-family: Arial, Helvetica, "Liberation Sans", FreeSans, sans-serif;
      background-color: #fff;
      margin: 0;
      padding: 0;
      border-width: 0;
      cursor: pointer;
    }

    #menu {
      position: relative;
      list-style-type: none;
      padding-left: 5px;
      z-index: 1000;
      /* 1 */
      display: inline-block;
      text-align: center;
    }

    #menu li {
      margin: 2px;
      padding: 4px 10px;
      border-radius: 5px;
      background-color: #ffff80;
    }

    #menu li:hover {
      background-color: #ffDD60;
    }

    #forPuzzle {
      position: absolute;
      width: 95vw;
      height: 95vh;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background-color: #ffffdd;
      overflow: hidden;
    }

    .polypiece {
      display: block;
      overflow: hidden;
      position: absolute;
    }

    .moving {
      transition-property: top, left;
      transition-duration: 1s;
      transition-timing-function: linear;
    }

    .gameCanvas {
      display: none;
      overflow: hidden;
      position: absolute;
    }
</style>


  
  
</head>

<body translate="no">
  <div id=forPuzzle></div>
  <ul id="menu">
    <li>&#x2630;</li>
    <li>Reset</li>
    <li>load image</li>
    <li>shape: <select id="shape">
        <option value="1" selected>classic</option>
        <option value="2">triangle</option>
        <option value="3">round</option>
        <option value="4">straight</option>
      </select></li>
    <li>12 pieces</li>
    <li>25 pieces</li>
    <li>50 pieces</li>
    <li>100 pieces</li>
    <li>200 pieces</li>
  </ul>
  
      <script >
"use strict";

let puzzle, autoStart;

const mhypot = Math.hypot,
mrandom = Math.random,
mmax = Math.max,
mmin = Math.min,
mround = Math.round,
mfloor = Math.floor,
msqrt = Math.sqrt,
mabs = Math.abs;
//-----------------------------------------------------------------------------
function isMiniature() {
  return location.pathname.includes('/fullcpgrid/');
}
//-----------------------------------------------------------------------------

function alea(min, max) {
  // random number [min..max[ . If no max is provided, [0..min[

  if (typeof max == 'undefined') return min * mrandom();
  return min + (max - min) * mrandom();
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

function intAlea(min, max) {
  // random integer number [min..max[ . If no max is provided, [0..min[

  if (typeof max == 'undefined') {
    max = min;min = 0;
  }
  return mfloor(min + (max - min) * mrandom());
} // intAlea

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

function arrayShuffle(array) {
  /* randomly changes the order of items in an array
  only the order is modified, not the elements
  */
  let k1, temp;
  for (let k = array.length - 1; k >= 1; --k) {
    k1 = intAlea(0, k + 1);
    temp = array[k];
    array[k] = array[k1];
    array[k1] = temp;
  } // for k
  return array;
} // arrayShuffle

//-----------------------------------------------------------------------------

// Point - - - - - - - - - - - - - - - - - - - -
class Point {
  constructor(x, y) {
    this.x = Number(x);
    this.y = Number(y);
  } // constructor
  copy() {
    return new Point(this.x, this.y);
  }

  distance(otherPoint) {
    return mhypot(this.x - otherPoint.x, this.y - otherPoint.y);
  }}
// class Point

// Segment - - - - - - - - - - - - - - - - - - - -
// those segments are oriented
class Segment {
  constructor(p1, p2) {
    this.p1 = new Point(p1.x, p1.y);
    this.p2 = new Point(p2.x, p2.y);
  }
  dx() {
    return this.p2.x - this.p1.x;
  }
  dy() {
    return this.p2.y - this.p1.y;
  }
  length() {
    return mhypot(this.dx(), this.dy());
  }

  // returns a point at a given distance of p1, positive direction beeing towards p2

  pointOnRelative(coeff) {
    // attention if segment length can be 0
    let dx = this.dx();
    let dy = this.dy();
    return new Point(this.p1.x + coeff * dx, this.p1.y + coeff * dy);
  }}
// class Segment
//-----------------------------------------------------------------------------
// one side of a piece
class Side {
  constructor() {
    this.type = ""; // "d" pour straight line or "z" pour classic
    this.points = []; // real points or Bezier curve points
    // this.scaledPoints will be added when we know the scale
  } // Side

  //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  reversed() {
    // returns a new Side, copy of current one but reversed
    const ns = new Side();
    ns.type = this.type;
    ns.points = this.points.slice().reverse();
    return ns;
  } // Side.reversed

  //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  scale(puzzle) {
    /* uses actual dimensions of puzzle to compute actual side points
    these points are not shifted by the piece position : the top left corner is at (0,0)
    */
    const coefx = puzzle.scalex;
    const coefy = puzzle.scaley;
    this.scaledPoints = this.points.map(p => new Point(p.x * coefx, p.y * coefy));

  } //

  //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  /*
  draws the path corresponding to a side
  Parameters :
    ctx : canvas context
    shiftx, shifty : position shift (used to create emboss effect)
    withoutMoveTo : to decide whether to do a moveTo to the first point. Without MoveTo
    must be done only for the first side of a piece, not for the following ones
  */

  drawPath(ctx, shiftx, shifty, withoutMoveTo) {

    if (!withoutMoveTo) {
      ctx.moveTo(this.scaledPoints[0].x + shiftx, this.scaledPoints[0].y + shifty);
    }
    if (this.type == "d") {
      ctx.lineTo(this.scaledPoints[1].x + shiftx, this.scaledPoints[1].y + shifty);
    } else {// edge zigzag
      for (let k = 1; k < this.scaledPoints.length - 1; k += 3) {
        ctx.bezierCurveTo(this.scaledPoints[k].x + shiftx, this.scaledPoints[k].y + shifty,
        this.scaledPoints[k + 1].x + shiftx, this.scaledPoints[k + 1].y + shifty,
        this.scaledPoints[k + 2].x + shiftx, this.scaledPoints[k + 2].y + shifty);
      } // for k
    } // if jigsaw side

  } // Side.drawPath
} // class Side

//-----------------------------------------------------------------------------
/* modifies a side
  changes it from a straight line (type "d") to a complex one (type "z")
  The change is done towards the opposite side (side between corners ca and cb)
*/

function twist0(side, ca, cb) {

  const seg0 = new Segment(side.points[0], side.points[1]);
  const dxh = seg0.dx();
  const dyh = seg0.dy();

  const seg1 = new Segment(ca, cb);
  const mid0 = seg0.pointOnRelative(0.5);
  const mid1 = seg1.pointOnRelative(0.5);

  const segMid = new Segment(mid0, mid1);
  const dxv = segMid.dx();
  const dyv = segMid.dy();

  const scalex = alea(0.8, 1);
  const scaley = alea(0.9, 1);
  const mid = alea(0.45, 0.55);

  const pa = pointAt(mid - 1 / 12 * scalex, 1 / 12 * scaley);
  const pb = pointAt(mid - 2 / 12 * scalex, 3 / 12 * scaley);
  const pc = pointAt(mid, 4 / 12 * scaley);
  const pd = pointAt(mid + 2 / 12 * scalex, 3 / 12 * scaley);
  const pe = pointAt(mid + 1 / 12 * scalex, 1 / 12 * scaley);

  side.points = [seg0.p1,
  new Point(seg0.p1.x + 5 / 12 * dxh * 0.52,
  seg0.p1.y + 5 / 12 * dyh * 0.52),
  new Point(pa.x - 1 / 12 * dxv * 0.72,
  pa.y - 1 / 12 * dyv * 0.72),
  pa,
  new Point(pa.x + 1 / 12 * dxv * 0.72,
  pa.y + 1 / 12 * dyv * 0.72),

  new Point(pb.x - 1 / 12 * dxv * 0.92,
  pb.y - 1 / 12 * dyv * 0.92),
  pb,
  new Point(pb.x + 1 / 12 * dxv * 0.52,
  pb.y + 1 / 12 * dyv * 0.52),
  new Point(pc.x - 2 / 12 * dxh * 0.40,
  pc.y - 2 / 12 * dyh * 0.40),
  pc,
  new Point(pc.x + 2 / 12 * dxh * 0.40,
  pc.y + 2 / 12 * dyh * 0.40),
  new Point(pd.x + 1 / 12 * dxv * 0.52,
  pd.y + 1 / 12 * dyv * 0.52),
  pd,
  new Point(pd.x - 1 / 12 * dxv * 0.92,
  pd.y - 1 / 12 * dyv * 0.92),
  new Point(pe.x + 1 / 12 * dxv * 0.72,
  pe.y + 1 / 12 * dyv * 0.72),
  pe,
  new Point(pe.x - 1 / 12 * dxv * 0.72,
  pe.y - 1 / 12 * dyv * 0.72),
  new Point(seg0.p2.x - 5 / 12 * dxh * 0.52,
  seg0.p2.y - 5 / 12 * dyh * 0.52),
  seg0.p2];
  side.type = "z";

  .........完整代码请登录后点击上方下载按钮下载查看

网友评论0