Add square buildings steps to building chapter

This commit is contained in:
Bryan Housel
2017-04-03 16:33:40 -04:00
parent 0af9df708f
commit bb7b60cd23
3 changed files with 151 additions and 18 deletions
+2
View File
@@ -876,6 +876,7 @@ en:
close: "**Hit escape, or click the {button} button to close the feature editor**"
rightclick_building: "**Right-click to select the building you created.**"
square_building: "The house that you just added will look even better with perfectly square corners. **Click on the {button} button to square the building shape.**"
retry_square: "You didn't click the Square button. Try again."
done_square: "See how the corners of the building moved into place? Let's learn another useful trick."
add_tank: "Let's trace this circular storage tank. **Click the {button} Area button to add a new area.**"
start_tank: "Don't worry, you won't need to draw a perfect circle. Just draw an area inside the tank that touches its edge. **Click or press spacebar to place a starting node on the edge of the tank.**"
@@ -884,6 +885,7 @@ en:
choose_tank: "**Choose {name} from the list.**"
rightclick_tank: "**Right-click to select the storage tank you created.**"
circle_tank: "**Click on the {button} button to make the tank a circle.**"
retry_circle: "You didn't click the Circularize button. Try again."
play: "Great Job! Try tracing a few more buildings. **When you are ready to continue to the next chapter, click '{next}'.**"
startediting:
title: "Start Editing"
+2
View File
@@ -739,6 +739,7 @@
"close": "**Hit escape, or click the {button} button to close the feature editor**",
"rightclick_building": "**Right-click to select the building you created.**",
"square_building": "The house that you just added will look even better with perfectly square corners. **Click on the {button} button to square the building shape.**",
"retry_square": "You didn't click the Square button. Try again.",
"done_square": "See how the corners of the building moved into place? Let's learn another useful trick.",
"add_tank": "Let's trace this circular storage tank. **Click the {button} Area button to add a new area.**",
"start_tank": "Don't worry, you won't need to draw a perfect circle. Just draw an area inside the tank that touches its edge. **Click or press spacebar to place a starting node on the edge of the tank.**",
@@ -747,6 +748,7 @@
"choose_tank": "**Choose {name} from the list.**",
"rightclick_tank": "**Right-click to select the storage tank you created.**",
"circle_tank": "**Click on the {button} button to make the tank a circle.**",
"retry_circle": "You didn't click the Circularize button. Try again.",
"play": "Great Job! Try tracing a few more buildings. **When you are ready to continue to the next chapter, click '{next}'.**"
},
"startediting": {
+147 -18
View File
@@ -1,5 +1,6 @@
import * as d3 from 'd3';
import { t } from '../../util/locale';
import { modeBrowse } from '../../modes/browse';
import { utilRebind } from '../../util/rebind';
import { icon, pad } from './helper';
@@ -8,7 +9,9 @@ export function uiIntroBuilding(context, reveal) {
var dispatch = d3.dispatch('done'),
house = [-85.62815, 41.95638],
tank = [-85.62732, 41.95347],
timeouts = [];
timeouts = [],
houseId = null,
tankId = null;
var chapter = {
@@ -27,6 +30,13 @@ export function uiIntroBuilding(context, reveal) {
}
function revealBuilding(center, text, options) {
var padding = 160 * Math.pow(2, context.map().zoom() - 20);
var box = pad(center, padding, context);
reveal(box, text, options);
}
function addBuilding() {
var tooltip = reveal('button.add-area',
t('intro.buildings.add_building', { button: icon('#icon-area', 'pre-text') }));
@@ -57,14 +67,10 @@ export function uiIntroBuilding(context, reveal) {
context.map().zoomEase(20, 500);
timeout(function() {
var padding = 160 * Math.pow(2, context.map().zoom() - 20);
var box = pad(house, padding, context);
reveal(box, t('intro.buildings.start_building'));
revealBuilding(house, t('intro.buildings.start_building'));
context.map().on('move.intro drawn.intro', function() {
padding = 160 * Math.pow(2, context.map().zoom() - 20);
box = pad(house, padding, context);
reveal(box, t('intro.buildings.start_building'), { duration: 0 });
revealBuilding(house, t('intro.buildings.start_building'), { duration: 0 });
});
context.on('enter.intro', function(mode) {
@@ -72,7 +78,7 @@ export function uiIntroBuilding(context, reveal) {
continueTo(drawBuilding);
});
}, 520); // after easing
}, 550); // after easing
function continueTo(nextStep) {
context.map().on('move.intro drawn.intro', null);
@@ -87,14 +93,10 @@ export function uiIntroBuilding(context, reveal) {
return chapter.restart();
}
var padding = 160 * Math.pow(2, context.map().zoom() - 20);
var box = pad(house, padding, context);
reveal(box, t('intro.buildings.continue_building'));
revealBuilding(house, t('intro.buildings.continue_building'));
context.map().on('move.intro drawn.intro', function() {
padding = 160 * Math.pow(2, context.map().zoom() - 20);
box = pad(house, padding, context);
reveal(box, t('intro.buildings.continue_building'), {duration: 0});
revealBuilding(house, t('intro.buildings.continue_building'), { duration: 0 });
});
context.on('enter.intro', function(mode) {
@@ -151,10 +153,9 @@ export function uiIntroBuilding(context, reveal) {
var button = d3.select('.preset-building-house .preset-list-button');
if (button.empty()) return chapter.restart();
timeout(function() {
reveal(button.node(), t('intro.buildings.choose_house'));
button.on('click.intro', function() { continueTo(closeEditor); });
button.on('click.intro', function() { continueTo(closeEditorHouse); });
}, 500);
function continueTo(nextStep) {
@@ -165,13 +166,16 @@ export function uiIntroBuilding(context, reveal) {
}
function closeEditor() {
function closeEditorHouse() {
if (context.mode().id !== 'select') {
return chapter.restart();
}
houseId = context.mode().selectedIDs()[0];
context.history().checkpoint('hasHouse');
context.on('exit.intro', function() {
continueTo(play);
continueTo(rightClickHouse);
});
timeout(function() {
@@ -187,6 +191,129 @@ export function uiIntroBuilding(context, reveal) {
}
function rightClickHouse() {
if (!houseId) return chapter.restart();
context.enter(modeBrowse(context));
context.history().reset('hasHouse');
context.map().centerEase(house, 500);
timeout(function() {
if (context.map().zoom() < 20) {
context.map().zoomEase(20, 500);
}
}, 520);
context.on('enter.intro', function(mode) {
if (mode.id !== 'select') return;
var ids = context.selectedIDs();
if (ids.length !== 1 || ids[0] !== houseId) return;
timeout(function() {
var node = d3.select('.edit-menu-item-orthogonalize, .radial-menu-item-orthogonalize').node();
if (!node) return;
continueTo(clickSquare);
}, 300); // after menu visible
});
context.map().on('move.intro drawn.intro', function() {
revealBuilding(house, t('intro.buildings.rightclick_building'), { duration: 0 });
});
context.history().on('change.intro', function() {
continueTo(rightClickHouse);
});
function continueTo(nextStep) {
context.on('enter.intro', null);
context.map().on('move.intro drawn.intro', null);
context.history().on('change.intro', null);
nextStep();
}
}
function clickSquare() {
if (!houseId) return chapter.restart();
var entity = context.hasEntity(houseId);
if (!entity) return continueTo(rightClickHouse);
var node = d3.select('.edit-menu-item-orthogonalize, .radial-menu-item-orthogonalize').node();
if (!node) { return continueTo(rightClickHouse); }
var wasChanged = false;
revealBuilding(house,
t('intro.buildings.square_building', { button: icon('#operation-orthogonalize', 'pre-text') })
);
context.on('enter.intro', function(mode) {
if (mode.id === 'browse') {
continueTo(rightClickHouse);
} else if (mode.id === 'move' || mode.id === 'rotate') {
continueTo(retryClickSquare);
}
});
context.map().on('move.intro drawn.intro', function() {
var node = d3.select('.edit-menu-item-orthogonalize, .radial-menu-item-orthogonalize').node();
if (!wasChanged && !node) { return continueTo(rightClickHouse); }
revealBuilding(house,
t('intro.buildings.square_building', { button: icon('#operation-orthogonalize', 'pre-text') }),
{ duration: 0 }
);
});
context.history().on('change.intro', function() {
wasChanged = true;
context.history().on('change.intro', null);
// Something changed. Wait for transition to complete and check undo annotation.
timeout(function() {
if (context.history().undoAnnotation() === t('operations.orthogonalize.annotation.area')) {
continueTo(doneSquare);
} else {
continueTo(retryClickSquare);
}
}, 500); // after transitioned actions
});
function continueTo(nextStep) {
context.on('enter.intro', null);
context.map().on('move.intro drawn.intro', null);
context.history().on('change.intro', null);
nextStep();
}
}
function retryClickSquare() {
context.enter(modeBrowse(context));
revealBuilding(house, t('intro.buildings.retry_square'), {
buttonText: t('intro.ok'),
buttonCallback: function() { continueTo(rightClickHouse); }
});
function continueTo(nextStep) {
nextStep();
}
}
function doneSquare() {
revealBuilding(house, t('intro.buildings.done_square'), {
buttonText: t('intro.ok'),
buttonCallback: function() { continueTo(play); }
});
function continueTo(nextStep) {
nextStep();
}
}
function play() {
dispatch.call('done');
reveal('.intro-nav-wrap .chapter-startEditing',
@@ -199,6 +326,8 @@ export function uiIntroBuilding(context, reveal) {
chapter.enter = function() {
houseId = null;
tankId = null;
context.history().reset('initial');
context.map().zoom(19).centerEase(house, 500);
timeout(addBuilding, 520);