So here's what I came up with so far based on the new 4.7 sketch example.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<title>Sketch temporary geometries - 4.7</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.7/esri/css/main.css">
<script src="https://js.arcgis.com/4.7/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
font-family: verdana;
}
#topbar {
background: #fff;
position: absolute;
top: 15px;
right: 15px;
padding: 10px;
}
.action-button {
font-size: 16px;
background-color: transparent;
border: 1px solid #D3D3D3;
color: #6e6e6e;
height: 32px;
width: 32px;
text-align: center;
box-shadow: 0 0 1px rgba(0, 0, 0, 0.3);
}
.action-button:hover,
.action-button:focus {
background: #0079c1;
color: #e4e4e4;
}
.active {
background: #0079c1;
color: #e4e4e4;
}
</style>
<script>
require([
"esri/views/MapView",
"esri/Map",
'esri/geometry/geometryEngine',
"esri/widgets/Sketch/SketchViewModel",
"esri/Graphic",
"esri/layers/GraphicsLayer",
"dojo/domReady!"
], function(
MapView, Map,
geometryEngine,
SketchViewModel, Graphic, GraphicsLayer
) {
var tempGraphicsLayer = new GraphicsLayer();
var bufferGraphicsLayer = new GraphicsLayer();
var updateGraphic, sketchStartEvent, viewPointerMoveEvent, bufferGraphic;
var bufferDistance = 1000;
var unit = 'kilometers'
var unionResults = true;
var map = new Map({
basemap: "gray",
layers: [tempGraphicsLayer, bufferGraphicsLayer]
});
var view = new MapView({
container: "viewDiv",
map: map,
zoom: 3
});
var pointSymbol = {
type: "simple-marker",
style: "square",
color: "#8A2BE2",
size: "16px",
outline: {
color: [255, 255, 255],
width: 3
}
}
var polylineSymbol = {
type: "simple-line",
color: "#8A2BE2",
width: "4",
style: "dash"
}
var polygonSymbol = {
type: "simple-fill",
color: "rgba(138,43,226, 0.8)",
style: "solid",
outline: {
color: "white",
width: 1
}
}
view.when(function() {
var sketchViewModel = new SketchViewModel({
view: view,
layer: tempGraphicsLayer,
pointSymbol: pointSymbol,
polylineSymbol: polylineSymbol,
polygonSymbol: polygonSymbol
});
setUpClickHandler();
sketchViewModel.on("draw-complete", addGraphic);
sketchViewModel.on("update-complete", addGraphic);
sketchViewModel.on("update-cancel", addGraphic);
function addGraphic(evt) {
viewPointerMoveEvent.remove();
var geometry = evt.geometry;
var symbol;
switch (geometry.type) {
case "point":
symbol = pointSymbol;
break;
case "polyline":
symbol = polylineSymbol;
break;
default:
symbol = polygonSymbol;
break;
}
var graphic = new Graphic({
geometry: geometry,
symbol: symbol
});
tempGraphicsLayer.add(graphic);
generateBufferGraphic(geometry);
tempGraphicsLayer.add(bufferGraphicsLayer.graphics.items[0]);
bufferGraphicsLayer.removeAll();
updateGraphic = null;
sketchViewModel.reset();
}
var drawPointButton = document.getElementById("pointButton");
drawPointButton.onclick = function() {
sketchViewModel.create("point");
setActiveButton(this);
};
var drawLineButton = document.getElementById("polylineButton");
drawLineButton.onclick = function() {
sketchViewModel.create("polyline");
setActiveButton(this);
};
var drawPolygonButton = document.getElementById("polygonButton");
drawPolygonButton.onclick = function() {
sketchViewModel.create("polygon");
setActiveButton(this);
};
var drawRectangleButton = document.getElementById(
"rectangleButton");
drawRectangleButton.onclick = function() {
sketchViewModel.create("rectangle");
setActiveButton(this);
};
var drawCircleButton = document.getElementById("circleButton");
drawCircleButton.onclick = function() {
sketchViewModel.create("circle");
setActiveButton(this);
};
document.getElementById("resetBtn").onclick = function() {
sketchViewModel.reset();
tempGraphicsLayer.removeAll();
bufferGraphicsLayer.removeAll();
setActiveButton();
};
function setActiveButton(selectedButton) {
view.focus();
var elements = document.getElementsByClassName("active");
for (var i = 0; i < elements.length; i++) {
elements[i].classList.remove("active");
}
if (selectedButton) {
selectedButton.classList.add("active");
}
}
function setUpClickHandler() {
view.on("click", function(evt) {
view.hitTest(evt).then(function(response) {
var results = response.results;
if (results.length && results[results.length - 1]
.graphic) {
if (!updateGraphic) {
updateGraphic = results[results.length - 1].graphic;
tempGraphicsLayer.remove(updateGraphic);
sketchViewModel.update(updateGraphic.geometry);
}
}
});
});
}
sketchStartEvent = sketchViewModel.on('draw-start', sketchStartHandler);
function sketchStartHandler(sketchEvt) {
var sketchGeometry;
viewPointerMoveEvent = view.on('pointer-move', viewPointerMoveHandler);
function viewPointerMoveHandler(viewEvt) {
if (sketchEvt.target.graphic && sketchEvt.target.draw.activeAction.vertices.length > 1) {
sketchGeometry = sketchEvt.target.graphic.geometry;
} else {
sketchGeometry = view.toMap({
x: viewEvt.x,
y: viewEvt.y
});
}
generateBufferGraphic(sketchGeometry);
};
};
function generateBufferGraphic(geometry, bufferDistance = 500, unit = 'kilometers', unionResults = true) {
bufferGraphicsLayer.removeAll();
var buffer = geometryEngine.geodesicBuffer(geometry, bufferDistance, unit, unionResults);
bufferGraphicsLayer.add(new Graphic({
geometry: buffer,
symbol: polygonSymbol
}));
}
});
});
</script>
</head>
<body>
<div id="viewDiv">
<div id="topbar">
<button class="action-button esri-icon-blank-map-pin" id="pointButton" type="button"
title="Draw point"></button>
<button class="action-button esri-icon-polyline" id="polylineButton" type="button"
title="Draw polyline"></button>
<button class="action-button esri-icon-polygon" id="polygonButton" type="button"
title="Draw polygon"></button>
<button class="action-button esri-icon-checkbox-unchecked" id="rectangleButton" type="button"
title="Draw rectangle"></button>
<button class="action-button esri-icon-radio-unchecked" id="circleButton" type="button"
title="Draw circle"></button>
<button class="action-button esri-icon-trash" id="resetBtn" type="button" title="Clear graphics"></button>
</div>
</div>
</body>
</html>
It seems to work but I'm not sure how best to remove the on pointer move event listener for the view. If you look at the console log, there are errors when drawing line or polygons. How do I remove the event listener so it doesn't keep running? I also tried using event.stopPropagation() but it looks like that doesn't actually remove the listener and might cause memory issues in the browser because it keeps running.