JavaScript使用arcgis實(shí)現(xiàn)截圖截屏功能
前言
本篇將使用arcgis實(shí)現(xiàn)截圖/截屏功能,類似于qq截圖
效果展示

相關(guān)代碼
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<title>4.5 地圖截圖</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<link rel="stylesheet" rel="external nofollow" >
<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.7.2.min.js"></script>
<script src="https://js.arcgis.com/4.5/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/geometry/Extent",
"esri/geometry/Point",
"esri/widgets/Print",
"esri/Graphic",
"dojo/on",
"dojo/dom",
"esri/layers/GraphicsLayer",
"esri/tasks/PrintTask",
"esri/tasks/support/PrintTemplate",
"esri/tasks/support/PrintParameters",
"esri/views/2d/draw/Draw",
"esri/geometry/Polygon",
"esri/geometry/Point",
"dojo/domReady!"
], function(Map, MapView, Extent, Point, Print, Graphic, on, dom, GraphicsLayer, PrintTask,
PrintTemplate, PrintParameters, Draw, Polygon, Point) {
let map = new Map({
basemap: "streets"
});
let tempGraphicsLayer = new GraphicsLayer();
map.add(tempGraphicsLayer);
let view = new MapView({
container: "viewDiv",
map: map,
zoom: 4,
center: [15, 65] // longitude, latitude
});
view.ui.add("screenshot", "top-right");
view.then(function () {
let printTask = new PrintTask("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task");
let printTemplate = new PrintTemplate({
format: "jpg",
exportOptions: {
dpi: 96,
width: 700,
height: 1100
},
layout: "MAP_ONLY",
layoutOptions: {
"titleText": "",
"authorText": "",
"copyrightText": "",
"scalebarUnit": "",
},
showLabels: false,
preserveScale: false,
attributionVisible: false //是否顯示地圖屬性
});
let draw = new Draw({
view: view
});
let drawAction = null;
//允許繪制矩形
function enableCreateRectangle(draw, view) {
isStartDraw = isEndDraw = false;
// create() will return a reference to an instance of PolygonDrawAction
drawAction = draw.create("polygon", {mode: "click"});
// focus the view to activate keyboard shortcuts for drawing polygons
view.focus();
// listen to vertex-add event on the action
drawAction.on("vertex-add", drawRectangle);
drawAction.on("cursor-update", drawRectangle);
drawAction.on("vertex-remove", drawRectangle);
drawAction.on("draw-complete", endDraw);
}
let tempRectangle = [];
// 是否開始繪制,是否結(jié)束繪制 , 是否最后一次繪制
let isStartDraw = false, isEndDraw = false, isLastDraw = false;
// 結(jié)束繪制
function endDraw(evt){
isLastDraw = true;
let graphics = drawRectangle(evt);
isLastDraw = false;
// 改變指針樣式
$(".esri-view-root").css("cursor", "default");
let lonlat = graphics[graphics.length - 1].geometry.rings[0][3];
// 添加 “取消”、“保存”按鈕
let submit = new Graphic({
geometry: new Point({
x: lonlat[0],
y: lonlat[1],
z: 0,
spatialReference: view.spatialReference
}),
symbol: {
type: "text",
declaredClass: "clipBtn",
color: [0, 0, 0, 1],
haloColor: "black",
haloSize: "1px",
text: "截屏",
xoffset: -12,
yoffset: -24,
font: { // autocast as Font
size: 12,
// weight: "bold",
family: "sans-serif"
}
},
attributes: {
clipName: "確定"
}
});
tempRectangle.push(submit);
tempGraphicsLayer.add(tempRectangle[tempRectangle.length - 1]);
let cancel = new Graphic({
geometry: new Point({
x: lonlat[0],
y: lonlat[1],
z: 0,
spatialReference: view.spatialReference
}),
symbol: {
type: "text",
declaredClass: "clipBtn",
color: "red",
haloColor: "black",
haloSize: "1px",
text: "取消",
xoffset: -48,
yoffset: -24,
font: { // autocast as Font
size: 12,
// weight: "bold",
family: "sans-serif"
}
},
attributes: {
clipName: "取消"
}
});
tempRectangle.push(cancel);
tempGraphicsLayer.add(tempRectangle[tempRectangle.length - 1]);
//繪制結(jié)束
isEndDraw = true;
}
// 繪制多邊形
function drawRectangle(evt) {
//頂點(diǎn)取第一個(gè)點(diǎn)和最后一個(gè)點(diǎn)
let vertices = [evt.vertices[0], evt.vertices[evt.vertices.length - 1]];
//判斷drawAction類型
switch(evt.type){
case "vertex-add": //鼠標(biāo)按下或鼠標(biāo)拖動
isStartDraw = true;
break;
case "cursor-update": //鼠標(biāo)未按下狀態(tài)時(shí)的鼠標(biāo)移動
//判斷是否開始繪制,若開始繪制后鼠標(biāo)抬起,則結(jié)束繪制
if(isStartDraw){
drawAction.complete();
isStartDraw = false;
}
return;
break;
case "vertex-drag":
isStartDraw = true;
break;
default:
break;
}
// 若未開始繪制,則返回
if(!isStartDraw){
return;
}
//remove existing graphic
clearGraphics();
// create a new rectangle
let polygon = createRectangle(vertices);
// create a new graphic representing the polygon, add it to the view
tempRectangle.push(createGraphic(polygon));
tempGraphicsLayer.add(tempRectangle[tempRectangle.length - 1]);
return tempRectangle;
}
// 創(chuàng)建矩形
function createRectangle(vertices) {
let rectangle = new Polygon({
rings: vertices,
spatialReference: view.spatialReference
});
// 添加四個(gè)角的標(biāo)記點(diǎn)
let extent = rectangle.extent.clone();
if(extent.xmin != extent.xmax && extent.ymin != extent.ymax){
let rings = [];
rings.push([extent.xmax, extent.ymax]);
rings.push([extent.xmin, extent.ymax]);
rings.push([extent.xmin, extent.ymin]);
rings.push([extent.xmax, extent.ymin]);
let rectangle = new Polygon({
rings: rings,
spatialReference: view.spatialReference
})
// 若不是最后一次繪制,則添加四個(gè)角點(diǎn)
// if(!isLastDraw){
for(let i=0; i<rings.length; i++){
let marker = new Graphic({
geometry: new Point({
x: rings[i][0],
y: rings[i][1],
z: 0,
spatialReference: view.spatialReference
}),
symbol: {
type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
color: [0, 0, 0],
outline: { // autocasts as new SimpleLineSymbol()
color: [0, 0, 0],
width: 0.5
}
},
attributes: {
clipName: "extent_" + i
}
});
tempRectangle.push(marker);
tempGraphicsLayer.add(tempRectangle[tempRectangle.length - 1]);
}
// }
return rectangle;
}
return rectangle;
}
// 清除截屏的要素
function clearGraphics(){
if(tempRectangle.length > 0){
for(let i=0; i<tempRectangle.length; i++){
tempGraphicsLayer.remove(tempRectangle[i]);
}
}
tempRectangle = [];
}
// 創(chuàng)建截屏要素
function createGraphic(rectangle) {
graphic = new Graphic({
geometry: rectangle,
symbol: {
type: "simple-fill", // autocasts as SimpleFillSymbol
color: [0, 0, 0, 0.1],
style: "solid",
outline: { // autocasts as SimpleLineSymbol
color: [0, 0, 0],
width: 1
}
},
attributes: {
clipName: "clipRectangle"
}
});
return graphic;
}
// 截圖按鈕點(diǎn)擊事件
let screenshotBtn = document.getElementById("screenshot");
screenshotBtn.addEventListener("click", function() {
//清除已繪制圖形
clearGraphics();
isEndDraw = false;
enableCreateRectangle(draw, view);
view.focus();
// 改變指針樣式
$(".esri-view-root").css("cursor", "crosshair");
});
// 監(jiān)聽地圖點(diǎn)擊事件
view.on("click", function(event){
let screenPoint = {
x: event.x,
y: event.y
};
// 開始截屏/取消截屏
if(isEndDraw){
view.hitTest(screenPoint).then(function(response){
if(response.results[0].graphic){
let graphic = response.results[0].graphic;
if(graphic.attributes.clipName){
switch(graphic.attributes.clipName){
case "確定":
let extent = tempRectangle[4].geometry.extent;
clearGraphics();
// let height = printTemplate.exportOptions.width*extent.height/extent.width;
let minPoint = view.toScreen({x: extent.xmin, y: extent.ymin});
let maxPoint = view.toScreen({x: extent.xmax, y: extent.ymax});
let width = Math.abs(maxPoint.x - minPoint.x);
let height = Math.abs(maxPoint.y - minPoint.y);
printTemplate.exportOptions.width = width;
printTemplate.exportOptions.height = height;
// 開始打印
let printParams = new PrintParameters({
view: view,
template: printTemplate,
extent: extent
});
printTask.execute(printParams).then(function(evt){
// 保存至本地
let a = document.createElement('a');
a.href = evt.url;
a.download = '截圖.jpg';
a.click();
//window.open(evt.url);
}, function (evt) {
alert("截圖失??!");
});
break;
case "取消":
clearGraphics();
isEndDraw = false;
break;
default:
break;
}
}
}
});
}
});
// 截屏范圍拖動事件監(jiān)聽
let isStartDrag = false, isAllDrag = false, dragHandle = {drag: {}}, isEnableDrag = true;
let allDrag = {startPoint: [], endPoint: [], orignVertices: [[], []]};
let dragVertices = [[], []];
view.on("pointer-down", function(event){
let screenPoint = {
x: event.x,
y: event.y
};
// 開始截屏/取消截屏
if(isEndDraw){
view.hitTest(screenPoint).then(function(response){
if(response.results[0].graphic){
let graphic = response.results[0].graphic;
if(graphic.attributes.clipName){
switch(graphic.attributes.clipName){
case "確定":
break;
case "取消":
break;
case "clipRectangle":
isStartDrag = isAllDrag = true;
let sGraphic = tempRectangle[1];
let nGraphic = tempRectangle[3];
dragVertices = [
[sGraphic.geometry.x, sGraphic.geometry.y],
[nGraphic.geometry.x, nGraphic.geometry.y]
];
let point = view.toMap(screenPoint);
allDrag.startPoint = [point.x, point.y];
allDrag.orignVertices = [].concat(dragVertices);
// 禁止地圖拖動
dragHandle.drag = view.on('drag',function(e){e.stopPropagation()});
break;
default:
if(graphic.attributes.clipName.indexOf("_") > -1){
// 開始拖動頂點(diǎn)
isStartDrag = true;
let index = graphic.attributes.clipName.split("_")[1];
let nIndex = parseInt(index) + 2;
if(nIndex > 3){
nIndex = nIndex - 3 - 1;
}
let nGraphic = tempRectangle[nIndex];
dragVertices[0] = [nGraphic.geometry.x, nGraphic.geometry.y];
// 禁止地圖拖動
dragHandle.drag = view.on('drag',function(e){e.stopPropagation()});
}
break;
}
}
}
});
}
})
// 監(jiān)聽鼠標(biāo)移動事件
view.on('pointer-move', function(evt){
let screenPoint = {x: evt.x, y: evt.y};
let point = view.toMap(screenPoint);
if(isEndDraw){
// 改變指針樣式
$(".esri-view-root").css("cursor", "default");
view.hitTest(screenPoint).then(function(response){
if(response.results[0].graphic){
let graphic = response.results[0].graphic;
if(graphic.attributes.clipName){
switch(graphic.attributes.clipName){
case "確定":
// 改變指針樣式
$(".esri-view-root").css("cursor", "pointer");
break;
case "取消":
// 改變指針樣式
$(".esri-view-root").css("cursor", "pointer");
break;
case "clipRectangle":
// 改變指針樣式
$(".esri-view-root").css("cursor", "move");
break;
case "extent_0":
// 改變指針樣式
$(".esri-view-root").css("cursor", "ne-resize");
break;
case "extent_1":
// 改變指針樣式
$(".esri-view-root").css("cursor", "se-resize");
break;
case "extent_2":
// 改變指針樣式
$(".esri-view-root").css("cursor", "sw-resize");
break;
case "extent_3":
// 改變指針樣式
$(".esri-view-root").css("cursor", "se-resize");
break;
default:
break;
}
}
}
});
}
// 若開始拖動
if(isStartDrag){
if(isAllDrag){//整體拖動
allDrag.endPoint = [point.x, point.y];
// xy差值
let gapX = allDrag.endPoint[0] - allDrag.startPoint[0];
let gapY = allDrag.endPoint[1] - allDrag.startPoint[1];
dragVertices = [
[allDrag.orignVertices[0][0] + gapX, allDrag.orignVertices[0][1] + gapY],
[allDrag.orignVertices[1][0] + gapX, allDrag.orignVertices[1][1] + gapY]
];
let evt = {
type: "vertex-drag",
vertices: dragVertices
}
endDraw(evt);
}else{//頂點(diǎn)拖動
dragVertices[1] = [point.x, point.y];
let evt = {
type: "vertex-drag",
vertices: dragVertices
}
endDraw(evt);
}
}
});
// 監(jiān)聽鼠標(biāo)移動事件
view.on('pointer-up', function(evt){
let point = view.toMap({x: evt.x, y: evt.y});
if(isStartDrag){
if(isAllDrag){//整體拖動
allDrag.endPoint = [point.x, point.y];
// xy差值
let gapX = allDrag.endPoint[0] - allDrag.startPoint[0];
let gapY = allDrag.endPoint[1] - allDrag.startPoint[1];
dragVertices = [
[allDrag.orignVertices[0][0] + gapX, allDrag.orignVertices[0][1] + gapY],
[allDrag.orignVertices[1][0] + gapX, allDrag.orignVertices[1][1] + gapY]
];
let evt = {
type: "vertex-drag",
vertices: dragVertices
}
endDraw(evt);
// 恢復(fù)地圖拖動
dragHandle.drag.remove();
isStartDrag = isAllDrag = false;
allDrag = {startPoint: [], endPoint: []};
}else{
dragVertices[1] = [point.x, point.y];
let evt = {
type: "vertex-drag",
vertices: dragVertices
}
endDraw(evt);
// 恢復(fù)地圖拖動
dragHandle.drag.remove();
isStartDrag = false;
}
}
});
});
});
</script>
</head>
<body>
<div id="viewDiv"></div>
<div id="screenshot" class="esri-widget-button esri-widget esri-interactive" title="截圖">
<a role="tab" data-toggle="tab" class="esri-icon-applications"></a>
</div>
</body>
</html>
說明:該代碼不太好 只實(shí)現(xiàn)了功能 在性能上和代碼上還需優(yōu)化!??!
到此這篇關(guān)于JavaScript使用arcgis實(shí)現(xiàn)截圖截屏功能的文章就介紹到這了,更多相關(guān)arcgis截圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何利用ES6進(jìn)行Promise封裝總結(jié)
這篇文章主要介紹了如何利用ES6進(jìn)行Promise封裝總結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02
Javascript中for循環(huán)語句的幾種寫法總結(jié)對比
如果您希望一遍又一遍地運(yùn)行相同的代碼,并且每次的值都不同,那么使用循環(huán)是很方便的,javascript中for循環(huán)也是非常常用的,下面這篇文章主要介紹了Javascript中for循環(huán)的幾種寫法,需要的朋友可以參考借鑒,一起來看看吧。2017-01-01
LayUI數(shù)據(jù)接口返回實(shí)體封裝的例子
今天小編就為大家分享一篇LayUI數(shù)據(jù)接口返回實(shí)體封裝的例子,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09
PPK 談 JavaScript 的 this 關(guān)鍵字 [翻譯]
在 JavaScript 中 this 是最強(qiáng)的關(guān)鍵字之一。這篇貼文就是要告訴你如何用好 this。2009-09-09

