Last active
July 6, 2016 15:32
-
-
Save danschumann/ec0745f9e1889c0c6e9d to your computer and use it in GitHub Desktop.
Dashed lines poly for canvas
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
_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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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