Skip to content
This repository has been archived by the owner on Feb 6, 2021. It is now read-only.

Commit

Permalink
Adding sources
Browse files Browse the repository at this point in the history
  • Loading branch information
w0rm committed Oct 5, 2012
1 parent ea5fe40 commit 85429ea
Show file tree
Hide file tree
Showing 3 changed files with 389 additions and 0 deletions.
247 changes: 247 additions & 0 deletions divcanvas.js
@@ -0,0 +1,247 @@
/*
Drawing polygons using slanted borders technique
by Andrey Kuzmin unsoundscapes@gmail.com MIT licensed
*/

(function() {

function getInternetExplorerVersion()
// Returns the version of Internet Explorer or a -1
// (indicating the use of another browser).
{
var rv = -1; // Return value assumes failure.
if (navigator.appName == 'Microsoft Internet Explorer')
{
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null)
rv = parseFloat( RegExp.$1 );
}
return rv;
}

function DivCanvas(element) {
this.element = element;
this.cache = "";
this.opacity = 1;
this.transparent = 'transparent';
this.filter = '';

this.ie = getInternetExplorerVersion();
if (this.ie > 5 && this.ie < 8) {
this.transparent = this.ieHackColor;
this.filter = ";filter: chroma(color=" + this.ieHackColor + ")";
}
}

DivCanvas.prototype = {
roundMethod: Math.round, // could be parseInt, but looks uglier
ieHackColor: 'cyan',
setOpacity: function(opacity) {
this.opacity = opacity;
if(this.ie>5 && this.ie<8)
this.filter = ";filter:chroma(color=" + this.ieHackColor + ")" +
(opacity==1 ? "" : " alpha(opacity=" + parseInt(opacity*100) + ")");
else if (this.ie>5 && this.ie<9)
this.filter = (opacity==1 ? "" : ";filter:alpha(opacity=" + parseInt(opacity*100) + ")");
else
this.filter = opacity==1 ? "" : ";opacity:" + opacity;
return this;
},
triangle: function(x, y, color) {
this._tri(x, y, color);
return this;
},
polygon: function(x, y, color) {
var n = x.length;
if (n < 3) return false;
var V = new Array(n);
/* we want a counter-clockwise polygon in V */
if ( 0.0 < this._area(x,y) )
for (var v=0; v<n; v++) V[v] = v;
else
for (var v=0; v<n; v++) V[v] = (n-1)-v;
var nv = n;
/* remove nv-2 Vertices, creating 1 triangle every time */
var count = 2 * nv; /* error detection */
for(var m=0, v=nv-1; nv>2; )
{
/* if we loop, it is probably a non-simple polygon */
if (0 >= (count--)) return false; //** Triangulate: ERROR - probable bad polygon!
/* three consecutive vertices in current polygon, <u,v,w> */
var u = v ; if (nv <= u) u = 0; /* previous */
v = u+1; if (nv <= v) v = 0; /* new v */
var w = v+1; if (nv <= w) w = 0; /* next */
if ( this._snip(x,y,u,v,w,nv,V) )
{
var a,b,c,s,t;
/* true names of the vertices */
a = V[u]; b = V[v]; c = V[w];
this._tri([x[c],x[a],x[b]], [y[c],y[a],y[b]], color )
m++;
/* remove v from remaining polygon */
for(s=v,t=v+1;t<nv;s++,t++) V[s] = V[t]; nv--;
/* resest error detection counter */
count = 2*nv;
}
}
return this;
},
circle: function(x, y, r, color) {
var dx1=r, dx2, dy1=0, dy2, da = 10;
for(var a = da; a <= 90; a+= da){
dx2 = this.roundMethod(r*Math.cos((a) * Math.PI / 180))
dy2 = this.roundMethod(-r*Math.sin((a) * Math.PI / 180))
this._trapezoid(x - dx1, y - dy1, dx1 - dx2, dx1 - dx2, dy1 - dy2, dx2 * 2, color)
this._trapezoid(x - dx1, y + dy1, dx1 - dx2, dx1 - dx2, dy2 - dy1, dx2 * 2, color)
dx1 = dx2
dy1 = dy2
}
return this;
},
textCircle: function(x, y, r, color) {
var x = parseInt(x - 1.379*r),
y = parseInt(y-2.61*r),
size = parseInt(r*4.61)
this.cache += "<span class='p' style='left:"+
x + "px;top:" + y + "px;font-family:Arial;font-size:" +
size + "px; color:" + color + "'>●</span>"
return this
},
flush: function() {
this.element.innerHTML += this.cache;
this.cache = "";
return this;
},
empty: function() {
this.element.innerHTML = "";
return this;
},
_area: function(x, y) {
var n = x.length, A = 0.0;
for(var p=n-1,q=0; q<n; p=q++)
A+= x[p] * y[q] - x[q] * y[p];
return A * 0.5;
},
_isInsideTriangle: function(Ax, Ay, Bx, By, Cx, Cy, Px, Py) {
return (Cx - Bx) * (Py - By) - (Cy - By) * (Px - Bx) >= 0 &&
(Bx - Ax) * (Py - Ay) - (By - Ay) * (Px - Ax) >= 0 &&
(Ax - Cx) * (Py - Cy) - (Ay - Cy) * (Px - Cx) >= 0;
},
_snip: function(x, y, u, v, w, n, V) {
var Ax, Ay, Bx, By, Cx, Cy;
Ax = x[V[u]]; Ay = y[V[u]];
Bx = x[V[v]]; By = y[V[v]];
Cx = x[V[w]]; Cy = y[V[w]];
if ( 0.0000000001 > (Bx-Ax)*(Cy-Ay) - (By-Ay)*(Cx-Ax) ) return false;
for (var p=0;p<n;p++){
if( p == u || p == v || p == w ) continue;
if (this._isInsideTriangle(Ax,Ay,Bx,By,Cx,Cy,x[V[p]],y[V[p]])) return false;
}
return true;
},
_tri: function(x, y, color) {
if(x[2]==x[1] || x[2]==x[0] || x[1]==x[0])
if(y[2]==y[1] || y[2]==y[0] || y[1]==y[0])
this._rightTri(x, y, color);
else
this._splitV(x, y, color);
else
this._splitH(x, y, color);
},
_sortOrder: function(a) {
if(a[0] > a[1])
if(a[1] > a[2])
return [0, 1, 2];
else
return a[0] > a[2] ? [0, 2, 1] : [2, 0, 1];
else
if(a[0] > a[2])
return [1, 0, 2];
else
return a[1] > a[2] ? [1, 2, 0] : [2, 1, 0];
},
_splitH: function(x, y, color) {
var p = this._sortOrder(x);
if(y[p[0]]==y[p[2]] && x[p[2]] < x[p[1]] < x[p[0]]) {
this._trapezoid(x[p[2]], y[p[2]], x[p[1]]-x[p[2]],x[p[0]]-x[p[1]],
y[p[1]]-y[p[0]], 0, color);
return
}
var y0 = this.roundMethod((y[p[2]] - y[p[0]]) *
(x[p[1]] - x[p[0]]) / (x[p[2]] - x[p[0]]) + y[p[0]]);
this._tri([x[p[0]], x[p[1]], x[p[1]]], [y[p[0]], y[p[1]], y0], color);
this._tri([x[p[2]], x[p[1]], x[p[1]]], [y[p[2]], y[p[1]], y0], color);
},
_splitV: function(x, y, color) {
var p = this._sortOrder(y);
if(x[p[0]]==x[p[2]] && y[p[2]] < y[p[1]] < y[p[0]]) {
this._trapezoidH(x[p[2]], y[p[2]], y[p[0]]-y[p[1]],
y[p[1]]-y[p[2]], x[p[1]]-x[p[0]], 0, color);
return
}
var x0 = this.roundMethod((x[p[2]] - x[p[0]]) *
(y[p[1]] - y[p[0]]) / (y[p[2]] - y[p[0]]) + x[p[0]]);
this._tri([x[p[0]], x[p[1]], x0], [y[p[0]], y[p[1]], y[p[1]]], color);
this._tri([x[p[2]], x[p[1]], x0], [y[p[2]], y[p[1]], y[p[1]]], color);
},
_rightTri: function(x, y, color)
/*
Iterates through all combinations to find
the position of the right corner
*/
{
for(var i=0, c; i<6; i++) {
c = [[0, 1, 2], [1, 2, 0], [2, 0, 1], [1, 0, 2], [0, 2, 1], [2, 1, 0]][i];
if(x[c[0]]==x[c[1]] && y[c[0]]==y[c[2]])
return this._rightTriangle(x[c[0]], y[c[0]], x[c[2]]-x[c[0]], y[c[1]]-y[c[0]], color);
}
},
_rightTriangle: function(x, y, dx, dy, color)
/*
Draws right triangle based on right angle,
endpoint coordinates, and catheti
|\
| \
dy | \
| \
| \
(x,y) o_____\
dx
*/
{
this.cache += "<div class='p' style='left:" +
(x + (dx<0 ? dx : 0)) + "px;top:" +
(y + (dy<0 ? dy : 0)) + "px;border-" +
(dx>0 ? "left" : "right") + ":" + Math.abs(dx) + "px solid " + color +
";border-" + (dy>0 ? "bottom:" : "top:") + Math.abs(dy) + "px solid " +
this.transparent + this.filter +
"'></div>";
},
_trapezoid: function(x, y, dx1, dx2, dy, w, color) {
this.cache += "<div class='p' style='left:" +
x + "px; top: " +
(y + (dy < 0 ? dy : 0)) + "px; width: " + w + "px; border-left:" +
Math.abs(dx1) + "px solid " + this.transparent + "; border-right:" +
Math.abs(dx2) + "px solid " + this.transparent + "; border-" +
(dy < 0 ? "bottom:" : "top:") + Math.abs(dy) + "px solid " + color + this.filter +
"'></div>";
},
_trapezoidH: function(x, y, dy1, dy2, dx, h, color) {
this.cache += "<div class='p' style='left:" +
(x + (dx < 0 ? dx : 0)) + "px; top: " +
y + "px; height: " + h + "px; border-top:" +
Math.abs(dy2) + "px solid " + this.transparent + "; border-bottom:" +
Math.abs(dy1) + "px solid " + this.transparent + "; border-" +
(dx<0 ? "right:" : "left:") + Math.abs(dx) + "px solid " + color + this.filter +
"'></div>";
}
};

this.DivCanvas = DivCanvas;

}).call(this)

34 changes: 34 additions & 0 deletions style.css
@@ -0,0 +1,34 @@

body {
background: gray;
}


/*
Canvas styles
should at least have
position: relative
*/
#divcanvas {
background: white;
width: 640px;
height: 480px;
margin: auto;
margin-top: 100px;
position: relative;
}


/* Basic css for generated elements */
div.p {
position: absolute;
overflow: hidden;
width: 0px;
height: 0px;
}
/* Used in textCircle */
span.p {
position: absolute;
cursor: default;
line-height: 1;
}
108 changes: 108 additions & 0 deletions test.html
@@ -0,0 +1,108 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>DivCanvas</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="style.css" type="text/css" media="screen">
<script src="divcanvas.js" type="text/javascript"></script>
</head>
<body>
<div id="divcanvas"></div>
<script>
// Init canvas
var canvas = new DivCanvas(document.getElementById("divcanvas"));

// Draw triangles
// canvas.triangle([470, 100, 300], [70, 400, 60], "red")
// canvas.triangle([70, 400, 30], [270, 200, 100], "blue")
// canvas.triangle([620, 200, 100], [170, 400, 360], "green")

// Test different circle methods
//canvas.setOpacity(.5)
//canvas.textCircle(460, 160, 100, "#b00")
canvas.circle(460, 160, 100, "#b00")

// Draw crane shape
var k = 2, dx = 100, dy = 380, // coefficients to scale and translate shape
crane = [
{
x: [48, 49, -19, -32, -6],
y: [-44, -17, -11, -33, -103],
c: "#c7d7e5"
},
{
x: [-25, -26, -32, 55, 55, 54, 54, 57, 50, 22, 13, 5, 0, -10, -19, -75],
y: [-14, 11, 28, 33, 27, 22, 19, 19, -18, -21, -21, -15, -16, -18, -18, -101],
c: "#394e4d"
},
{
x: [-78, -27, -22, -22, -76],
y: [-100, 13, 0, -14, -103],
c: "#628183"
},
{
x: [-79, -26, -33, -77],
y: [-97, 12, -13, -102],
c: "#aac7db"
},
{
x: [31, 24, 21, 44, 45, 34, 87, 93],
y: [-57, -29, -8, 10, 7, -52, -51, -55],
c: "#668082"
},
{
x: [46, 48, 38, 34 ],
y: [10, 2, -51, -53],
c: "#344747"
},
{
x: [28, 32, 92, 94],
y: [-57, -66, -60, -55],
c: "#879aa3"
},
{
x: [35, 29, 32, 27, 25, 23, 30, 34, 93],
y: [-61, -59, -66, -63, -54, -22, -54, -57, -55],
c: "#fbfbfb"
},
{
x: [-24, -16, -2, 13, 42, 39, -67, -70, -54, -32],
y: [10, -5, -11, -10, 20, 35, 106, 103, 46, 31],
c: "#e1e9ee"
},
{
x: [-20, -11, 3, 16, 29, 34, 25, 5, -10, -30],
y: [10, 0, -8, -6, 9, 22, 28, 34, 33, 30],
c: "#b0c7d2"
},
{
x: [30, 41, 38, -64, -67, -70, -66, 42, 43],
y: [7, 22, 34, 104, 105, 105, 108, 35, 20],
c: "#567e7c"
},
{
x: [16, 0, -6],
y: [-77, -55, -102],
c: "#acbdca"
},
{
x: [-57, -66, -27, -28],
y: [68, 103, 77, 52],
c: "#f7f9fa"
}
]

for (var i=0, x, y, j, n, l=crane.length; i<l; i++) {
x = [], y = []
for (j=0, n=crane[i].x.length; j<n; j++) {
x[j] = crane[i].x[j] * k + dx
y[j] = crane[i].y[j] * k + dy
}
canvas.polygon(x, y, crane[i].c)
}

// Show the drawing
canvas.flush()
</script>
</body>
</html>

0 comments on commit 85429ea

Please sign in to comment.