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