Skip to content

Instantly share code, notes, and snippets.

@danschumann
Last active July 6, 2016 15:32
Show Gist options
  • Save danschumann/ec0745f9e1889c0c6e9d to your computer and use it in GitHub Desktop.
Save danschumann/ec0745f9e1889c0c6e9d to your computer and use it in GitHub Desktop.
Dashed lines poly for canvas
_moveTo = CanvasRenderingContext2D::moveTo
_lineTo = CanvasRenderingContext2D::lineTo
_save = CanvasRenderingContext2D::save
_restore = CanvasRenderingContext2D::restore
keys = ['_lineDash', '_lineDashSegment', '_lineDashTime', '_lineDashActive', '_lineDashLast']
CanvasRenderingContext2D::save = ->
@['_saved' + k] = @[k] for k in keys
_save.apply this, arguments
CanvasRenderingContext2D::restore = ->
@[k] = @['_saved' + k] for k in keys
_restore.apply this, arguments
# Call this whatever you want --
# We're going to assume that there isn't much native support, going 100% custom
CanvasRenderingContext2D::setLineDashCustom = (args...) ->
# Segment index will dictate which part of out options we're on
@_lineDashSegment = 0
# Time step will indicate what part of a segment we're on
@_lineDashTime ?= 0
@_lineDashActive = true
@_lineDash = args
CanvasRenderingContext2D::moveTo = (x, y) ->
@_lineDashLast = {x, y}
_moveTo.apply this, arguments
CanvasRenderingContext2D::lineTo = (x, y) ->
{x: _x, y: _y} = @_lineDashLast
@_lineDashLast = {x, y}
if '_lineDash' of this and @_lineDash
dx = x - _x
dy = y - _y
dist = Math.sqrt(dx * dx + dy * dy)
while dist
distTilNext = @_lineDash[ @_lineDashSegment ] - @_lineDashTime
_moveTo.call this, _x, _y
if distTilNext > dist
if @_lineDashActive
_lineTo.call this, x, y
@_lineDashTime += dist # this is how much further we progressed it
dist = 0
else
factor = distTilNext / dist
_x = _x * (1-factor) + x * (factor)
_y = _y * (1-factor) + y * (factor)
if @_lineDashActive
_lineTo.call this, _x, _y
@_lineDashActive = not @_lineDashActive
dist -= distTilNext
@_lineDashSegment = (@_lineDashSegment+1) % @_lineDash.length # increment
@_lineDashTime = 0
else
_lineTo.call this, x, y
var _lineTo, _moveTo, _restore, _save, keys,
slice = [].slice;
_moveTo = CanvasRenderingContext2D.prototype.moveTo;
_lineTo = CanvasRenderingContext2D.prototype.lineTo;
_save = CanvasRenderingContext2D.prototype.save;
_restore = CanvasRenderingContext2D.prototype.restore;
keys = ['_lineDash', '_lineDashSegment', '_lineDashTime', '_lineDashActive', '_lineDashLast'];
CanvasRenderingContext2D.prototype.save = function() {
var i, k, len;
for (i = 0, len = keys.length; i < len; i++) {
k = keys[i];
this['_saved' + k] = this[k];
}
return _save.apply(this, arguments);
};
CanvasRenderingContext2D.prototype.restore = function() {
var i, k, len;
for (i = 0, len = keys.length; i < len; i++) {
k = keys[i];
this[k] = this['_saved' + k];
}
return _restore.apply(this, arguments);
};
CanvasRenderingContext2D.prototype.setLineDashCustom = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
/*
if "mozDash" of this
@mozDash = args
else if "webkitLineDash" of this
@webkitLineDash = args
else
*/
this._lineDashSegment = 0;
if (this._lineDashTime == null) {
this._lineDashTime = 0;
}
this._lineDashActive = true;
return this._lineDash = args;
};
CanvasRenderingContext2D.prototype.moveTo = function(x, y) {
this._lineDashLast = {
x: x,
y: y
};
return _moveTo.apply(this, arguments);
};
CanvasRenderingContext2D.prototype.lineTo = function(x, y) {
var _x, _y, dist, distTilNext, dx, dy, factor, ref, results;
ref = this._lineDashLast, _x = ref.x, _y = ref.y;
this._lineDashLast = {
x: x,
y: y
};
if ('_lineDash' in this && this._lineDash) {
dx = x - _x;
dy = y - _y;
dist = Math.sqrt(dx * dx + dy * dy);
results = [];
while (dist) {
distTilNext = this._lineDash[this._lineDashSegment] - this._lineDashTime;
_moveTo.call(this, _x, _y);
if (distTilNext > dist) {
if (this._lineDashActive) {
_lineTo.call(this, x, y);
}
this._lineDashTime += dist;
results.push(dist = 0);
} else {
factor = distTilNext / dist;
_x = _x * (1 - factor) + x * factor;
_y = _y * (1 - factor) + y * factor;
if (this._lineDashActive) {
_lineTo.call(this, _x, _y);
}
this._lineDashActive = !this._lineDashActive;
dist -= distTilNext;
this._lineDashSegment = (this._lineDashSegment + 1) % this._lineDash.length;
results.push(this._lineDashTime = 0);
}
}
return results;
} else {
return _lineTo.call(this, x, y);
}
};
// ---
// generated by coffee-script 1.9.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment