cycle-canvas
Advanced tools
Comparing version 0.2.0 to 0.3.0
@@ -9,2 +9,4 @@ 'use strict'; | ||
exports.translateVtreeToInstructions = translateVtreeToInstructions; | ||
exports.renderInstructionsToCanvas = renderInstructionsToCanvas; | ||
exports.c = c; | ||
@@ -14,119 +16,216 @@ exports.rect = rect; | ||
exports.line = line; | ||
exports.polygon = polygon; | ||
exports.makeCanvasDriver = makeCanvasDriver; | ||
function renderElement(context, element, parent) { | ||
if (!element) { | ||
return; | ||
} | ||
if (!parent) { | ||
parent = { x: 0, y: 0 }; | ||
} | ||
var _xstreamAdapter = require('@cycle/xstream-adapter'); | ||
var origin = { | ||
x: element.x ? parent.x + element.x : parent.x, | ||
y: element.y ? parent.y + element.y : parent.y | ||
}; | ||
var _xstreamAdapter2 = _interopRequireDefault(_xstreamAdapter); | ||
preDrawHooks(element, context); | ||
var _xstream = require('xstream'); | ||
if (element.font) { | ||
context.font = element.font; | ||
} | ||
var _xstream2 = _interopRequireDefault(_xstream); | ||
var elementMapping = { | ||
rect: drawRect, | ||
text: drawText, | ||
line: drawLine | ||
}; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var elementFunction = elementMapping[element.kind]; | ||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } | ||
elementFunction(context, element, origin); | ||
function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); } | ||
element.children && element.children.forEach(function (child) { | ||
return renderElement(context, child, element); | ||
}); | ||
function flatten(array) { | ||
if (typeof array.reduce !== 'function') { | ||
return array; | ||
} | ||
postDrawHooks(context); | ||
return array.reduce(function (flatArray, arrayElement) { | ||
return flatArray.concat(flatten(arrayElement)); | ||
}, []); | ||
} | ||
function drawLine(context, element, origin) { | ||
context.lineWidth = element.style.lineWidth || 1; | ||
context.lineCap = element.style.lineCap || 'butt'; | ||
context.lineJoin = element.style.lineJoin || 'miter'; | ||
context.strokeStyle = element.style.strokeStyle || 'black'; | ||
var lineDash = element.style.lineDash; | ||
if (lineDash && lineDash.constructor === Array) { | ||
context.setLineDash(element.style.lineDash); | ||
} | ||
context.moveTo(origin.x, origin.y); | ||
context.beginPath(); | ||
element.points.forEach(function (point) { | ||
context.lineTo(origin.x + point.x, origin.y + point.y); | ||
function compact(array) { | ||
return array.filter(function (element) { | ||
return element !== undefined && element !== null; | ||
}); | ||
context.stroke(); | ||
context.setLineDash([]); | ||
} | ||
function drawRect(context, element, origin) { | ||
element.draw.forEach(function (operation) { | ||
context.lineWidth = operation.lineWidth || 1; | ||
function translateRect(element, origin) { | ||
return element.draw.map(function (operation) { | ||
var operations = [{ set: 'lineWidth', value: operation.lineWidth || 1 }]; | ||
if (operation.clear) { | ||
context.clearRect(origin.x, origin.y, element.width, element.height); | ||
operations.push({ | ||
call: 'clearRect', | ||
args: [origin.x, origin.y, element.width, element.height] | ||
}); | ||
} | ||
if (operation.fill) { | ||
context.fillStyle = operation.fill || 'black'; | ||
operations.push({ | ||
set: 'fillStyle', | ||
value: operation.fill || 'black' | ||
}); | ||
context.fillRect(origin.x, origin.y, element.width, element.height); | ||
operations.push({ | ||
call: 'fillRect', | ||
args: [origin.x, origin.y, element.width, element.height] | ||
}); | ||
} | ||
if (operation.stroke) { | ||
context.strokeStyle = operation.stroke || 'black'; | ||
operations.push({ | ||
set: 'strokeStyle', | ||
value: operation.stroke || 'black' | ||
}); | ||
context.strokeRect(origin.x, origin.y, element.width, element.height); | ||
operations.push({ | ||
call: 'strokeRect', | ||
args: [origin.x, origin.y, element.width, element.height] | ||
}); | ||
} | ||
return operations; | ||
}); | ||
} | ||
function drawText(context, element, origin) { | ||
element.draw.forEach(function (operation) { | ||
context.textAlign = element.textAlign || 'left'; | ||
function translateLine(element, origin) { | ||
var operations = [{ set: 'lineWidth', value: element.style.lineWidth || 1 }, { set: 'lineCap', value: element.style.lineCap || 'butt' }, { set: 'lineJoin', value: element.style.lineJoin || 'mitter' }, { set: 'strokeStyle', value: element.style.strokeStyle || 'black' }]; | ||
if (element.style.lineDash && element.style.lineDash.constructor === Array) { | ||
operations.push({ | ||
call: 'setLineDash', | ||
args: element.style.lineDash | ||
}); | ||
} | ||
operations.push({ | ||
call: 'moveTo', | ||
args: [origin.x, origin.y] | ||
}); | ||
operations.push({ | ||
call: 'beginPath', | ||
args: [] | ||
}); | ||
element.points.forEach(function (point) { | ||
operations.push({ | ||
call: 'lineTo', | ||
args: [origin.x + point.x, origin.y + point.y] | ||
}); | ||
}); | ||
operations.push({ | ||
call: 'stroke', | ||
args: [] | ||
}); | ||
operations.push({ | ||
call: 'setLineDash', | ||
args: [] | ||
}); | ||
return operations; | ||
} | ||
function translatePolygon(element, origin) { | ||
var _element$points = _toArray(element.points); | ||
var first = _element$points[0]; | ||
var rest = _element$points.slice(1); | ||
return [].concat([{ call: 'beginPath', args: [] }], [{ call: 'moveTo', args: [origin.x + first.x, origin.y + first.y] }], rest.map(function (point) { | ||
return { call: 'lineTo', args: [origin.x + point.x, origin.y + point.y] }; | ||
}), [{ call: 'closePath', args: [] }], element.draw.map(function (operation) { | ||
var fillInstructions = [{ set: 'fillStyle', value: operation.fill }, { call: 'fill', args: [] }]; | ||
var strokeInstructions = [{ set: 'strokeStyle', value: operation.stroke }, { call: 'stroke', args: [] }]; | ||
return operation.fill ? fillInstructions : operation.stroke ? strokeInstructions : []; | ||
})); | ||
} | ||
function translateText(element, origin) { | ||
return element.draw.map(function (operation) { | ||
var operations = [{ set: 'textAlign', value: element.textAlign || 'left' }, { set: 'font', value: element.font }]; | ||
var args = [element.value, origin.x, origin.y]; | ||
if (element.width) { | ||
args.push(element.width); | ||
} | ||
if (operation.fill) { | ||
context.fillStyle = operation.fill || 'black'; | ||
operations.push({ | ||
set: 'fillStyle', | ||
value: operation.fill || 'black' | ||
}); | ||
context.fillText(element.value, origin.x, origin.y, element.width); | ||
operations.push({ | ||
call: 'fillText', | ||
args: args | ||
}); | ||
} | ||
if (operation.stroke) { | ||
context.strokeStyle = operation.stroke || 'black'; | ||
operations.push({ | ||
set: 'strokeStyle', | ||
value: operation.stroke || 'black' | ||
}); | ||
context.strokeText(element.value, origin.x, origin.y, element.width); | ||
operations.push({ | ||
call: 'strokeText', | ||
args: args | ||
}); | ||
} | ||
return operations; | ||
}); | ||
} | ||
function preDrawHooks(element, context) { | ||
context.save(); | ||
if (!element.transformations) { | ||
function translateVtreeToInstructions(element, parentEl) { | ||
if (!element) { | ||
return; | ||
} | ||
element.transformations.forEach(function (transformation) { | ||
if (transformation.translate) { | ||
context.translate(transformation.translate.x, transformation.translate.y); | ||
} | ||
if (!parentEl) { | ||
parentEl = { x: 0, y: 0 }; | ||
} | ||
if (transformation.rotate) { | ||
context.rotate(transformation.rotate); | ||
} | ||
var origin = { | ||
x: element.x ? parentEl.x + element.x : parentEl.x, | ||
y: element.y ? parentEl.y + element.y : parentEl.y | ||
}; | ||
if (transformation.scale) { | ||
context.scale(transformation.scale.x, transformation.scale.y); | ||
var elementMapping = { | ||
rect: translateRect, | ||
line: translateLine, | ||
text: translateText, | ||
polygon: translatePolygon | ||
}; | ||
var instructions = preDrawHooks(element); | ||
instructions.push(elementMapping[element.kind](element, origin)); | ||
instructions.push(postDrawHooks()); | ||
var flatInstructions = compact(flatten(instructions)); | ||
if (element.children) { | ||
element.children.forEach(function (child) { | ||
var childInstructions = translateVtreeToInstructions(child, element); | ||
if (childInstructions) { | ||
flatInstructions.push.apply(flatInstructions, _toConsumableArray(childInstructions)); | ||
} | ||
}); | ||
} | ||
return flatInstructions; | ||
} | ||
function renderInstructionsToCanvas(instructions, context) { | ||
instructions.forEach(function (instruction) { | ||
if (instruction.set) { | ||
context[instruction.set] = instruction.value; | ||
} else if (instruction.call) { | ||
context[instruction.call].apply(context, _toConsumableArray(instruction.args)); | ||
} | ||
@@ -136,6 +235,37 @@ }); | ||
function postDrawHooks(context) { | ||
context.restore(); | ||
function preDrawHooks(element) { | ||
var operations = [{ call: 'save', args: [] }]; | ||
if (element.transformations) { | ||
element.transformations.forEach(function (transformation) { | ||
if (transformation.translate) { | ||
operations.push({ | ||
call: 'translate', | ||
args: [transformation.translate.x, transformation.translate.y] | ||
}); | ||
} | ||
if (transformation.rotate) { | ||
operations.push({ | ||
call: 'rotate', | ||
args: [transformation.rotate] | ||
}); | ||
} | ||
if (transformation.scale) { | ||
operations.push({ | ||
call: 'scale', | ||
args: [transformation.scale.x, transformation.scale.y] | ||
}); | ||
} | ||
}); | ||
} | ||
return operations; | ||
} | ||
function postDrawHooks() { | ||
return [{ call: 'restore', args: [] }]; | ||
} | ||
function c(kind, opts, children) { | ||
@@ -173,2 +303,6 @@ if (opts.children) { | ||
function polygon(opts, children) { | ||
return c('polygon', opts, children); | ||
} | ||
function makeCanvasDriver(selector, _ref) { | ||
@@ -191,18 +325,33 @@ var width = _ref.width; | ||
return function canvasDriver(sink$) { | ||
return sink$.subscribe(function (rootElement) { | ||
var defaults = { | ||
kind: 'rect', | ||
x: 0, | ||
y: 0, | ||
width: canvas.width, | ||
height: canvas.height, | ||
draw: [{ clear: true }] | ||
}; | ||
var driver = function canvasDriver(sink$) { | ||
sink$.addListener({ | ||
next: function next(rootElement) { | ||
var defaults = { | ||
kind: 'rect', | ||
x: 0, | ||
y: 0, | ||
width: canvas.width, | ||
height: canvas.height, | ||
draw: [{ clear: true }] | ||
}; | ||
var rootElementWithDefaults = Object.assign({}, defaults, rootElement); | ||
var rootElementWithDefaults = Object.assign({}, defaults, rootElement); | ||
renderElement(context, rootElementWithDefaults); | ||
var instructions = translateVtreeToInstructions(rootElementWithDefaults); | ||
renderInstructionsToCanvas(instructions, context); | ||
}, | ||
error: function error(e) { | ||
throw e; | ||
}, | ||
complete: function complete() { | ||
return null; | ||
} | ||
}); | ||
return _xstream2.default.empty(); | ||
}; | ||
driver.streamAdapter = _xstreamAdapter2.default; | ||
return driver; | ||
} |
{ | ||
"name": "cycle-canvas", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "A canvas driver for Cycle.js", | ||
"main": "lib/canvas-driver.js", | ||
"jspm": { | ||
"main": "src/canvas-driver.js" | ||
}, | ||
"scripts": { | ||
"start": "babel-node ./examples/flappy-bird/server.js", | ||
"test": "mocha --compilers js:babel-register", | ||
"test": "mocha --compilers js:babel-core/register", | ||
"autotest": "mocha --compilers js:babel-core/register --watch -R min", | ||
"bundle": "browserify ./examples/flappy-bird/index.js -t babelify -t uglifyify -o bundle.js", | ||
@@ -15,3 +19,3 @@ "precompile-lib": "rm -rf lib/ && mkdir -p lib", | ||
"files": [ | ||
"lib/" | ||
"lib/" | ||
], | ||
@@ -23,6 +27,6 @@ "repository": { | ||
"keywords": [ | ||
"hot", | ||
"reloading", | ||
"cycle.js", | ||
"happiness" | ||
"canvas", | ||
"driver", | ||
"cycle", | ||
"cycle.js" | ||
], | ||
@@ -36,21 +40,27 @@ "author": "Nick Johnstone", | ||
"devDependencies": { | ||
"@cycle/core": "^6.0.0-rc2", | ||
"@cycle/dom": "^9.0.1", | ||
"@cycle/isolate": "^1.2.0", | ||
"@cycle/rx-run": "^7.0.1", | ||
"assert": "^1.3.0", | ||
"babel-cli": "^6.2.0", | ||
"babel-core": "^6.2.1", | ||
"babel-plugin-transform-object-rest-spread": "^6.6.5", | ||
"babel-preset-es2015": "^6.1.18", | ||
"babelify": "^7.2.0", | ||
"box-collide": "^1.0.2", | ||
"browserify": "^12.0.1", | ||
"browserify-hmr": "^0.3.1", | ||
"budo": "^6.1.0", | ||
"cycle-animation-driver": "^0.1.3", | ||
"cycle-restart": "0.0.14", | ||
"keycode": "^2.1.1", | ||
"lodash": "^4.8.1", | ||
"mocha": "^2.4.5", | ||
"rx": "^4.0.7", | ||
"babel-cli": "^6.2.0", | ||
"babel-core": "^6.2.1", | ||
"babelify": "^7.2.0", | ||
"browserify": "^12.0.1", | ||
"browserify-hmr": "^0.3.1", | ||
"budo": "^6.1.0", | ||
"lodash": "^4.8.1", | ||
"uglifyify": "^3.0.1" | ||
}, | ||
"dependencies": { | ||
"@cycle/xstream-adapter": "^3.0.3", | ||
"xstream": "^6.2.0" | ||
} | ||
} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
274
11704
2
20
3
2
0
2
+ Addedxstream@^6.2.0
+ Added@cycle/xstream-adapter@3.1.0(transitive)
+ Addedsymbol-observable@1.2.0(transitive)
+ Addedxstream@6.6.0(transitive)