Add initial canvas implementation of replay API
This commit is contained in:
220
src/ol/replay/canvas/canvasbatchgroup.js
Normal file
220
src/ol/replay/canvas/canvasbatchgroup.js
Normal file
@@ -0,0 +1,220 @@
|
||||
// FIXME store coordinates in batchgroup?
|
||||
// FIXME flattened coordinates
|
||||
// FIXME per-batch extent tests
|
||||
|
||||
goog.provide('ol.replay.canvas.BatchGroup');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.functions');
|
||||
goog.require('goog.object');
|
||||
goog.require('ol.replay');
|
||||
goog.require('ol.replay.IBatch');
|
||||
goog.require('ol.replay.IBatchGroup');
|
||||
|
||||
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
ol.replay.canvas.InstructionType = {
|
||||
DRAW_LINE_STRING_GEOMETRY: 0,
|
||||
SET_STROKE_STYLE: 1
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{argument: ?,
|
||||
* type: ol.replay.canvas.InstructionType}}
|
||||
*/
|
||||
ol.replay.canvas.Instruction;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements {ol.replay.IBatch}
|
||||
*/
|
||||
ol.replay.canvas.Batch = function() {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<ol.replay.canvas.Instruction>}
|
||||
*/
|
||||
this.instructions_ = [];
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.coordinates_ = [];
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.pixelCoordinates_ = [];
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {CanvasRenderingContext2D} context Context.
|
||||
* @param {goog.vec.Mat4.AnyType} transform Transform.
|
||||
*/
|
||||
ol.replay.canvas.Batch.prototype.draw = function(context, transform) {
|
||||
var pixelCoordinates = ol.replay.transformCoordinates(
|
||||
this.coordinates_, transform, this.pixelCoordinates_);
|
||||
this.pixelCoordinates_ = pixelCoordinates; // FIXME ?
|
||||
var begunPath = false;
|
||||
var fillPending = false;
|
||||
var strokePending = false;
|
||||
var flushPath = function() {
|
||||
if (strokePending || fillPending) {
|
||||
if (strokePending) {
|
||||
context.stroke();
|
||||
strokePending = false;
|
||||
}
|
||||
if (fillPending) {
|
||||
context.fill();
|
||||
fillPending = false;
|
||||
}
|
||||
context.beginPath();
|
||||
begunPath = true;
|
||||
}
|
||||
};
|
||||
var instructions = this.instructions_;
|
||||
var i = 0;
|
||||
var j, jj;
|
||||
for (j = 0, jj = instructions.length; j < jj; ++j) {
|
||||
var instruction = instructions[j];
|
||||
if (instruction.type ==
|
||||
ol.replay.canvas.InstructionType.DRAW_LINE_STRING_GEOMETRY) {
|
||||
if (!begunPath) {
|
||||
context.beginPath();
|
||||
begunPath = true;
|
||||
}
|
||||
context.moveTo(pixelCoordinates[i], pixelCoordinates[i + 1]);
|
||||
goog.asserts.assert(goog.isNumber(instruction.argument));
|
||||
var ii = /** @type {number} */ (instruction.argument);
|
||||
for (i += 2; i < ii; i += 2) {
|
||||
context.lineTo(pixelCoordinates[i], pixelCoordinates[i + 1]);
|
||||
}
|
||||
strokePending = true;
|
||||
} else if (instruction.type ==
|
||||
ol.replay.canvas.InstructionType.SET_STROKE_STYLE) {
|
||||
flushPath();
|
||||
goog.asserts.assert(goog.isObject(instruction.argument));
|
||||
var strokeStyle = /** @type {ol.style.Stroke} */ (instruction.argument);
|
||||
context.strokeStyle = strokeStyle.color;
|
||||
context.lineWidth = strokeStyle.width;
|
||||
}
|
||||
}
|
||||
flushPath();
|
||||
goog.asserts.assert(i == pixelCoordinates.length);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.replay.canvas.Batch.prototype.drawLineStringGeometry =
|
||||
function(lineStringGeometry) {
|
||||
var coordinates = this.coordinates_;
|
||||
var lineStringCoordinates = lineStringGeometry.getCoordinates();
|
||||
var i = coordinates.length;
|
||||
var j, jj;
|
||||
for (j = 0, jj = lineStringCoordinates.length; j < jj; ++j) {
|
||||
coordinates[i++] = lineStringCoordinates[j][0];
|
||||
coordinates[i++] = lineStringCoordinates[j][1];
|
||||
}
|
||||
this.instructions_.push({
|
||||
type: ol.replay.canvas.InstructionType.DRAW_LINE_STRING_GEOMETRY,
|
||||
argument: i
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.replay.canvas.Batch.prototype.setStrokeStyle = function(strokeStyle) {
|
||||
this.instructions_.push({
|
||||
type: ol.replay.canvas.InstructionType.SET_STROKE_STYLE,
|
||||
argument: strokeStyle
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements {ol.replay.IBatchGroup}
|
||||
*/
|
||||
ol.replay.canvas.BatchGroup = function() {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string,
|
||||
* Object.<ol.replay.BatchType, ol.replay.canvas.Batch>>}
|
||||
*/
|
||||
this.batchesByZIndex_ = {};
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {CanvasRenderingContext2D} context Context.
|
||||
* @param {goog.vec.Mat4.AnyType} transform Transform.
|
||||
*/
|
||||
ol.replay.canvas.BatchGroup.prototype.draw = function(context, transform) {
|
||||
window.console.log('drawing batch');
|
||||
/** @type {Array.<number>} */
|
||||
var zs = goog.array.map(goog.object.getKeys(this.batchesByZIndex_), Number);
|
||||
goog.array.sort(zs);
|
||||
var i, ii;
|
||||
for (i = 0, ii = zs.length; i < ii; ++i) {
|
||||
var batches = this.batchesByZIndex_[zs[i].toString()];
|
||||
var batchType;
|
||||
for (batchType in batches) {
|
||||
var batch = batches[batchType];
|
||||
batch.draw(context, transform);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.replay.canvas.BatchGroup.prototype.getBatch = function(zIndex, batchType) {
|
||||
var zIndexKey = zIndex.toString();
|
||||
var batches = this.batchesByZIndex_[zIndexKey];
|
||||
if (!goog.isDef(batches)) {
|
||||
batches = {};
|
||||
this.batchesByZIndex_[zIndexKey] = batches;
|
||||
}
|
||||
var batch = batches[batchType];
|
||||
if (!goog.isDef(batch)) {
|
||||
var constructor = ol.replay.canvas.BATCH_CONSTRUCTORS_[batchType];
|
||||
goog.asserts.assert(goog.isDef(constructor));
|
||||
batch = new constructor();
|
||||
batches[batchType] = batch;
|
||||
}
|
||||
return batch;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.replay.canvas.BatchGroup.prototype.isEmpty = goog.functions.FALSE; // FIXME
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @private
|
||||
* @type {Object.<ol.replay.BatchType, function(new: ol.replay.canvas.Batch)>}
|
||||
*/
|
||||
ol.replay.canvas.BATCH_CONSTRUCTORS_ = {
|
||||
'strokeLine': ol.replay.canvas.Batch
|
||||
};
|
||||
Reference in New Issue
Block a user