mirror of
https://github.com/skishore/makemeahanzi.git
synced 2025-11-01 03:45:51 +08:00
Clean up stage persistence API
This commit is contained in:
@ -14,6 +14,14 @@ const changeGlyph = (method, argument) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const constructStage = (type) => {
|
||||||
|
const glyph = Session.get('editor.glyph');
|
||||||
|
stage = new stages[type](glyph);
|
||||||
|
Session.set('editor.glyph', glyph);
|
||||||
|
stage._type = type;
|
||||||
|
stage.refresh(glyph);
|
||||||
|
}
|
||||||
|
|
||||||
this.getGlyph = (selector) => changeGlyph('getGlyph', selector);
|
this.getGlyph = (selector) => changeGlyph('getGlyph', selector);
|
||||||
|
|
||||||
const incrementStage = (amount) => {
|
const incrementStage = (amount) => {
|
||||||
@ -21,10 +29,7 @@ const incrementStage = (amount) => {
|
|||||||
if (index < 0) return;
|
if (index < 0) return;
|
||||||
const new_index = index + amount;
|
const new_index = index + amount;
|
||||||
if (new_index < 0 || new_index >= types.length) return;
|
if (new_index < 0 || new_index >= types.length) return;
|
||||||
const glyph = Session.get('editor.glyph');
|
constructStage(types[new_index]);
|
||||||
stage = new stages[types[new_index]](glyph);
|
|
||||||
stage._type = types[new_index];
|
|
||||||
stage.refresh(glyph);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialize = () => {
|
const initialize = () => {
|
||||||
@ -46,7 +51,9 @@ const bindings = {
|
|||||||
Template.editor.events({
|
Template.editor.events({
|
||||||
'click svg .selectable': function(event) {
|
'click svg .selectable': function(event) {
|
||||||
// We avoid the arrow function here so that this is bound to the template.
|
// We avoid the arrow function here so that this is bound to the template.
|
||||||
stage.handleEvent(Session.get('editor.glyph'), event, this);
|
const glyph = Session.get('editor.glyph');
|
||||||
|
stage.handleEvent(glyph, event, this);
|
||||||
|
Session.set('editor.glyph', glyph);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -69,8 +76,7 @@ Tracker.autorun(() => {
|
|||||||
if (!last_glyph || glyph.character !== last_glyph.character) {
|
if (!last_glyph || glyph.character !== last_glyph.character) {
|
||||||
let last_completed_stage = types[0];
|
let last_completed_stage = types[0];
|
||||||
types.map((x) => { if (glyph.stages[x]) last_completed_stage = x; });
|
types.map((x) => { if (glyph.stages[x]) last_completed_stage = x; });
|
||||||
stage = new stages[last_completed_stage](glyph);
|
constructStage(last_completed_stage);
|
||||||
stage._type = last_completed_stage;
|
|
||||||
}
|
}
|
||||||
stage.refresh(glyph);
|
stage.refresh(glyph);
|
||||||
last_glyph = glyph;
|
last_glyph = glyph;
|
||||||
|
|||||||
@ -2,10 +2,11 @@ if (this.stages !== undefined) throw new Error('Redifining stages global!');
|
|||||||
this.stages = {};
|
this.stages = {};
|
||||||
|
|
||||||
stages.AbstractStage = class AbstractStage {
|
stages.AbstractStage = class AbstractStage {
|
||||||
// Initialize this stage's internal state. The glyph may already include
|
// This method should fill in this stage's field in glyph.stages. The glyph
|
||||||
// output from this stage. If the internal state can be initialized in such
|
// may already have a value for this stage set. If so, this stage's internal
|
||||||
// a way to achieve that output, it should be; doing so allows users to make
|
// state should be initialized in such a way to achieve that output, if that
|
||||||
// some edits, switch to another glyph, and later resume where they left off.
|
// is possible; doing so allows users to make some edits, switch to another
|
||||||
|
// glyph, and then switch back and continue where they left off.
|
||||||
constructor(glyph) {
|
constructor(glyph) {
|
||||||
// Session variables the interface by which the stage interacts with UI:
|
// Session variables the interface by which the stage interacts with UI:
|
||||||
// - type - String type of this stage.
|
// - type - String type of this stage.
|
||||||
@ -27,8 +28,8 @@ stages.AbstractStage = class AbstractStage {
|
|||||||
this.colors = ['#0074D9', '#2ECC40', '#FFDC00', '#FF4136', '#7FDBFF',
|
this.colors = ['#0074D9', '#2ECC40', '#FFDC00', '#FF4136', '#7FDBFF',
|
||||||
'#001F3F', '#39CCCC', '#3D9970', '#01FF70', '#FF851B'];
|
'#001F3F', '#39CCCC', '#3D9970', '#01FF70', '#FF851B'];
|
||||||
}
|
}
|
||||||
// Update the stage's internal state and the editor.glyph Session variable
|
// Update the stage's internal state and possibly update this stage's field
|
||||||
// based on the event.
|
// in glyph.stages based on the event.
|
||||||
handleEvent(glyph, event, template) {
|
handleEvent(glyph, event, template) {
|
||||||
assert(false, 'handleEvent was not implemented!');
|
assert(false, 'handleEvent was not implemented!');
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,17 +17,16 @@ stages.bridges = class BridgesStage extends stages.AbstractStage {
|
|||||||
'Connect each pair of points on the glyph outline such that ' +
|
'Connect each pair of points on the glyph outline such that ' +
|
||||||
'the segment connecting those points is part of some stroke ' +
|
'the segment connecting those points is part of some stroke ' +
|
||||||
'outline. Click on a bridge to drop it.');
|
'outline. Click on a bridge to drop it.');
|
||||||
const bridges = stroke_extractor.getBridges(glyph);
|
const bridges = stroke_extractor.getBridges(glyph.stages.path);
|
||||||
this.bridges = bridges.bridges;
|
this.bridges = bridges.bridges;
|
||||||
this.endpoints = [];
|
this.endpoints = [];
|
||||||
bridges.endpoints.map(
|
bridges.endpoints.map(
|
||||||
(path) => this.endpoints = this.endpoints.concat(path));
|
(path) => this.endpoints = this.endpoints.concat(path));
|
||||||
this.selected_point = undefined;
|
this.selected_point = undefined;
|
||||||
glyph.stages.strokes = glyph.stages.strokes || this.bridges;
|
glyph.stages.bridges = glyph.stages.bridges || this.bridges;
|
||||||
}
|
}
|
||||||
handleClickOnBridge(glyph, bridge) {
|
handleClickOnBridge(glyph, bridge) {
|
||||||
glyph.stages.bridges = removeBridge(glyph.stages.bridges, bridge);
|
glyph.stages.bridges = removeBridge(glyph.stages.bridges, bridge);
|
||||||
Session.set('editor.glyph', glyph);
|
|
||||||
}
|
}
|
||||||
handleClickOnPoint(glyph, point) {
|
handleClickOnPoint(glyph, point) {
|
||||||
if (this.selected_point === undefined) {
|
if (this.selected_point === undefined) {
|
||||||
@ -47,7 +46,6 @@ stages.bridges = class BridgesStage extends stages.AbstractStage {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
glyph.stages.bridges.push(bridge);
|
glyph.stages.bridges.push(bridge);
|
||||||
Session.set('editor.glyph', glyph);
|
|
||||||
}
|
}
|
||||||
handleEvent(glyph, event, template) {
|
handleEvent(glyph, event, template) {
|
||||||
if (template.x1 !== undefined) {
|
if (template.x1 !== undefined) {
|
||||||
@ -87,7 +85,8 @@ stages.bridges = class BridgesStage extends stages.AbstractStage {
|
|||||||
stroke: color,
|
stroke: color,
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
const strokes = stroke_extractor.getStrokes(glyph);
|
const strokes = stroke_extractor.getStrokes(
|
||||||
|
glyph.stages.path, glyph.stages.bridges);
|
||||||
const n = strokes.strokes.length;
|
const n = strokes.strokes.length;
|
||||||
const message = `Extracted ${n} stroke${n == 1 ? '' : 's'}.`;
|
const message = `Extracted ${n} stroke${n == 1 ? '' : 's'}.`;
|
||||||
Session.set('stage.status', strokes.log.concat([{message: message}]));
|
Session.set('stage.status', strokes.log.concat([{message: message}]));
|
||||||
|
|||||||
@ -29,13 +29,15 @@ stages.strokes = class StrokesStage extends stages.AbstractStage {
|
|||||||
'The final number of paths must agree with the stroke count ' +
|
'The final number of paths must agree with the stroke count ' +
|
||||||
'in the character metadata.');
|
'in the character metadata.');
|
||||||
const include = this.include = {};
|
const include = this.include = {};
|
||||||
this.strokes = stroke_extractor.getStrokes(glyph).strokes;
|
this.strokes = stroke_extractor.getStrokes(
|
||||||
|
glyph.stages.path, glyph.stages.bridges).strokes;
|
||||||
this.strokes.map((stroke) => include[stroke] = true);
|
this.strokes.map((stroke) => include[stroke] = true);
|
||||||
if (glyph.stages.strokes && glyph.stages.strokes.length > 0 &&
|
if (glyph.stages.strokes && glyph.stages.strokes.length > 0 &&
|
||||||
glyph.stages.strokes.filter((x) => !include[x]).length === 0) {
|
glyph.stages.strokes.filter((x) => !include[x]).length === 0) {
|
||||||
this.strokes.map((stroke) => include[stroke] = false);
|
this.strokes.map((stroke) => include[stroke] = false);
|
||||||
glyph.stages.strokes.map((stroke) => include[stroke] = true);
|
glyph.stages.strokes.map((stroke) => include[stroke] = true);
|
||||||
}
|
}
|
||||||
|
glyph.stages.strokes = this.strokes.filter((x) => this.include[x]);
|
||||||
}
|
}
|
||||||
handleEvent(glyph, event, template) {
|
handleEvent(glyph, event, template) {
|
||||||
assert(this.include.hasOwnProperty(template.d));
|
assert(this.include.hasOwnProperty(template.d));
|
||||||
|
|||||||
@ -354,9 +354,8 @@ if (this.stroke_extractor !== undefined) {
|
|||||||
}
|
}
|
||||||
this.stroke_extractor = {};
|
this.stroke_extractor = {};
|
||||||
|
|
||||||
stroke_extractor.getBridges = (glyph, classifier) => {
|
stroke_extractor.getBridges = (path, classifier) => {
|
||||||
assert(glyph.stages.path)
|
const paths = svg.convertSVGPathToPaths(path);
|
||||||
const paths = svg.convertSVGPathToPaths(glyph.stages.path);
|
|
||||||
const endpoints = [];
|
const endpoints = [];
|
||||||
for (let i = 0; i < paths.length; i++) {
|
for (let i = 0; i < paths.length; i++) {
|
||||||
for (let j = 0; j < paths[i].length; j++) {
|
for (let j = 0; j < paths[i].length; j++) {
|
||||||
@ -368,10 +367,8 @@ stroke_extractor.getBridges = (glyph, classifier) => {
|
|||||||
return {endpoints: endpoints, bridges: bridges};
|
return {endpoints: endpoints, bridges: bridges};
|
||||||
}
|
}
|
||||||
|
|
||||||
stroke_extractor.getStrokes = (glyph) => {
|
stroke_extractor.getStrokes = (path, bridges) => {
|
||||||
assert(glyph.stages.path)
|
const paths = svg.convertSVGPathToPaths(path);
|
||||||
assert(glyph.stages.bridges)
|
|
||||||
const paths = svg.convertSVGPathToPaths(glyph.stages.path);
|
|
||||||
const endpoints = [];
|
const endpoints = [];
|
||||||
for (let i = 0; i < paths.length; i++) {
|
for (let i = 0; i < paths.length; i++) {
|
||||||
for (let j = 0; j < paths[i].length; j++) {
|
for (let j = 0; j < paths[i].length; j++) {
|
||||||
@ -379,8 +376,7 @@ stroke_extractor.getStrokes = (glyph) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const log = [];
|
const log = [];
|
||||||
const stroke_paths = extractStrokes(
|
const stroke_paths = extractStrokes(paths, endpoints, bridges, log);
|
||||||
paths, endpoints, glyph.stages.bridges, log);
|
|
||||||
const strokes = stroke_paths.map((x) => svg.convertPathsToSVGPath([x]));
|
const strokes = stroke_paths.map((x) => svg.convertPathsToSVGPath([x]));
|
||||||
return {log: log, strokes: strokes};
|
return {log: log, strokes: strokes};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user