From 0bc56f94712346cea6b794df0a26163a47415d64 Mon Sep 17 00:00:00 2001 From: Quincy Morgan Date: Fri, 26 Jun 2020 15:48:57 -0400 Subject: [PATCH] Start touch support for walkthrough (re: #7692) --- data/core.yaml | 51 ++++++++++++++++++-------------- dist/locales/en.json | 53 +++++++++++++++++++--------------- modules/core/context.js | 1 + modules/ui/curtain.js | 13 +++++++-- modules/ui/init.js | 12 ++++++-- modules/ui/intro/area.js | 10 ++++--- modules/ui/intro/building.js | 40 +++++++------------------ modules/ui/intro/line.js | 40 +++++++------------------ modules/ui/intro/navigation.js | 17 +++++++---- modules/ui/intro/point.js | 37 +++++++----------------- 10 files changed, 131 insertions(+), 143 deletions(-) diff --git a/data/core.yaml b/data/core.yaml index 91c2feef5..043886df3 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -1927,12 +1927,15 @@ en: chapters: "You can use the buttons below to skip chapters at any time or to restart a chapter if you get stuck. Let's begin! **Press '{next}' to continue.**" navigation: title: "Navigation" - drag: "The main map area shows OpenStreetMap data on top of a background.{br}You can click-and-drag or tap-and-drag the map to move it around. You can also use the arrow keys on a keyboard. **Drag the map!**" - zoom: "You can zoom in or out by scrolling with a mouse wheel, pinching on a touchscreen, or pressing the {plus} / {minus} buttons. **Zoom the map!**" + drag: "The main map area shows OpenStreetMap data on top of a background.{br}You can click-and-drag the map with the left mouse button to move it around. You can also use the arrow keys on a keyboard. **Drag the map!**" + drag_touch: "The main map area shows OpenStreetMap data on top of a background.{br}You can tap-and-drag the map to move it around. You can also use the arrow keys on a keyboard. **Drag the map!**" + zoom: "You can zoom the map by scrolling with a mouse wheel or trackpad, or by pressing the {plus} / {minus} buttons. **Zoom the map!**" + zoom_touch: "You can zoom the map by pinching it with two fingers, double-tapping a location, or pressing the {plus} / {minus} buttons. **Zoom the map!**" features: "We use the word *features* to describe the things that appear on the map. Anything in the real world can be mapped as a feature on OpenStreetMap." points_lines_areas: "Map features are represented using *points, lines, or areas.*" nodes_ways: "In OpenStreetMap, points are sometimes called *nodes*, and lines and areas are sometimes called *ways*." - click_townhall: "All features on the map can be selected by clicking or tapping on them. **Select the point.**" + click_townhall: "All features on the map can be selected by clicking on them. **Click the point to select it.**" + tap_townhall: "All features on the map can be selected by tapping on them. **Tap the point to select it.**" selected_townhall: "Great! The point is now selected. Selected features are drawn with a pulsing glow." editor_townhall: "When a feature is selected, the *feature editor* is displayed alongside the map." preset_townhall: "The top part of the feature editor shows the feature's type. This point is a {preset}." @@ -1945,33 +1948,37 @@ en: play: "Try exploring the map and selecting some other features to see what kinds of things can be added to OpenStreetMap. **When you are ready to continue to the next chapter, press '{next}'.**" points: title: "Points" - add_point: "*Points* can be used to represent features such as shops, restaurants, and monuments.{br}They mark a specific location, and describe what's there. **Click the {button} Point button to add a new point.**" + add_point: "*Points* can be used to represent features such as shops, restaurants, and monuments.{br}They mark a specific location, and describe what's there. **Press the {button} Point button to add a new point.**" place_point: "To place the new point on the map, position your mouse cursor where the point should go, then left-click or press the spacebar. **Move the mouse pointer over this building, then left-click or press the spacebar.**" + place_point_touch: "To place the new point on the map, tap the location where it should go. **Tap the center of this building.**" search_cafe: "There are many different features that can be represented by points. The point you just added is a cafe. **Search for '{preset}'.**" choose_cafe: "**Choose {preset} from the list.**" feature_editor: "The point is now marked as a cafe. Using the feature editor, we can add more information about the cafe." add_name: "In OpenStreetMap, all of the fields are optional, and it's OK to leave a field blank if you are unsure.{br}Let's pretend that you have local knowledge of this cafe, and you know its name. **Add a name for the cafe.**" - add_close: "The feature editor will remember all of your changes automatically. **When you are finished adding the name, hit escape, enter, or click the {button} button to close the feature editor.**" - reselect: "Often points will already exist, but have mistakes or be incomplete. We can edit existing points. **Click to select the cafe you just created.**" + add_close: "The feature editor will remember all of your changes automatically. **When you are finished adding the name, hit escape, enter, or press the {button} button to close the feature editor.**" + reselect: "Often points will already exist, but have mistakes or be incomplete. We can edit existing points. **Select the cafe you just created.**" update: "Let's fill in some more details for this cafe. You can change its name, add a cuisine, or add an address. **Change the cafe details.**" - update_close: "**When you are finished updating the cafe, hit escape, enter, or click the {button} button to close the feature editor.**" - rightclick: "You can right-click on any feature to see the *edit menu*, which shows a list of editing operations that can be performed. **Right-click to select the point you created and show the edit menu.**" - delete: "It's OK to delete features that don't exist in the real world.{br}Deleting a feature from OpenStreetMap removes it from the map that everyone uses, so you should make sure a feature is really gone before you delete it. **Click on the {button} button to delete the point.**" - undo: "You can always undo any changes up until you save your edits to OpenStreetMap. **Click on the {button} button to undo the delete and get the point back.**" - play: "Now that you know how to create and edit points, try creating a few more points for practice! **When you are ready to continue to the next chapter, click '{next}'.**" + update_close: "**When you are finished updating the cafe, hit escape, enter, or press the {button} button to close the feature editor.**" + rightclick: "You can right-click on any feature to see the *edit menu*, which shows a list of editing operations that can be performed.{br}A right-click might be the same as a control-click, or a two-finger tap on a trackpad. **Right-click to select the point you created and show the edit menu.**" + edit_menu_touch: "You can long-press on any feature to see the *edit menu*, which shows a list of editing operations that can be performed. **Press-and-hold the point you created to show the edit menu.**" + delete: "It's OK to delete features that don't exist in the real world.{br}Deleting a feature from OpenStreetMap removes it from the map that everyone uses, so you should make sure a feature is really gone before you delete it. **Press the {button} button to delete the point.**" + undo: "You can always undo any changes up until you save your edits to OpenStreetMap. **Press the {button} button to undo the delete and get the point back.**" + play: "Now that you know how to create and edit points, try creating a few more points for practice! **When you are ready to continue to the next chapter, press '{next}'.**" areas: title: "Areas" - add_playground: "*Areas* are used to show the boundaries of features like lakes, buildings, and residential areas.{br}They can also be used for more detailed mapping of many features you might normally map as points. **Click the {button} Area button to add a new area.**" + add_playground: "*Areas* are used to show the boundaries of features like lakes, buildings, and residential areas.{br}They can also be used for more detailed mapping of many features you might normally map as points. **Press the {button} Area button to add a new area.**" start_playground: "Let's add this playground to the map by drawing an area. Areas are drawn by placing *nodes* along the outer edge of the feature. **Click or press spacebar to place a starting node on one of the corners of the playground.**" + start_playground_touch: "Let's add this playground to the map by drawing an area. Areas are drawn by placing *nodes* along the outer edge of the feature. **Tap to place a starting node on one of the corners of the playground.**" continue_playground: "Continue drawing the area by placing more nodes along the playground's edge. It is OK to connect the area to the existing walking paths.{br}Tip: You can hold down the '{alt}' key to prevent nodes from connecting to other features. **Continue drawing an area for the playground.**" finish_playground: "Finish the area by pressing enter, or clicking again on either the first or last node. **Finish drawing an area for the playground.**" + finish_playground_touch: "Finish the area by tapping again on either the first or last node, or by pressing enter on a keyboard. **Finish drawing an area for the playground.**" search_playground: "**Search for '{preset}'.**" choose_playground: "**Choose {preset} from the list.**" add_field: "This playground doesn't have an official name, so we won't add anything in the Name field.{br}Instead let's add some additional details about the playground to the Description field. **Open the Add Field list.**" choose_field: "**Choose {field} from the list.**" retry_add_field: "You didn't select the {field} field. Let's try again." - describe_playground: "**Add a description, then click the {button} button to close the feature editor.**" - play: "Good job! Try drawing a few more areas, and see what other kinds of area features you can add to OpenStreetMap. **When you are ready to continue to the next chapter, click '{next}'.**" + describe_playground: "**Add a description, then press the {button} button to close the feature editor.**" + play: "Good job! Try drawing a few more areas, and see what other kinds of area features you can add to OpenStreetMap. **When you are ready to continue to the next chapter, press '{next}'.**" lines: title: "Lines" add_line: "*Lines* are used to represent features such as roads, railroads, and rivers. **Click the {button} Line button to add a new line.**" @@ -2000,10 +2007,10 @@ en: multi_rightclick: "Good! Both lines to delete are now selected. **Right-click on one of the lines to show the edit menu.**" multi_delete: "**Click on the {button} button to delete the extra lines.**" retry_delete: "You didn't click the Delete button. Try again." - play: "Great! Use the skills that you've learned in this chapter to practice editing some more lines. **When you are ready to continue to the next chapter, click '{next}'.**" + play: "Great! Use the skills that you've learned in this chapter to practice editing some more lines. **When you are ready to continue to the next chapter, press '{next}'.**" buildings: title: "Buildings" - add_building: "OpenStreetMap is the world's largest database of buildings.{br}You can help improve this database by tracing buildings that aren't already mapped. **Click the {button} Area button to add a new area.**" + add_building: "OpenStreetMap is the world's largest database of buildings.{br}You can help improve this database by tracing buildings that aren't already mapped. **Press the {button} Area button to add a new area.**" start_building: "Let's add this house to the map by tracing its outline.{br}Buildings should be traced around their footprint as accurately as possible. **Click or press spacebar to place a starting node on one of the corners of the building.**" continue_building: "Continue adding more nodes to trace the outline of the building. Remember that you can zoom in if you want to add more details.{br}Finish the building by pressing enter, or clicking again on either the first or last node. **Finish tracing the building.**" retry_building: "It looks like you had some trouble placing the nodes at the building corners. Try again!" @@ -2011,21 +2018,21 @@ en: choose_preset_house: "There are many different types of buildings, but this one is clearly a house.{br}If you're not sure of the type, it's OK to just choose the generic Building type. **Choose the {preset} type.**" close: "**Hit escape or click the {button} button to close the feature editor.**" rightclick_building: "**Right-click to select the building you created and show the edit menu.**" - 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." + square_building: "The house that you just added will look even better with perfectly square corners. **Press the {button} button to square the building shape.**" + retry_square: "You didn't press 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: "Next we'll trace this circular storage tank. **Click the {button} Area button to add a new area.**" + add_tank: "Next we'll trace this circular storage tank. **Press 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.**" continue_tank: "Add a few more nodes around the edge. The circle will be created outside the nodes that you draw.{br}Finish the area by pressing enter, or clicking again on either the first or last node. **Finish tracing the tank.**" search_tank: "**Search for '{preset}'.**" choose_tank: "**Choose {preset} from the list.**" rightclick_tank: "**Right-click to select the storage tank you created and show the edit menu.**" - circle_tank: "**Click on the {button} button to make the tank a circle.**" + circle_tank: "**Press the {button} button to make the tank a circle.**" retry_circle: "You didn't click the Circularize button. Try again." - play: "Great Job! Practice tracing a few more buildings, and try some of the other commands on the edit menu. **When you are ready to continue to the next chapter, click '{next}'.**" + play: "Great Job! Practice tracing a few more buildings, and try some of the other commands on the edit menu. **When you are ready to continue to the next chapter, press '{next}'.**" startediting: title: "Start Editing" - help: "You're now ready to edit OpenStreetMap!{br}You can replay this walkthrough anytime or view more documentation by clicking the {button} Help button or pressing the '{key}' key." + help: "You're now ready to edit OpenStreetMap!{br}You can replay this walkthrough anytime or view more documentation by pressing the {button} Help button or the '{key}' key." shortcuts: "You can view a list of commands along with their keyboard shortcuts by pressing the '{key}' key." save: "Don't forget to regularly save your changes!" start: "Start mapping!" diff --git a/dist/locales/en.json b/dist/locales/en.json index beb4978ca..4bcce1875 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -2402,12 +2402,15 @@ }, "navigation": { "title": "Navigation", - "drag": "The main map area shows OpenStreetMap data on top of a background.{br}You can click-and-drag or tap-and-drag the map to move it around. You can also use the arrow keys on a keyboard. **Drag the map!**", - "zoom": "You can zoom in or out by scrolling with a mouse wheel, pinching on a touchscreen, or pressing the {plus} / {minus} buttons. **Zoom the map!**", + "drag": "The main map area shows OpenStreetMap data on top of a background.{br}You can click-and-drag the map with the left mouse button to move it around. You can also use the arrow keys on a keyboard. **Drag the map!**", + "drag_touch": "The main map area shows OpenStreetMap data on top of a background.{br}You can tap-and-drag the map to move it around. You can also use the arrow keys on a keyboard. **Drag the map!**", + "zoom": "You can zoom the map by scrolling with a mouse wheel or trackpad, or by pressing the {plus} / {minus} buttons. **Zoom the map!**", + "zoom_touch": "You can zoom the map by pinching it with two fingers, double-tapping a location, or pressing the {plus} / {minus} buttons. **Zoom the map!**", "features": "We use the word *features* to describe the things that appear on the map. Anything in the real world can be mapped as a feature on OpenStreetMap.", "points_lines_areas": "Map features are represented using *points, lines, or areas.*", "nodes_ways": "In OpenStreetMap, points are sometimes called *nodes*, and lines and areas are sometimes called *ways*.", - "click_townhall": "All features on the map can be selected by clicking or tapping on them. **Select the point.**", + "click_townhall": "All features on the map can be selected by clicking on them. **Click the point to select it.**", + "tap_townhall": "All features on the map can be selected by tapping on them. **Tap the point to select it.**", "selected_townhall": "Great! The point is now selected. Selected features are drawn with a pulsing glow.", "editor_townhall": "When a feature is selected, the *feature editor* is displayed alongside the map.", "preset_townhall": "The top part of the feature editor shows the feature's type. This point is a {preset}.", @@ -2421,34 +2424,38 @@ }, "points": { "title": "Points", - "add_point": "*Points* can be used to represent features such as shops, restaurants, and monuments.{br}They mark a specific location, and describe what's there. **Click the {button} Point button to add a new point.**", + "add_point": "*Points* can be used to represent features such as shops, restaurants, and monuments.{br}They mark a specific location, and describe what's there. **Press the {button} Point button to add a new point.**", "place_point": "To place the new point on the map, position your mouse cursor where the point should go, then left-click or press the spacebar. **Move the mouse pointer over this building, then left-click or press the spacebar.**", + "place_point_touch": "To place the new point on the map, tap the location where it should go. **Tap the center of this building.**", "search_cafe": "There are many different features that can be represented by points. The point you just added is a cafe. **Search for '{preset}'.**", "choose_cafe": "**Choose {preset} from the list.**", "feature_editor": "The point is now marked as a cafe. Using the feature editor, we can add more information about the cafe.", "add_name": "In OpenStreetMap, all of the fields are optional, and it's OK to leave a field blank if you are unsure.{br}Let's pretend that you have local knowledge of this cafe, and you know its name. **Add a name for the cafe.**", - "add_close": "The feature editor will remember all of your changes automatically. **When you are finished adding the name, hit escape, enter, or click the {button} button to close the feature editor.**", - "reselect": "Often points will already exist, but have mistakes or be incomplete. We can edit existing points. **Click to select the cafe you just created.**", + "add_close": "The feature editor will remember all of your changes automatically. **When you are finished adding the name, hit escape, enter, or press the {button} button to close the feature editor.**", + "reselect": "Often points will already exist, but have mistakes or be incomplete. We can edit existing points. **Select the cafe you just created.**", "update": "Let's fill in some more details for this cafe. You can change its name, add a cuisine, or add an address. **Change the cafe details.**", - "update_close": "**When you are finished updating the cafe, hit escape, enter, or click the {button} button to close the feature editor.**", - "rightclick": "You can right-click on any feature to see the *edit menu*, which shows a list of editing operations that can be performed. **Right-click to select the point you created and show the edit menu.**", - "delete": "It's OK to delete features that don't exist in the real world.{br}Deleting a feature from OpenStreetMap removes it from the map that everyone uses, so you should make sure a feature is really gone before you delete it. **Click on the {button} button to delete the point.**", - "undo": "You can always undo any changes up until you save your edits to OpenStreetMap. **Click on the {button} button to undo the delete and get the point back.**", - "play": "Now that you know how to create and edit points, try creating a few more points for practice! **When you are ready to continue to the next chapter, click '{next}'.**" + "update_close": "**When you are finished updating the cafe, hit escape, enter, or press the {button} button to close the feature editor.**", + "rightclick": "You can right-click on any feature to see the *edit menu*, which shows a list of editing operations that can be performed.{br}A right-click might be the same as a control-click, or a two-finger tap on a trackpad. **Right-click to select the point you created and show the edit menu.**", + "edit_menu_touch": "You can long-press on any feature to see the *edit menu*, which shows a list of editing operations that can be performed. **Press-and-hold the point you created to show the edit menu.**", + "delete": "It's OK to delete features that don't exist in the real world.{br}Deleting a feature from OpenStreetMap removes it from the map that everyone uses, so you should make sure a feature is really gone before you delete it. **Press the {button} button to delete the point.**", + "undo": "You can always undo any changes up until you save your edits to OpenStreetMap. **Press the {button} button to undo the delete and get the point back.**", + "play": "Now that you know how to create and edit points, try creating a few more points for practice! **When you are ready to continue to the next chapter, press '{next}'.**" }, "areas": { "title": "Areas", - "add_playground": "*Areas* are used to show the boundaries of features like lakes, buildings, and residential areas.{br}They can also be used for more detailed mapping of many features you might normally map as points. **Click the {button} Area button to add a new area.**", + "add_playground": "*Areas* are used to show the boundaries of features like lakes, buildings, and residential areas.{br}They can also be used for more detailed mapping of many features you might normally map as points. **Press the {button} Area button to add a new area.**", "start_playground": "Let's add this playground to the map by drawing an area. Areas are drawn by placing *nodes* along the outer edge of the feature. **Click or press spacebar to place a starting node on one of the corners of the playground.**", + "start_playground_touch": "Let's add this playground to the map by drawing an area. Areas are drawn by placing *nodes* along the outer edge of the feature. **Tap to place a starting node on one of the corners of the playground.**", "continue_playground": "Continue drawing the area by placing more nodes along the playground's edge. It is OK to connect the area to the existing walking paths.{br}Tip: You can hold down the '{alt}' key to prevent nodes from connecting to other features. **Continue drawing an area for the playground.**", "finish_playground": "Finish the area by pressing enter, or clicking again on either the first or last node. **Finish drawing an area for the playground.**", + "finish_playground_touch": "Finish the area by tapping again on either the first or last node, or by pressing enter on a keyboard. **Finish drawing an area for the playground.**", "search_playground": "**Search for '{preset}'.**", "choose_playground": "**Choose {preset} from the list.**", "add_field": "This playground doesn't have an official name, so we won't add anything in the Name field.{br}Instead let's add some additional details about the playground to the Description field. **Open the Add Field list.**", "choose_field": "**Choose {field} from the list.**", "retry_add_field": "You didn't select the {field} field. Let's try again.", - "describe_playground": "**Add a description, then click the {button} button to close the feature editor.**", - "play": "Good job! Try drawing a few more areas, and see what other kinds of area features you can add to OpenStreetMap. **When you are ready to continue to the next chapter, click '{next}'.**" + "describe_playground": "**Add a description, then press the {button} button to close the feature editor.**", + "play": "Good job! Try drawing a few more areas, and see what other kinds of area features you can add to OpenStreetMap. **When you are ready to continue to the next chapter, press '{next}'.**" }, "lines": { "title": "Lines", @@ -2478,11 +2485,11 @@ "multi_rightclick": "Good! Both lines to delete are now selected. **Right-click on one of the lines to show the edit menu.**", "multi_delete": "**Click on the {button} button to delete the extra lines.**", "retry_delete": "You didn't click the Delete button. Try again.", - "play": "Great! Use the skills that you've learned in this chapter to practice editing some more lines. **When you are ready to continue to the next chapter, click '{next}'.**" + "play": "Great! Use the skills that you've learned in this chapter to practice editing some more lines. **When you are ready to continue to the next chapter, press '{next}'.**" }, "buildings": { "title": "Buildings", - "add_building": "OpenStreetMap is the world's largest database of buildings.{br}You can help improve this database by tracing buildings that aren't already mapped. **Click the {button} Area button to add a new area.**", + "add_building": "OpenStreetMap is the world's largest database of buildings.{br}You can help improve this database by tracing buildings that aren't already mapped. **Press the {button} Area button to add a new area.**", "start_building": "Let's add this house to the map by tracing its outline.{br}Buildings should be traced around their footprint as accurately as possible. **Click or press spacebar to place a starting node on one of the corners of the building.**", "continue_building": "Continue adding more nodes to trace the outline of the building. Remember that you can zoom in if you want to add more details.{br}Finish the building by pressing enter, or clicking again on either the first or last node. **Finish tracing the building.**", "retry_building": "It looks like you had some trouble placing the nodes at the building corners. Try again!", @@ -2490,22 +2497,22 @@ "choose_preset_house": "There are many different types of buildings, but this one is clearly a house.{br}If you're not sure of the type, it's OK to just choose the generic Building type. **Choose the {preset} type.**", "close": "**Hit escape or click the {button} button to close the feature editor.**", "rightclick_building": "**Right-click to select the building you created and show the edit menu.**", - "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.", + "square_building": "The house that you just added will look even better with perfectly square corners. **Press the {button} button to square the building shape.**", + "retry_square": "You didn't press 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": "Next we'll trace this circular storage tank. **Click the {button} Area button to add a new area.**", + "add_tank": "Next we'll trace this circular storage tank. **Press 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.**", "continue_tank": "Add a few more nodes around the edge. The circle will be created outside the nodes that you draw.{br}Finish the area by pressing enter, or clicking again on either the first or last node. **Finish tracing the tank.**", "search_tank": "**Search for '{preset}'.**", "choose_tank": "**Choose {preset} from the list.**", "rightclick_tank": "**Right-click to select the storage tank you created and show the edit menu.**", - "circle_tank": "**Click on the {button} button to make the tank a circle.**", + "circle_tank": "**Press the {button} button to make the tank a circle.**", "retry_circle": "You didn't click the Circularize button. Try again.", - "play": "Great Job! Practice tracing a few more buildings, and try some of the other commands on the edit menu. **When you are ready to continue to the next chapter, click '{next}'.**" + "play": "Great Job! Practice tracing a few more buildings, and try some of the other commands on the edit menu. **When you are ready to continue to the next chapter, press '{next}'.**" }, "startediting": { "title": "Start Editing", - "help": "You're now ready to edit OpenStreetMap!{br}You can replay this walkthrough anytime or view more documentation by clicking the {button} Help button or pressing the '{key}' key.", + "help": "You're now ready to edit OpenStreetMap!{br}You can replay this walkthrough anytime or view more documentation by pressing the {button} Help button or the '{key}' key.", "shortcuts": "You can view a list of commands along with their keyboard shortcuts by pressing the '{key}' key.", "save": "Don't forget to regularly save your changes!", "start": "Start mapping!" @@ -13012,4 +13019,4 @@ } } } -} +} \ No newline at end of file diff --git a/modules/core/context.js b/modules/core/context.js index 011960358..77e61ca33 100644 --- a/modules/core/context.js +++ b/modules/core/context.js @@ -80,6 +80,7 @@ export function coreContext() { /* User interface and keybinding */ let _ui; context.ui = () => _ui; + context.lastPointerType = () => _ui.lastPointerType(); let _keybinding = utilKeybinding('context'); context.keybinding = () => _keybinding; diff --git a/modules/ui/curtain.js b/modules/ui/curtain.js index 380aa4702..4e9fd3abe 100644 --- a/modules/ui/curtain.js +++ b/modules/ui/curtain.js @@ -64,9 +64,12 @@ export function uiCurtain(containerNode) { * @param {integer} [options.duration] transition time in milliseconds * @param {string} [options.buttonText] if set, create a button with this text label * @param {function} [options.buttonCallback] if set, the callback for the button + * @param {function} [options.padding] extra margin in px to put around bbox * @param {String|ClientRect} [options.tooltipBox] box for tooltip position, if different from box for the curtain */ curtain.reveal = function(box, text, options) { + options = options || {}; + if (typeof box === 'string') { box = d3_select(box).node(); } @@ -76,8 +79,14 @@ export function uiCurtain(containerNode) { box.top -= containerRect.top; box.left -= containerRect.left; } - - options = options || {}; + if (box && options.padding) { + box.top -= options.padding; + box.left -= options.padding; + box.bottom += options.padding; + box.right += options.padding; + box.height += options.padding * 2; + box.width += options.padding * 2; + } var tooltipBox; if (options.tooltipBox) { diff --git a/modules/ui/init.js b/modules/ui/init.js index b5b5f0dd3..797e779bb 100644 --- a/modules/ui/init.js +++ b/modules/ui/init.js @@ -52,6 +52,8 @@ export function uiInit(context) { var _initCounter = 0; var _needWidth = {}; + var _lastPointerType; + function render(container) { @@ -92,13 +94,15 @@ export function uiInit(context) { if ('PointerEvent' in window) { d3_select(window) .on('pointerdown.ui pointerup.ui', function() { - var pointerType = d3_event.pointerType || 'mouse'; - if (container.attr('pointer') !== pointerType) { + var pointerType = d3_event.pointerType || 'mouse'; + if (_lastPointerType !== pointerType) { + _lastPointerType = pointerType; container .attr('pointer', pointerType); } }, true); } else { + _lastPointerType = 'mouse'; container .attr('pointer', 'mouse'); } @@ -478,6 +482,10 @@ export function uiInit(context) { ui.ensureLoaded(); }; + ui.lastPointerType = function() { + return _lastPointerType; + }; + ui.flash = uiFlash(context); ui.sidebar = uiSidebar(context); diff --git a/modules/ui/intro/area.js b/modules/ui/intro/area.js index 53b4db2c5..78a69ef64 100644 --- a/modules/ui/intro/area.js +++ b/modules/ui/intro/area.js @@ -90,14 +90,15 @@ export function uiIntroArea(context, reveal) { context.map().zoomEase(19.5, 500); timeout(function() { + var textId = context.lastPointerType() === 'mouse' ? 'start_playground' : 'start_playground_touch'; revealPlayground(playground, - t('intro.areas.start_playground'), { duration: 250 } + t('intro.areas.' + textId), { duration: 250 } ); timeout(function() { context.map().on('move.intro drawn.intro', function() { revealPlayground(playground, - t('intro.areas.start_playground'), { duration: 0 } + t('intro.areas.' + textId), { duration: 0 } ); }); context.on('enter.intro', function(mode) { @@ -166,14 +167,15 @@ export function uiIntroArea(context, reveal) { } _areaID = null; + var textId = context.lastPointerType() === 'mouse' ? 'finish_playground' : 'finish_playground_touch'; revealPlayground(playground, - t('intro.areas.finish_playground'), { duration: 250 } + t('intro.areas.' + textId), { duration: 250 } ); timeout(function() { context.map().on('move.intro drawn.intro', function() { revealPlayground(playground, - t('intro.areas.finish_playground'), { duration: 0 } + t('intro.areas.' + textId), { duration: 0 } ); }); }, 250); // after reveal diff --git a/modules/ui/intro/building.js b/modules/ui/intro/building.js index 00f6a3ea8..7e35ee222 100644 --- a/modules/ui/intro/building.js +++ b/modules/ui/intro/building.js @@ -5,7 +5,7 @@ import { } from 'd3-selection'; import { presetManager } from '../../presets'; -import { t, localizer } from '../../core/localizer'; +import { t } from '../../core/localizer'; import { modeBrowse } from '../../modes/browse'; import { modeSelect } from '../../modes/select'; import { utilArrayUniq, utilRebind } from '../../util'; @@ -54,24 +54,6 @@ export function uiIntroBuilding(context, reveal) { } - function revealEditMenu(loc, text, options) { - var rect = context.surfaceRect(); - var point = context.curtainProjection(loc); - var pad = 40; - var width = 250 + (2 * pad); - var height = 350; - var startX = rect.left + point[0]; - var left = (localizer.textDirection() === 'rtl') ? (startX - width + pad) : (startX - pad); - var box = { - left: left, - top: point[1] + rect.top - 60, - width: width, - height: height - }; - reveal(box, text, options); - } - - function addHouse() { context.enter(modeBrowse(context)); context.history().reset('initial'); @@ -372,10 +354,10 @@ export function uiIntroBuilding(context, reveal) { if (!node) { return continueTo(rightClickHouse); } var wasChanged = false; - var menuCoords = context.map().mouseCoordinates(); - revealEditMenu(menuCoords, - t('intro.buildings.square_building', { button: icon('#iD-operation-orthogonalize', 'pre-text') }) + reveal('.edit-menu', + t('intro.buildings.square_building', { button: icon('#iD-operation-orthogonalize', 'pre-text') }), + { padding: 50 } ); context.on('enter.intro', function(mode) { @@ -390,9 +372,9 @@ export function uiIntroBuilding(context, reveal) { var node = selectMenuItem(context, 'orthogonalize').node(); if (!wasChanged && !node) { return continueTo(rightClickHouse); } - revealEditMenu(menuCoords, + reveal('.edit-menu', t('intro.buildings.square_building', { button: icon('#iD-operation-orthogonalize', 'pre-text') }), - { duration: 0 } + { duration: 0, padding: 50 } ); }); @@ -694,10 +676,10 @@ export function uiIntroBuilding(context, reveal) { if (!node) { return continueTo(rightClickTank); } var wasChanged = false; - var menuCoords = context.map().mouseCoordinates(); - revealEditMenu(menuCoords, - t('intro.buildings.circle_tank', { button: icon('#iD-operation-circularize', 'pre-text') }) + reveal('.edit-menu', + t('intro.buildings.circle_tank', { button: icon('#iD-operation-circularize', 'pre-text') }), + { padding: 50 } ); context.on('enter.intro', function(mode) { @@ -712,9 +694,9 @@ export function uiIntroBuilding(context, reveal) { var node = selectMenuItem(context, 'circularize').node(); if (!wasChanged && !node) { return continueTo(rightClickTank); } - revealEditMenu(menuCoords, + reveal('.edit-menu', t('intro.buildings.circle_tank', { button: icon('#iD-operation-circularize', 'pre-text') }), - { duration: 0 } + { duration: 0, padding: 50 } ); }); diff --git a/modules/ui/intro/line.js b/modules/ui/intro/line.js index 6e4440dcc..289ab266e 100644 --- a/modules/ui/intro/line.js +++ b/modules/ui/intro/line.js @@ -6,7 +6,7 @@ import { } from 'd3-selection'; import { presetManager } from '../../presets'; -import { t, localizer } from '../../core/localizer'; +import { t } from '../../core/localizer'; import { geoSphericalDistance } from '../../geo'; import { modeBrowse } from '../../modes/browse'; import { modeSelect } from '../../modes/select'; @@ -56,24 +56,6 @@ export function uiIntroLine(context, reveal) { } - function revealEditMenu(loc, text, options) { - var rect = context.surfaceRect(); - var point = context.curtainProjection(loc); - var pad = 40; - var width = 250 + (2 * pad); - var height = 350; - var startX = rect.left + point[0]; - var left = (localizer.textDirection() === 'rtl') ? (startX - width + pad) : (startX - pad); - var box = { - left: left, - top: point[1] + rect.top - 60, - width: width, - height: height - }; - reveal(box, text, options); - } - - function addLine() { context.enter(modeBrowse(context)); context.history().reset('initial'); @@ -707,20 +689,20 @@ export function uiIntroLine(context, reveal) { if (!node) { return continueTo(rightClickIntersection); } var wasChanged = false; - var menuCoords = context.map().mouseCoordinates(); _washingtonSegmentID = null; - revealEditMenu(menuCoords, t('intro.lines.split_intersection', - { button: icon('#iD-operation-split', 'pre-text'), street: t('intro.graph.name.washington-street') }) + reveal('.edit-menu', t('intro.lines.split_intersection', + { button: icon('#iD-operation-split', 'pre-text'), street: t('intro.graph.name.washington-street') }), + { padding: 50 } ); context.map().on('move.intro drawn.intro', function() { var node = selectMenuItem(context, 'split').node(); if (!wasChanged && !node) { return continueTo(rightClickIntersection); } - revealEditMenu(menuCoords, t('intro.lines.split_intersection', + reveal('.edit-menu', t('intro.lines.split_intersection', { button: icon('#iD-operation-split', 'pre-text'), street: t('intro.graph.name.washington-street') }), - { duration: 0 } + { duration: 0, padding: 50 } ); }); @@ -984,15 +966,15 @@ export function uiIntroLine(context, reveal) { var node = selectMenuItem(context, 'delete').node(); if (!node) return continueTo(multiRightClick); - var menuCoords = context.map().mouseCoordinates(); - revealEditMenu(menuCoords, - t('intro.lines.multi_delete', { button: icon('#iD-operation-delete', 'pre-text') }) + reveal('.edit-menu', + t('intro.lines.multi_delete', { button: icon('#iD-operation-delete', 'pre-text') }), + { padding: 50 } ); context.map().on('move.intro drawn.intro', function() { - revealEditMenu(menuCoords, + reveal('.edit-menu', t('intro.lines.multi_delete', { button: icon('#iD-operation-delete', 'pre-text') }), - { duration: 0 } + { duration: 0, padding: 50 } ); }); diff --git a/modules/ui/intro/navigation.js b/modules/ui/intro/navigation.js index d34a3b69d..7843aac4c 100644 --- a/modules/ui/intro/navigation.js +++ b/modules/ui/intro/navigation.js @@ -58,9 +58,11 @@ export function uiIntroNavigation(context, reveal) { timeout(function() { var centerStart = context.map().center(); - reveal('.surface', t('intro.navigation.drag')); + var textId = context.lastPointerType() === 'mouse' ? 'drag' : 'drag_touch'; + + reveal('.surface', t('intro.navigation.' + textId)); context.map().on('drawn.intro', function() { - reveal('.surface', t('intro.navigation.drag'), { duration: 0 }); + reveal('.surface', t('intro.navigation.' + textId), { duration: 0 }); }); context.map().on('move.intro', function() { @@ -83,8 +85,10 @@ export function uiIntroNavigation(context, reveal) { function zoomMap() { var zoomStart = context.map().zoom(); + var textId = context.lastPointerType() === 'mouse' ? 'zoom' : 'zoom_touch'; + reveal('.surface', - t('intro.navigation.zoom', { + t('intro.navigation.' + textId, { plus: icon('#iD-icon-plus', 'pre-text'), minus: icon('#iD-icon-minus', 'pre-text') }) @@ -92,7 +96,7 @@ export function uiIntroNavigation(context, reveal) { context.map().on('drawn.intro', function() { reveal('.surface', - t('intro.navigation.zoom', { + t('intro.navigation.' + textId, { plus: icon('#iD-icon-plus', 'pre-text'), minus: icon('#iD-icon-minus', 'pre-text') }), { duration: 0 } @@ -183,13 +187,14 @@ export function uiIntroNavigation(context, reveal) { var entity = context.hasEntity(hallId); if (!entity) return; var box = pointBox(entity.loc, context); - reveal(box, t('intro.navigation.click_townhall')); + var textId = context.lastPointerType() === 'mouse' ? 'click_townhall' : 'tap_townhall'; + reveal(box, t('intro.navigation.' + textId)); context.map().on('move.intro drawn.intro', function() { var entity = context.hasEntity(hallId); if (!entity) return; var box = pointBox(entity.loc, context); - reveal(box, t('intro.navigation.click_townhall'), { duration: 0 }); + reveal(box, t('intro.navigation.' + textId), { duration: 0 }); }); context.on('enter.intro', function() { diff --git a/modules/ui/intro/point.js b/modules/ui/intro/point.js index a5ddcae03..81917c9cd 100644 --- a/modules/ui/intro/point.js +++ b/modules/ui/intro/point.js @@ -32,24 +32,6 @@ export function uiIntroPoint(context, reveal) { } - function revealEditMenu(loc, text, options) { - var rect = context.surfaceRect(); - var point = context.curtainProjection(loc); - var pad = 40; - var width = 250 + (2 * pad); - var height = 250; - var startX = rect.left + point[0]; - var left = (localizer.textDirection() === 'rtl') ? (startX - width + pad) : (startX - pad); - var box = { - left: left, - top: point[1] + rect.top - 60, - width: width, - height: height - }; - reveal(box, text, options); - } - - function eventCancel() { d3_event.stopPropagation(); d3_event.preventDefault(); @@ -95,11 +77,12 @@ export function uiIntroPoint(context, reveal) { } var pointBox = pad(building, 150, context); - reveal(pointBox, t('intro.points.place_point')); + var textId = context.lastPointerType() === 'mouse' ? 'place_point' : 'place_point_touch'; + reveal(pointBox, t('intro.points.' + textId)); context.map().on('move.intro drawn.intro', function() { pointBox = pad(building, 150, context); - reveal(pointBox, t('intro.points.place_point'), { duration: 0 }); + reveal(pointBox, t('intro.points.' + textId), { duration: 0 }); }); context.on('enter.intro', function(mode) { @@ -385,14 +368,15 @@ export function uiIntroPoint(context, reveal) { context.enter(modeBrowse(context)); var box = pointBox(entity.loc, context); - reveal(box, t('intro.points.rightclick'), { duration: 600 }); + var textId = context.lastPointerType() === 'mouse' ? 'rightclick' : 'edit_menu_touch'; + reveal(box, t('intro.points.' + textId), { duration: 600 }); timeout(function() { context.map().on('move.intro', function() { var entity = context.hasEntity(_pointID); if (!entity) return chapter.restart(); var box = pointBox(entity.loc, context); - reveal(box, t('intro.points.rightclick'), { duration: 0 }); + reveal(box, t('intro.points.' + textId), { duration: 0 }); }); }, 600); // after reveal @@ -424,15 +408,16 @@ export function uiIntroPoint(context, reveal) { var node = selectMenuItem(context, 'delete').node(); if (!node) { return continueTo(rightClickPoint); } - revealEditMenu(entity.loc, - t('intro.points.delete', { button: icon('#iD-operation-delete', 'pre-text') }) + reveal('.edit-menu', + t('intro.points.delete', { button: icon('#iD-operation-delete', 'pre-text') }), + { padding: 50 } ); timeout(function() { context.map().on('move.intro', function() { - revealEditMenu(entity.loc, + reveal('.edit-menu', t('intro.points.delete', { button: icon('#iD-operation-delete', 'pre-text') }), - { duration: 0} + { duration: 0, padding: 50 } ); }); }, 300); // after menu visible