Canvas Inner Shadow on Polygon
Inner Shadow effect that supports polygons, even with holes.
by warriormole
HTML
<script src="https://rawgit.com/MadLittleMods/4dd235b9cdcd79c57efd/raw/22aa676be65567b99536fb79e2b6b724495bde43/clipper-6-1-3a.js"></script>
<div>
Created by <a href="http://ericeastwood.com/">Eric Eastwood</a>
<br />
Inner Shadow effect
</div>
<div>
Using this technique: <a href="http://www.rgraph.net/blog/2013/april/an-example-of-html5-canvas-shadows.html">RGraph: example of using canvas shadows</a>
</div>
<div>
Using <a href="http://sourceforge.net/projects/jsclipper/">jsClipper</a> for offsetting polygons.
</div>
<canvas class="main-canvas" width="720" height="480"></canvas>
CSS
body
{
background: #333333;
color: #eeeeee;
font-family: Arial;
font-size: 14px;
}
a
{
color: inherit;
}
JavaScript
function polygon_offset(pointList, offset)
{
// Scale up the path so it is easier to see
//var scale = 100;
//ClipperLib.JS.ScaleUpPath(holePointList, scale);
// Possibly ClipperLib.Clipper.SimplifyPolygons() here
// Possibly ClipperLib.Clipper.CleanPolygons() here
// MiterLimit: http://sourceforge.net/p/jsclipper/wiki/documentation/#clipperlibclipperoffsetmiterlimit
// roundPrecision
var co = new ClipperLib.ClipperOffset(20, 0.25);
co.AddPath(pointList, ClipperLib.JoinType.jtMiter, ClipperLib.EndType.etClosedPolygon);
var offsetted_paths = new ClipperLib.Paths();
co.Execute(offsetted_paths, offset);
if(offsetted_paths.length)
{
var resultant_point_list = [];
offsetted_paths[0].forEach(function(point, index, array) {
// Clipper uses a slightly differnt format
resultant_point_list.push(new Vector2(point.X, point.Y));
});
}
return resultant_point_list || false;
}
function Vector2(x, y)
{
this.x = x;
this.X = x;
this.y = y;
this.Y = y;
}
Vector2.prototype.add = function(other) {
return new Vector2(this.x + other.x, this.y + other.y);
}
Vector2.prototype.subtract = function(other) {
return new Vector2(this.x - other.x, this.y - other.y);
}
Vector2.prototype.scale = function(scalar) {
return new Vector2(this.x*scalar, this.y*scalar);
}
Vector2.prototype.normalized = function() {
var magnitude = Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2));
return new Vector2(this.x/magnitude, this.y/magnitude);
}
Vector2.prototype.dot = function(other) {
return this.x*other.x + this.y*other.y;
}
Vector2.prototype.closestPointOnLine = function(pt1, pt2)
{
var A = this.subtract(pt1);
var u = pt2.subtract(pt1).normalized();
return pt1.add(u.scale(A.dot(u)));
}
Vector2.prototype.vector2Args = function(x, y) {
x = x || 0;
y = y || 0;
return [this.x + x, this.y + y];
}
function Rect(position, width, height)
{
this.position = position;
this.width = width;
this.height = height;
}
Rect.prototype.rectArgs = function(x, y,...