Skip to content

Instantly share code, notes, and snippets.

@darbicus
Created August 9, 2013 23:32
Show Gist options
  • Save darbicus/6198189 to your computer and use it in GitHub Desktop.
Save darbicus/6198189 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="puzzle v3.0 rotate and bezier curves to make shapes of pieces." />
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<img hidden=true id="image" style="position:absolute;visibility:hidden;" src="http://www.prlog.org/11949574-hot-girl.jpg"></img>
</body>
</html>
function clone(obj) {
if (null == obj || "object" != typeof obj) return obj;
var copy = obj.constructor();
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
}
return copy;
}
function Point(x, y) {
this.x = x;
this.y = y;
this.d = Math.sqrt(x * x + y * y);
return this;
}
Point.prototype = {
slopeTo: function (p) {
return (this.y - p.y) / (this.x - p.x);
},
distanceTo: function (p) {
return (Math.sqrt(((this.y - p.y) * (this.y - p.y)) + ((this.x - p.x) * (this.x - p.x))));
},
distanceByAxis: function (p) {
return (new Point(this.x - p.x, this.y - p.y));
},
normalize: function () {
return new Point(this.x / this.d, this.y / this.d);
}
};
var puzzlePiece = (function () {
function puzzlePiece(obj) {
this.imgtop = clone(obj.top);
this.imgright = clone(obj.right);
this.imgbottom = clone(obj.bottom);
this.imgleft = clone(obj.left);
this.rotation = obj.rotation;
this.image = obj.image;
this.width = obj.width+0;
this.height = obj.height+0;
this.canvas = document.createElement("canvas");
this.canvas.rotation = 0;
this.canvas.setAttribute("style", "position:absolute;");
this.canvas.setAttribute("width", obj.width * 3);
this.canvas.setAttribute("height", obj.height * 3);
this.canvas.style.setProperty("top", this.imgtop.first.y + 1 + "px");
this.canvas.style.setProperty("left", this.imgtop.first.x + 1 + "px");
//this.canvas.ondblclick = dblclick;
this.context = this.canvas.getContext('2d');
document.body.appendChild(this.canvas);
this.top = {"first": new Point((this.canvas.height/2)-(obj.width/2.0),(this.canvas.height/2)-(obj.height/2.0)),
"last": new Point((this.canvas.height/2)+(obj.width/2.0),(this.canvas.height/2)-(obj.height/2.0))};
this.right = {"first": new Point((this.canvas.height/2)+(obj.width/2.0),(this.canvas.height/2)-(obj.height/2.0)),
"last": new Point((this.canvas.height/2)+(obj.width/2.0),(this.canvas.height/2)+(obj.height/2.0))};
this.bottom = {"first": new Point((this.canvas.height/2)+(obj.width/2.0),(this.canvas.height/2)+(obj.height/2.0)),
"last": new Point((this.canvas.height/2)-(obj.width/2.0),(this.canvas.height/2)+(obj.height/2.0))};
this.left = {"first": new Point((this.canvas.height/2)-(obj.width/2.0),(this.canvas.height/2)+(obj.height/2.0)),
"last": new Point((this.canvas.height/2)-(obj.width/2.0),(this.canvas.height/2)-(obj.height/2.0))};
if (!(obj.top.first.y <= 0)) {
this.top.points = this.makeSide(this.top);
} else {
this.top.points = [];
this.top.points.push(this.top.first);
this.top.points.push(this.top.last);
}
if (!(obj.right.first.x >= this.image.width)) {
this.right.points = this.makeSide(this.right);
} else {
this.right.points = [];
this.right.points.push(this.right.first);
this.right.points.push(this.right.last);
}
if (!(obj.bottom.first.y >= this.image.height)) {
this.bottom.points = this.makeSide(this.bottom);
} else {
this.bottom.points = [];
this.bottom.points.push(this.bottom.first);
this.bottom.points.push(this.bottom.last);
}
if (!(obj.left.first.x <= 0)) {
this.left.points = this.makeSide(this.left);
} else {
this.left.points = [];
this.left.points.push(this.left.first);
this.left.points.push(this.left.last);
}
this.display = function () {
//this.context.save();
//this.canvas.style.setProperty("border-style","solid");
//this.context.translate((this.canvas.width/2.0)-(this.width/4.0)-this.top.first.x,(this.canvas.width/2.0)-(this.width/4.0)-this.top.first.y);
this.context.beginPath();
this.dBezierCurve(this.top.points);
this.dBezierCurve(this.right.points);
this.dBezierCurve(this.bottom.points);
this.dBezierCurve(this.left.points);
this.context.closePath();
this.context.save();
this.context.clip();
this.context.drawImage(this.image,-this.imgtop.first.x,-this.imgtop.first.y);
//context.fill();
for (var i = 5; i > 1; i --) {
this.context.strokeStyle = "RGBA(0,0,0,.1)";
this.context.lineWidth = i;
this.context.stroke();
}
//this.context.restore();
};
}
return puzzlePiece;
})();
puzzlePiece.prototype = {
dBezierCurve: function () {
var controlpoint = 3.5;
var args = Array.prototype.slice.call(arguments);
if (args[0].length > 1) {
args = args[0];
}
if (args.length <= 2) {
this.context.lineTo(args[0].x, args[0].y);
this.context.lineTo(args[1].x, args[1].y);
return;
}
var a = [];
a.push(args[0]);
for (var j = 0; j < args.length; j++) {
a.push(args[j]);
}
a.push(args[args.length - 1]);
args = a;
for (var i = 2; i < args.length - 1; i++) {
//these get the args before and after arg[i] it is so long because i am checking to make sure it actually exists if not it gets the remainder of it divided by the total args
var before = new Point(args[(i + (args.length - 1)) % args.length].x, args[(i + (args.length - 1)) % args.length].y);
var after = new Point(args[(i + (args.length + 1)) % args.length].x, args[(i + (args.length + 1)) % args.length].y);
var current = new Point(args[(i + (args.length)) % args.length].x, args[(i + (args.length)) % args.length].y);
var before2 = new Point(args[(i + (args.length - 2)) % args.length].x, args[(i + (args.length - 2)) % args.length].y);
//these are taking the difference of the points before and after divides it by controlpoint and adds or subtracts that from the middle point to get the bezier control points
var mid1 = new Point(before.x - ((before2.x - current.x) / controlpoint), before.y - ((before2.y - current.y) / controlpoint));
var mid2 = new Point(current.x + ((before.x - after.x) / controlpoint), current.y + ((before.y - after.y) / controlpoint));
this.context.bezierCurveTo(mid1.x, mid1.y, mid2.x, mid2.y, current.x, current.y);
}
},
makeSide: function (eobj) {
var lp = [];
var d = new Point(eobj.first.x - eobj.last.x, eobj.first.y - eobj.last.y),
midpoint = new Point((eobj.first.x + eobj.last.x) / 2.0, (eobj.first.y + eobj.last.y) / 2.0),
r = (Math.round(Math.random()) * 2.0) - 1,
//r = 1,
rd = new Point(d.x / 6.0 * (Math.random() * 0.5 + 0.7), d.y / 6.0 * (Math.random() * 0.5 + 0.7)),
pt1 = new Point(midpoint.x + rd.x + (rd.y / 2.0 * Math.random()), midpoint.y + rd.y + (rd.x / 2.0 * Math.random())),
pt2 = new Point(midpoint.x - rd.x + (rd.y / 2.0 * Math.random()), midpoint.y - rd.y + (rd.x / 2.0 * Math.random()));
lp.push(new Point(eobj.first.x, eobj.first.y));
lp.push(pt1);
//lp.push(new Point((obj.first.x+midpoint.x + rd.x + (rd.y * r))/2.0,(obj.first.y+ midpoint.y + rd.y + (rd.x * r))/2.0));
lp.push(new Point(pt1.x + (rd.y * r), pt1.y + (rd.x * r)));
lp.push(new Point(pt2.x + (rd.y * r), pt2.y + (rd.x * r)));
lp.push(pt2);
//lp.push(new Point((lp[lp.length - 1].x+obj.last.x)/2.0,(lp[lp.length - 1].y+obj.last.y)/2.0));
lp.push(new Point(eobj.last.x, eobj.last.y));
return lp.splice(0);
}
};
var p = [];
var square =75;
var cols = Math.ceil(document.getElementById("image").width / square);
var rows = Math.ceil(document.getElementById("image").height / square);
var count = 0;
for (var l = 0; l < rows; l++) {
for (var k = 0; k < cols; k++) {
p.push(new puzzlePiece({
"rotation": 0,
"width": square,
"height": square,
"image": document.getElementById("image"),
"imagepoint": new Point(k*square,l*square),
"top": {
"first": new Point(k * square, l * square),
"last": new Point(k * square + square, l * square)
},
"right": {
"first": new Point(k * square + square, l * square),
"last": new Point(k * square + square, l * square + square)
},
"bottom": {
"first": new Point(k * square + square, l * square + square),
"last": new Point(k * square, l * square + square)
},
"left": {
"first": new Point(k * square, l * square + square),
"last": new Point(k * square, l * square)
}
}));
if (k !== 0) {
var temp = p[p.length - 2].right.points;
p[p.length - 1].left.points = [];
for (var i = 0; i < temp.length; i++) {
p[p.length - 1].left.points.push(new Point(temp[i].x-p[p.length - 1].width,temp[i].y));
}
p[p.length - 1].left.points.reverse();
}
if (l !== 0) {
var temp2 = p[count - cols].bottom.points;
p[count].top.points = [];
for (var i = 0; i < temp2.length; i++) {
p[count].top.points.push(new Point(temp2[i].x,temp2[i].y-p[count].height));
}
p[count].top.points.reverse();
}
count++;
}
}
///var canvas = document.getElementById('can');
//var context = canvas.getContext('2d');
//var temp = p[0].right.points;
//p[1].left.points = [];
//for (var i = 0; i < temp.length; i++) {
// p[1].left.points.push(temp[i]);
//}
//p[1].left.points.reverse();
for (var i = 0; i < p.length; i++) {
p[i].display();
}
function mousedown(event) {
for (var i = 0; i < p.length; i++) {
var that = p[i].canvas;
if (that.getContext('2d').isPointInPath(event.pageX - parseInt(that.style.getPropertyValue("left"),10), event.pageY - parseInt(that.style.getPropertyValue("top"),10))) {
that.mouse = new Point(event.pageX, event.pageY);
document.selected = that;
document.onmousemove = function (evt) {
document.selected.style.setProperty("top", parseInt(document.selected.style.getPropertyValue("top"),10) + evt.pageY - document.selected.mouse.y + "px");
document.selected.style.setProperty("left", parseInt(document.selected.style.getPropertyValue("left"),10) + evt.pageX - document.selected.mouse.x + "px");
document.selected.mouse = new Point(evt.pageX, evt.pageY);
};
document.onmouseup = function (evt) {
//alert('hello');
document.selected.style.setProperty("top", parseInt(document.selected.style.getPropertyValue("top"),10) + evt.pageY - document.selected.mouse.y + "px");
document.selected.style.setProperty("left", parseInt(document.selected.style.getPropertyValue("left"),10) + evt.pageX - document.selected.mouse.x + "px");
document.onmouseup = '';
document.onmousemove = '';
document.selected.mouse = '';
document.selected = '';
};
}
}
}
document.onmousedown = mousedown;
function dblclick(event){
//alert("works");
for (var i = 0; i < p.length; i++) {
var that = p[i];
if (that.canvas.getContext('2d').isPointInPath(event.pageX - parseInt(that.canvas.style.getPropertyValue("left"),10), event.pageY - parseInt(that.canvas.style.getPropertyValue("top"),10))) {
that.canvas.getContext('2d').restore();
that.canvas.getContext('2d').clearRect(0,0,that.canvas.width,that.canvas.height);
//this.context.translate((this.canvas.width/2.0)-(this.width/4.0)-this.top.first.x,+(this.canvas.width/2.0)-(this.width/4.0)-this.top.first.y); that.canvas.getContext('2d').clearRect(0,0,that.canvas.width*2,that.canvas.height*2);
//alert('works');
//that.canvas.getContext('2d').save();
//that.canvas.getContext('2d').closePath();
//that.canvas.width = that.canvas.width+0;
//that.canvas.getContext('2d').restore();
that.context.translate(that.canvas.width/2.0,that.canvas.height/2.0);
that.canvas.getContext('2d').rotate(Math.PI/2.0); //that.context.translate((that.canvas.width/4)-(that.width/2)-that.top.first.x,(that.canvas.width/4)-(that.width/2)-that.top.first.y);
//that.canvas.getContext('2d').translate(that.canvas.width/2.0-that.width/2.0,that.canvas.width/2.0-that.width/2.0);
//that.canvas.getContext('2d').rotate(that.canvas.rotation);
that.context.translate(-(that.canvas.width/2.0),-(that.canvas.height/2.0));
//that.context.translate(((that.canvas.width/4)-(that.width/2)-that.top.first.x)*-1,((that.canvas.width/4)-(that.width/2)-that.top.first.y)*-1);
// that.canvas.getContext('2d').translate(-(that.canvas.width/2.0-that.width/2.0),-(that.canvas.width/2.0-that.width/2.0) );
that.display();
//that.canvas.getContext('2d').restore();
}
}
}
document.ondblclick = dblclick;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment