-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #48 from conveyal/dev
Next release
- Loading branch information
Showing
33 changed files
with
12,720 additions
and
5,995 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,19 @@ | ||
sudo: false | ||
language: node_js | ||
cache: | ||
directories: | ||
- ~/.yarn-cache | ||
yarn: true | ||
notifications: | ||
email: false | ||
node_js: | ||
- '6' | ||
before_install: | ||
- npm i -g yarn codecov | ||
- '10' | ||
install: | ||
- yarn | ||
script: | ||
- npm run lint | ||
- npm run cover | ||
- codecov | ||
after_success: | ||
- yarn run semantic-release | ||
- bash <(curl -s https://codecov.io/bash) | ||
- semantic-release | ||
branches: | ||
except: | ||
- /^v\d+\.\d+\.\d+$/ |
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
import roundedRect from 'rounded-rect' | ||
|
||
import Display from './display' | ||
|
||
export default class CanvasDisplay extends Display { | ||
constructor (transitive) { | ||
super(transitive) | ||
|
||
const { el, canvas } = transitive.options | ||
|
||
// Handle case of externally-provided canvas | ||
if (canvas) { | ||
// Set internal dimensions to match those of canvas | ||
this.setDimensions(canvas.width, canvas.height) | ||
this.setCanvas(canvas) | ||
|
||
// We have a DOM element; create canvas | ||
} else if (el) { | ||
this.setDimensions(el.clientWidth, el.clientHeight) | ||
|
||
const canvas = document.createElement('canvas') | ||
canvas.width = el.clientWidth | ||
canvas.height = el.clientHeight | ||
el.appendChild(canvas) | ||
|
||
// Check for Hi-PPI display | ||
if (window.devicePixelRatio > 1) makeCanvasHiPPI(canvas) | ||
|
||
this.setCanvas(canvas) | ||
} | ||
} | ||
|
||
setCanvas (canvas) { | ||
this.canvas = canvas | ||
this.ctx = this.canvas.getContext('2d') | ||
} | ||
|
||
clear () { | ||
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height) | ||
} | ||
|
||
drawRect (upperLeft, attrs) { | ||
this.ctx.strokeStyle = attrs['stroke'] | ||
this.ctx.lineWidth = attrs['stroke-width'] | ||
this.ctx.fillStyle = attrs['fill'] | ||
|
||
this.ctx.beginPath() | ||
if (attrs.rx && attrs.ry && attrs.rx === attrs.ry) { | ||
roundedRect(this.ctx, upperLeft.x, upperLeft.y, attrs.width, attrs.height, attrs.rx) | ||
// TODO: handle case where rx != ry | ||
} else { // ordinary rectangle | ||
this.ctx.rect(upperLeft.x, upperLeft.y, attrs.width, attrs.height) | ||
} | ||
this.ctx.closePath() | ||
|
||
if (attrs['fill']) this.ctx.fill() | ||
if (attrs['stroke']) this.ctx.stroke() | ||
} | ||
|
||
drawCircle (center, attrs) { | ||
this.ctx.beginPath() | ||
this.ctx.arc(center.x, center.y, attrs.r, 0, Math.PI * 2, true) | ||
this.ctx.closePath() | ||
|
||
if (attrs['fill']) { | ||
this.ctx.fillStyle = attrs['fill'] | ||
this.ctx.fill() | ||
} | ||
if (attrs['stroke']) { | ||
this.ctx.strokeStyle = attrs['stroke'] | ||
this.ctx.lineWidth = attrs['stroke-width'] || 1 | ||
this.ctx.stroke() | ||
} | ||
} | ||
|
||
drawEllipse (center, attrs) { | ||
// TODO: implement | ||
} | ||
|
||
drawPath (renderData, attrs) { | ||
if (!renderData || renderData.length === 0) return | ||
|
||
// Apply stroke/width styles | ||
this.ctx.strokeStyle = attrs['stroke'] | ||
this.ctx.lineWidth = attrs['stroke-width'] | ||
|
||
// Apply line-dash style, if present | ||
if (attrs['stroke-dasharray']) { | ||
const arr = attrs['stroke-dasharray'].split(',').map(str => parseFloat(str.trim())) | ||
this.ctx.setLineDash(arr) | ||
} | ||
|
||
// Apply linecap style | ||
this.ctx.lineCap = attrs['stroke-linecap'] || 'butt' | ||
|
||
// Draw the path | ||
this.ctx.beginPath() | ||
this.ctx.moveTo(renderData[0].x, renderData[0].y) | ||
for (let i = 1; i < renderData.length; i++) { | ||
const rd = renderData[i] | ||
if (rd.arc) this.ctx.arcTo(rd.ex, rd.ey, rd.x, rd.y, rd.radius) | ||
else this.ctx.lineTo(rd.x, rd.y) | ||
} | ||
this.ctx.stroke() | ||
|
||
// Revert line-dash style to default | ||
if (attrs['stroke-dasharray']) this.ctx.setLineDash([]) | ||
} | ||
|
||
drawText (text, anchor, attrs) { | ||
// For equivalence w/ SVG text rendering | ||
this.ctx.textBaseline = 'top' | ||
|
||
this.ctx.font = `${attrs.fontSize || '14px'} ${attrs.fontFamily || 'sans-serif'}` | ||
if (attrs['text-anchor']) this.ctx.textAlign = attrs['text-anchor'] | ||
|
||
if (attrs['stroke']) { | ||
this.ctx.strokeStyle = attrs['stroke'] | ||
if (attrs['stroke-opacity']) this.ctx.globalAlpha = attrs['stroke-opacity'] | ||
this.ctx.lineWidth = attrs['stroke-width'] || 1 | ||
this.ctx.strokeText(text, anchor.x, anchor.y) | ||
} | ||
if (attrs['fill']) { | ||
this.ctx.fillStyle = attrs['fill'] | ||
if (attrs['fill-opacity']) this.ctx.globalAlpha = attrs['fill-opacity'] | ||
this.ctx.fillText(text, anchor.x, anchor.y) | ||
} | ||
|
||
this.ctx.textAlign = 'start' | ||
this.ctx.globalAlpha = 1 | ||
} | ||
} | ||
|
||
// Utility function to support HiPPI displays (e.g. Retina) | ||
function makeCanvasHiPPI (canvas) { | ||
const PIXEL_RATIO = 2 | ||
canvas.style.width = canvas.width + 'px' | ||
canvas.style.height = canvas.height + 'px' | ||
|
||
canvas.width *= PIXEL_RATIO | ||
canvas.height *= PIXEL_RATIO | ||
|
||
var context = canvas.getContext('2d') | ||
context.scale(PIXEL_RATIO, PIXEL_RATIO) | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.