diff --git a/data/core.yaml b/data/core.yaml index 7e19e72a6..66b72849e 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -810,14 +810,18 @@ en: portage_ave: Portage Avenue welcome: title: "Welcome" + welcome: "Welcome! This walkthrough will teach you the basics of editing on OpenStreetMap." + chapters: "You can use the buttons below to skip chapters at any time, or restart a chapter if you get stuck. Let's begin!" navigation: title: "Navigation" drag: "The main map area shows OpenStreetMap data on top of a background. You can navigate by dragging and scrolling, just like any web map. **Drag the map!**" select: "Map features are represented three ways: using points, lines or areas. All features can be selected by clicking on them. **Click on the point to select it.**" + selected: "Great! The point is now selected. Selected items are drawn with a pulsing glow." pane: "When a feature is selected, the feature editor is displayed. The header shows us the feature type and the main pane shows the feature's attributes, such as its name and address. **Close the feature editor by pressing the {button} button in the top right.**" search: "You can also search for features in the current view, or worldwide. **Search for '{name}'**" choose: "**Choose {name} from the list to select it.**" - chosen: "Great! {name} is now selected. **Close the feature editor by pressing the {button} button.**" + chosen: "Great! {name} is now selected. See how the fields displayed for a street are different than the fields displayed for the town hall. **Close the feature editor by pressing the {button} button.**" + play: "Try moving the map and clicking on some other features. **When you are ready to continue to the next chapter, click '{chapter}'.**" points: title: "Points" add: "Points can be used to represent features such as shops, restaurants, and monuments. They mark a specific location, and describe what's there. **Click the {button} Point button to add a new point.**" diff --git a/dist/locales/en.json b/dist/locales/en.json index 645803768..94069ea3d 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -667,16 +667,20 @@ "portage_ave": "Portage Avenue" }, "welcome": { - "title": "Welcome" + "title": "Welcome", + "welcome": "Welcome! This walkthrough will teach you the basics of editing on OpenStreetMap.", + "chapters": "You can use the buttons below to skip chapters at any time, or restart a chapter if you get stuck. Let's begin!" }, "navigation": { "title": "Navigation", "drag": "The main map area shows OpenStreetMap data on top of a background. You can navigate by dragging and scrolling, just like any web map. **Drag the map!**", "select": "Map features are represented three ways: using points, lines or areas. All features can be selected by clicking on them. **Click on the point to select it.**", + "selected": "Great! The point is now selected. Selected items are drawn with a pulsing glow.", "pane": "When a feature is selected, the feature editor is displayed. The header shows us the feature type and the main pane shows the feature's attributes, such as its name and address. **Close the feature editor by pressing the {button} button in the top right.**", "search": "You can also search for features in the current view, or worldwide. **Search for '{name}'**", "choose": "**Choose {name} from the list to select it.**", - "chosen": "Great! {name} is now selected. **Close the feature editor by pressing the {button} button.**" + "chosen": "Great! {name} is now selected. See how the fields displayed for a street are different than the fields displayed for the town hall. **Close the feature editor by pressing the {button} button.**", + "play": "Try moving the map and clicking on some other features. **When you are ready to continue to the next chapter, click '{chapter}'.**" }, "points": { "title": "Points", diff --git a/modules/ui/curtain.js b/modules/ui/curtain.js index cf29f5eb5..52e6ccbdc 100644 --- a/modules/ui/curtain.js +++ b/modules/ui/curtain.js @@ -168,7 +168,9 @@ export function uiCurtain() { .style('top', shiftY + 'px'); } else { - tooltip.call(uiToggle(false)); + tooltip + .classed('in', false) + .call(uiToggle(false)); } return tooltip; diff --git a/modules/ui/intro/intro.js b/modules/ui/intro/intro.js index b7b5b2750..77344e3bf 100644 --- a/modules/ui/intro/intro.js +++ b/modules/ui/intro/intro.js @@ -84,7 +84,7 @@ export function uiIntro(context) { buttons.filter(function(d) { return d.title === s.title; }).classed('finished', true); - enterChapter(chapters[i + 1]); + // enterChapter(chapters[i + 1]); }); return s; }); @@ -121,7 +121,7 @@ export function uiIntro(context) { .data(chapters) .enter() .append('button') - .attr('class', 'chapter') + .attr('class', function(d, i) { return 'chapter chapter-' + chapterFlow[i]; }) .on('click', enterChapter); buttons diff --git a/modules/ui/intro/navigation.js b/modules/ui/intro/navigation.js index 92bcec9eb..0aecfa7bf 100644 --- a/modules/ui/intro/navigation.js +++ b/modules/ui/intro/navigation.js @@ -6,6 +6,7 @@ import { icon, pointBox } from './helper'; export function uiIntroNavigation(context, reveal) { var dispatch = d3.dispatch('done'), + hallId = 'n2140018997', timeouts = []; @@ -25,6 +26,12 @@ export function uiIntroNavigation(context, reveal) { } + function isTownHallSelected() { + var ids = context.selectedIDs(); + return ids.length === 1 && ids[0] === hallId; + } + + function dragMap() { var dragged = false, rect = context.surfaceRect(), @@ -43,21 +50,29 @@ export function uiIntroNavigation(context, reveal) { }); d3.select(window).on('mouseup.intro', function() { - if (!dragged) return; - d3.select(window).on('mouseup.intro', null, true); - context.map().on('move.intro', null); - clickTownHall(); + if (dragged) advance(); }, true); + + function advance() { + context.map().on('move.intro', null); + d3.select(window).on('mouseup.intro', null, true); + clickTownHall(); + } } function clickTownHall() { - context.history().reset('initial'); // ensure townhall exists - var hall = context.entity('n2140018997'); + if (!context.hasEntity(hallId)) { + context.history().reset('initial'); + } - context.on('enter.intro', inspectTownHall); + var hall = context.entity(hallId); context.map().centerEase(hall.loc, 250); + context.on('enter.intro', function() { + if (isTownHallSelected()) advance(); + }); + timeout(function() { var box = pointBox(hall.loc, context); reveal(box, t('intro.navigation.select')); @@ -66,46 +81,85 @@ export function uiIntroNavigation(context, reveal) { reveal(box, t('intro.navigation.select'), { duration: 0 }); }); }, 260); + + function advance() { + context.on('enter.intro', null); + context.map().on('move.intro drawn.intro', null); + selectedTownHall(); + } + } + + + function selectedTownHall() { + if (!isTownHallSelected()) return clickTownHall(); + + var hall = context.entity('n2140018997'); + var box = pointBox(hall.loc, context); + + reveal(box, t('intro.navigation.selected')); + + context.map().on('move.intro drawn.intro', function() { + var box = pointBox(hall.loc, context); + reveal(box, t('intro.navigation.selected'), { duration: 0 }); + }); + + timeout(advance, 4000); + + function advance() { + context.map().on('move.intro drawn.intro', null); + inspectTownHall(); + } } function inspectTownHall(mode) { - if (mode.id !== 'select') return; + if (!isTownHallSelected()) return clickTownHall(); - context.on('enter.intro', null); - context.map().on('move.intro drawn.intro', null); - context.on('exit.intro', streetSearch); + context.on('exit.intro', advance); timeout(function() { reveal('.entity-editor-pane', t('intro.navigation.pane', { button: icon('#icon-close', 'pre-text') }) ); }, 700); + + function advance() { + context.on('exit.intro', null); + streetSearch(); + } } function streetSearch() { context.history().reset('initial'); // ensure spring street exists - context.on('exit.intro', null); + reveal('.search-header input', t('intro.navigation.search', { name: t('intro.graph.spring_st') })); + d3.select('.search-header input') - .on('keyup.intro', searchResult); + .on('keyup.intro', checkSearchResult); } - function searchResult() { - var first = d3.select('.feature-list-item:nth-child(0n+2)'), // skip No Results item + function checkSearchResult() { + var first = d3.select('.feature-list-item:nth-child(0n+2)'), // skip "No Results" item firstName = first.select('.entity-name'), name = t('intro.graph.spring_st'); if (!firstName.empty() && firstName.text() === name) { reveal(first.node(), t('intro.navigation.choose', { name: name })); - context.on('exit.intro', selectedStreet); + + context.on('exit.intro', advance); + d3.select('.search-header input') .on('keydown.intro', eventCancel, true) .on('keyup.intro', null); } + + function advance() { + context.on('exit.intro', null); + selectedStreet(); + } } @@ -120,10 +174,26 @@ export function uiIntroNavigation(context, reveal) { button: icon('#icon-close', 'pre-text') }) ); - context.on('exit.intro', function() { - dispatch.call('done'); - }); + context.on('exit.intro', advance); }, 400); + + function advance() { + context.on('exit.intro', null); + play(); + } + } + + + function play() { + reveal('.intro-nav-wrap .chapter-point', + t('intro.navigation.play', { chapter: t('intro.points.title') }), { + buttonText: t('intro.ok'), + buttonCallback: function() { + dispatch.call('done'); + reveal('#id-container'); + } + } + ); } diff --git a/modules/ui/intro/welcome.js b/modules/ui/intro/welcome.js index f23acfcf1..a469493a6 100644 --- a/modules/ui/intro/welcome.js +++ b/modules/ui/intro/welcome.js @@ -15,14 +15,14 @@ export function uiIntroWelcome(context, reveal) { function welcome() { context.map().centerZoom([-85.63591, 41.94285], 19); reveal('.intro-nav-wrap', - 'Welcome! This walkthrough will teach you the basics of editing on OpenStreetMap.', - { buttonText: t('intro.ok'), buttonCallback: buttons } + t('intro.welcome.welcome'), + { buttonText: t('intro.ok'), buttonCallback: chapters } ); } - function buttons() { + function chapters() { reveal('.intro-nav-wrap', - 'You can use the buttons along bottom to skip sections or restart a section if you get stuck.', + t('intro.welcome.chapters'), { buttonText: t('intro.ok'), buttonCallback: function() { dispatch.call('done'); } } ); }