Skip to content

Commit

Permalink
convert painter and other render classes to ES6 class syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
mourner committed Oct 19, 2016
1 parent 2136d9b commit 1d712b7
Show file tree
Hide file tree
Showing 5 changed files with 618 additions and 615 deletions.
111 changes: 57 additions & 54 deletions js/render/frame_history.js
Original file line number Diff line number Diff line change
@@ -1,70 +1,73 @@
'use strict';

module.exports = FrameHistory;

function FrameHistory() {
this.changeTimes = new Float64Array(256);
this.changeOpacities = new Uint8Array(256);
this.opacities = new Uint8ClampedArray(256);
this.array = new Uint8Array(this.opacities.buffer);

this.fadeDuration = 300;
this.previousZoom = 0;
this.firstFrame = true;
}
class FrameHistory {

FrameHistory.prototype.record = function(zoom) {
let now = Date.now();
constructor() {
this.changeTimes = new Float64Array(256);
this.changeOpacities = new Uint8Array(256);
this.opacities = new Uint8ClampedArray(256);
this.array = new Uint8Array(this.opacities.buffer);

if (this.firstFrame) {
now = 0;
this.firstFrame = false;
this.fadeDuration = 300;
this.previousZoom = 0;
this.firstFrame = true;
}

zoom = Math.floor(zoom * 10);
record(zoom) {
let now = Date.now();

let z;
if (zoom < this.previousZoom) {
for (z = zoom + 1; z <= this.previousZoom; z++) {
this.changeTimes[z] = now;
this.changeOpacities[z] = this.opacities[z];
if (this.firstFrame) {
now = 0;
this.firstFrame = false;
}
} else {
for (z = zoom; z > this.previousZoom; z--) {
this.changeTimes[z] = now;
this.changeOpacities[z] = this.opacities[z];
}
}

for (z = 0; z < 256; z++) {
const timeSince = now - this.changeTimes[z];
const opacityChange = timeSince / this.fadeDuration * 255;
if (z <= zoom) {
this.opacities[z] = this.changeOpacities[z] + opacityChange;
zoom = Math.floor(zoom * 10);

let z;
if (zoom < this.previousZoom) {
for (z = zoom + 1; z <= this.previousZoom; z++) {
this.changeTimes[z] = now;
this.changeOpacities[z] = this.opacities[z];
}
} else {
this.opacities[z] = this.changeOpacities[z] - opacityChange;
for (z = zoom; z > this.previousZoom; z--) {
this.changeTimes[z] = now;
this.changeOpacities[z] = this.opacities[z];
}
}
}

this.changed = true;
this.previousZoom = zoom;
};
for (z = 0; z < 256; z++) {
const timeSince = now - this.changeTimes[z];
const opacityChange = timeSince / this.fadeDuration * 255;
if (z <= zoom) {
this.opacities[z] = this.changeOpacities[z] + opacityChange;
} else {
this.opacities[z] = this.changeOpacities[z] - opacityChange;
}
}

this.changed = true;
this.previousZoom = zoom;
}

FrameHistory.prototype.bind = function(gl) {
if (!this.texture) {
this.texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, this.texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.ALPHA, 256, 1, 0, gl.ALPHA, gl.UNSIGNED_BYTE, this.array);
bind(gl) {
if (!this.texture) {
this.texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, this.texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.ALPHA, 256, 1, 0, gl.ALPHA, gl.UNSIGNED_BYTE, this.array);

} else {
gl.bindTexture(gl.TEXTURE_2D, this.texture);
if (this.changed) {
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 256, 1, gl.ALPHA, gl.UNSIGNED_BYTE, this.array);
this.changed = false;
} else {
gl.bindTexture(gl.TEXTURE_2D, this.texture);
if (this.changed) {
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 256, 1, gl.ALPHA, gl.UNSIGNED_BYTE, this.array);
this.changed = false;
}
}
}
};
}

module.exports = FrameHistory;
214 changes: 108 additions & 106 deletions js/render/line_atlas.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

const util = require('../util/util');

module.exports = LineAtlas;

/**
* A LineAtlas lets us reuse rendered dashed lines
* by writing many of them to a texture and then fetching their positions
Expand All @@ -13,133 +11,137 @@ module.exports = LineAtlas;
* @param {number} height
* @private
*/
function LineAtlas(width, height) {
this.width = width;
this.height = height;
this.nextRow = 0;
class LineAtlas {
constructor(width, height) {
this.width = width;
this.height = height;
this.nextRow = 0;

this.bytes = 4;
this.data = new Uint8Array(this.width * this.height * this.bytes);

this.positions = {};
}
this.bytes = 4;
this.data = new Uint8Array(this.width * this.height * this.bytes);

LineAtlas.prototype.setSprite = function(sprite) {
this.sprite = sprite;
};
this.positions = {};
}

/**
* Get or create a dash line pattern.
*
* @param {Array<number>} dasharray
* @param {boolean} round whether to add circle caps in between dash segments
* @returns {Object} position of dash texture in { y, height, width }
* @private
*/
LineAtlas.prototype.getDash = function(dasharray, round) {
const key = dasharray.join(",") + round;
setSprite(sprite) {
this.sprite = sprite;
}

if (!this.positions[key]) {
this.positions[key] = this.addDash(dasharray, round);
/**
* Get or create a dash line pattern.
*
* @param {Array<number>} dasharray
* @param {boolean} round whether to add circle caps in between dash segments
* @returns {Object} position of dash texture in { y, height, width }
* @private
*/
getDash(dasharray, round) {
const key = dasharray.join(",") + round;

if (!this.positions[key]) {
this.positions[key] = this.addDash(dasharray, round);
}
return this.positions[key];
}
return this.positions[key];
};

LineAtlas.prototype.addDash = function(dasharray, round) {
addDash(dasharray, round) {

const n = round ? 7 : 0;
const height = 2 * n + 1;
const offset = 128;
const n = round ? 7 : 0;
const height = 2 * n + 1;
const offset = 128;

if (this.nextRow + height > this.height) {
util.warnOnce('LineAtlas out of space');
return null;
}
if (this.nextRow + height > this.height) {
util.warnOnce('LineAtlas out of space');
return null;
}

let length = 0;
for (let i = 0; i < dasharray.length; i++) {
length += dasharray[i];
}
let length = 0;
for (let i = 0; i < dasharray.length; i++) {
length += dasharray[i];
}

const stretch = this.width / length;
const halfWidth = stretch / 2;
const stretch = this.width / length;
const halfWidth = stretch / 2;

// If dasharray has an odd length, both the first and last parts
// are dashes and should be joined seamlessly.
const oddLength = dasharray.length % 2 === 1;
// If dasharray has an odd length, both the first and last parts
// are dashes and should be joined seamlessly.
const oddLength = dasharray.length % 2 === 1;

for (let y = -n; y <= n; y++) {
const row = this.nextRow + n + y;
const index = this.width * row;
for (let y = -n; y <= n; y++) {
const row = this.nextRow + n + y;
const index = this.width * row;

let left = oddLength ? -dasharray[dasharray.length - 1] : 0;
let right = dasharray[0];
let partIndex = 1;
let left = oddLength ? -dasharray[dasharray.length - 1] : 0;
let right = dasharray[0];
let partIndex = 1;

for (let x = 0; x < this.width; x++) {
for (let x = 0; x < this.width; x++) {

while (right < x / stretch) {
left = right;
right = right + dasharray[partIndex];
while (right < x / stretch) {
left = right;
right = right + dasharray[partIndex];

if (oddLength && partIndex === dasharray.length - 1) {
right += dasharray[0];
}
if (oddLength && partIndex === dasharray.length - 1) {
right += dasharray[0];
}

partIndex++;
}
partIndex++;
}

const distLeft = Math.abs(x - left * stretch);
const distRight = Math.abs(x - right * stretch);
const dist = Math.min(distLeft, distRight);
const inside = (partIndex % 2) === 1;
let signedDistance;

if (round) {
// Add circle caps
const distMiddle = n ? y / n * (halfWidth + 1) : 0;
if (inside) {
const distEdge = halfWidth - Math.abs(distMiddle);
signedDistance = Math.sqrt(dist * dist + distEdge * distEdge);
const distLeft = Math.abs(x - left * stretch);
const distRight = Math.abs(x - right * stretch);
const dist = Math.min(distLeft, distRight);
const inside = (partIndex % 2) === 1;
let signedDistance;

if (round) {
// Add circle caps
const distMiddle = n ? y / n * (halfWidth + 1) : 0;
if (inside) {
const distEdge = halfWidth - Math.abs(distMiddle);
signedDistance = Math.sqrt(dist * dist + distEdge * distEdge);
} else {
signedDistance = halfWidth - Math.sqrt(dist * dist + distMiddle * distMiddle);
}
} else {
signedDistance = halfWidth - Math.sqrt(dist * dist + distMiddle * distMiddle);
signedDistance = (inside ? 1 : -1) * dist;
}
} else {
signedDistance = (inside ? 1 : -1) * dist;
}

this.data[3 + (index + x) * 4] = Math.max(0, Math.min(255, signedDistance + offset));
this.data[3 + (index + x) * 4] = Math.max(0, Math.min(255, signedDistance + offset));
}
}

const pos = {
y: (this.nextRow + n + 0.5) / this.height,
height: 2 * n / this.height,
width: length
};

this.nextRow += height;
this.dirty = true;

return pos;
}

const pos = {
y: (this.nextRow + n + 0.5) / this.height,
height: 2 * n / this.height,
width: length
};

this.nextRow += height;
this.dirty = true;

return pos;
};

LineAtlas.prototype.bind = function(gl) {
if (!this.texture) {
this.texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, this.texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, this.data);

} else {
gl.bindTexture(gl.TEXTURE_2D, this.texture);

if (this.dirty) {
this.dirty = false;
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, this.width, this.height, gl.RGBA, gl.UNSIGNED_BYTE, this.data);
bind(gl) {
if (!this.texture) {
this.texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, this.texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, this.data);

} else {
gl.bindTexture(gl.TEXTURE_2D, this.texture);

if (this.dirty) {
this.dirty = false;
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, this.width, this.height, gl.RGBA, gl.UNSIGNED_BYTE, this.data);
}
}
}
};
}

module.exports = LineAtlas;
Loading

0 comments on commit 1d712b7

Please sign in to comment.