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>☰</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