在 angularjs 或 Jquery 中点击并标记图像的不同部分
Click on and tag different section of image in angularjs or Jquery
我有一个基于建筑的新项目。在这里,我们将拥有大量的建筑结构和工程图图像集。
这是我尝试这样做的小 plunker link 尝试。
我不知道这是否可行,我想点击图像的不同部分,创建标签并根据这些标签进行评论。
有人可以帮助我在鼠标点击图像顶部的光标旁边获得弹出窗口。
创建的标签将用于该部分,下次任何想要预览的用户都可以将鼠标悬停在图像上并将标签作为工具提示查看,然后关注该标签的评论主题。
我试过 angular 但 Jquery 或任何其他 js 框架都可以,只要它有效。
<body ng-controller="MainCtrl">
<br>
<div class='container-fluid'>
<div class='alert alert-info'>
<h4>Click the image and tag</h4>
</div>
<div class='row'>
<div class='col-lg-11'>
<div class='col-sm-11 ' >
<img tagover src='http://www.studioats.com/wp-content/uploads/2011/05/A2-1A-First-Floor-Plan-Area-A-12x18.jpg' height='300' width='500' />
</div>
<div class='col-sm-3 well' >
<p><span class='label label-info'>Comments</span> {{tagName}}</p>
<textarea class='form-control' placeholder='comments here'></textarea>
</div>
</div>
</div>
</div>
脚本
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
});
app.directive('tagover', function ($compile,$templateCache,$interpolate) {
var getTemplate = function (contentType,attrs) {
var template = '';
switch (contentType) {
case 'comment':
var template = "<div class='' >";
template += "<input class='form-control' type='text' ng-model='tagName' placeholder='tag name'>";
template += "</div>";
template += "</div>";
break;
}
return template;
} //
return {
restrict: "A",
link: function (scope, element, attrs) {
var popOverContent;
var d = new Date();
var mm = d.getMonth()+1;
popOverContent = getTemplate("comment",attrs);
var compiled = $compile(popOverContent)(scope);
var options = {
content: compiled,
placement: "bottom",
html: true,
date: scope.date
};
$(element).popover(options);
}
};
});
我认为 angular-leaflet-directive
更容易做到这一点。 Leaflet 是一种映射工具,您可以在其中添加图像作为叠加层,并且可以根据需要添加 marker/tags。这些位置存储为地理坐标 (longitude/latitude),但我认为这没关系。如果你需要以像素为单位的位置,你可以计算它们,但我认为你不需要那个。
下面我已经为您或在此 fiddle 编写了一个简短的演示。
在传单指令之后,我添加了 tagNames
范围变量用于调试。
您的应用需要改进的地方:
- 向服务添加标记,以便将它们存储在本地存储或数据库中
- 控制台有时会出现错误
TypeError: t.className is undefined
不确定是什么,它是在平移地图期间随机发生的。
- 检查是否最大。地图的边界是正确的。我还没有检查它是否是从演示代码中复制的。
- 检查标记是否需要 mouseout。我已经对其进行了评论,因此您可以单击标签名称的输入。
- 了解拼贴图像的工作原理,然后您可以将一张高分辨率图像拆分成许多拼贴,您将获得更好的用户体验,但对于开始,您可以先处理一张图像,然后再添加拼贴。
- 检查您是否需要图层(例如一楼或二楼)。我认为可以将其添加到传单中,但是您需要检查是否必须向标记添加可见性属性(如果传单未处理)。
angular.module("taggingApp", ["leaflet-directive"])
.controller('tagController', TagController);
//string.format helper
String.prototype.format = function() {
var formatted = this;
for (var i = 0; i < arguments.length; i++) {
var regexp = new RegExp('\{'+i+'\}', 'gi');
formatted = formatted.replace(regexp, arguments[i]);
}
return formatted;
};
function TagController($scope, $compile, $log, $timeout, leafletData, leafletBoundsHelpers) {
var markerCount = 0;
var html = '<div>Please add tag name: <input ng-model="tagNames.m{0}"/><button ng-click="remove(\'m{0}\')">remove tag</button></div>marker key: m{0}'; //.format(markerCount); //template for marker
// image size = 1.296px × 864px
var maxBounds = leafletBoundsHelpers.createBoundsFromArray([[-540, -960], [540, 960]]);
angular.extend($scope, {
tagNames: {
m0: 'first tag'
}, // tagnames
defaults: {
scrollWheelZoom: false,
crs: 'Simple',
maxZoom: 2
},
markers: {
m0: {
lat: 33,
lng: 4,
//message: "I'm a static marker - m" + markerCount,
message: html.format(markerCount++),
getMessageScope: function() { return $scope;},
icon: {},
}
},
center: {
lat: 0,
lng: 0,
zoom: 0
},
maxBounds: maxBounds,
layers: {
baselayers: {
home: {
name: 'home',
type: 'imageOverlay',
url: 'http://www.studioats.com/wp-content/uploads/2011/05/A2-1A-First-Floor-Plan-Area-A-12x18.jpg',
bounds: [[-540, -960], [540, 960]],
layerParams: {
noWrap: true,
attribution: 'demo tile...'
}
}
}
}
});
$scope.$on('leafletDirectiveMarker.mouseover', function(e, args) {
args.leafletEvent.target.openPopup();
});
/*$scope.$on('leafletDirectiveMarker.mouseout', function(e, args) {
args.leafletEvent.target.closePopup();
});*/
$scope.remove = function(markerName) {
console.log(markerName, $scope.markers);
// remove marker
if ( $scope.tagNames && $scope.tagNames[markerName] )
delete $scope.tagNames[markerName];
delete $scope.markers[markerName];
markerCount-- < 0 ? 0: markerCount;
console.log(markerCount);
};
$scope.$on('leafletDirectiveMap.click', function(scope, e) {
//console.log(e, pos);
var lat = e.leafletEvent.latlng.lat,
lng = e.leafletEvent.latlng.lng;
//alert("Lat, Lon : " + e.leafletEvent.latlng.lat + ", " + e.leafletEvent.latlng.lng)
$scope.markers['m'+(++markerCount)] = {
lat: lat,
lng: lng,
//message: "I'm a static marker - m" + markerCount,
message: html.format(markerCount),
getMessageScope: function() { return $scope;},
icon: {},
};
});
}
<link href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.js"></script>
<script src="http://tombatossals.github.io/angular-leaflet-directive/dist/angular-leaflet-directive.min.js"></script>
<script src="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.js"></script>
<div ng-app="taggingApp" ng-controller="tagController">
<leaflet width="500px" height="500px" center="center" layers="layers" defaults="defaults" markers="markers"></leaflet>
{{tagNames | json}}
</div>
我有一个基于建筑的新项目。在这里,我们将拥有大量的建筑结构和工程图图像集。
这是我尝试这样做的小 plunker link 尝试。
我不知道这是否可行,我想点击图像的不同部分,创建标签并根据这些标签进行评论。
有人可以帮助我在鼠标点击图像顶部的光标旁边获得弹出窗口。 创建的标签将用于该部分,下次任何想要预览的用户都可以将鼠标悬停在图像上并将标签作为工具提示查看,然后关注该标签的评论主题。
我试过 angular 但 Jquery 或任何其他 js 框架都可以,只要它有效。
<body ng-controller="MainCtrl">
<br>
<div class='container-fluid'>
<div class='alert alert-info'>
<h4>Click the image and tag</h4>
</div>
<div class='row'>
<div class='col-lg-11'>
<div class='col-sm-11 ' >
<img tagover src='http://www.studioats.com/wp-content/uploads/2011/05/A2-1A-First-Floor-Plan-Area-A-12x18.jpg' height='300' width='500' />
</div>
<div class='col-sm-3 well' >
<p><span class='label label-info'>Comments</span> {{tagName}}</p>
<textarea class='form-control' placeholder='comments here'></textarea>
</div>
</div>
</div>
</div>
脚本
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
});
app.directive('tagover', function ($compile,$templateCache,$interpolate) {
var getTemplate = function (contentType,attrs) {
var template = '';
switch (contentType) {
case 'comment':
var template = "<div class='' >";
template += "<input class='form-control' type='text' ng-model='tagName' placeholder='tag name'>";
template += "</div>";
template += "</div>";
break;
}
return template;
} //
return {
restrict: "A",
link: function (scope, element, attrs) {
var popOverContent;
var d = new Date();
var mm = d.getMonth()+1;
popOverContent = getTemplate("comment",attrs);
var compiled = $compile(popOverContent)(scope);
var options = {
content: compiled,
placement: "bottom",
html: true,
date: scope.date
};
$(element).popover(options);
}
};
});
我认为 angular-leaflet-directive
更容易做到这一点。 Leaflet 是一种映射工具,您可以在其中添加图像作为叠加层,并且可以根据需要添加 marker/tags。这些位置存储为地理坐标 (longitude/latitude),但我认为这没关系。如果你需要以像素为单位的位置,你可以计算它们,但我认为你不需要那个。
下面我已经为您或在此 fiddle 编写了一个简短的演示。
在传单指令之后,我添加了 tagNames
范围变量用于调试。
您的应用需要改进的地方:
- 向服务添加标记,以便将它们存储在本地存储或数据库中
- 控制台有时会出现错误
TypeError: t.className is undefined
不确定是什么,它是在平移地图期间随机发生的。 - 检查是否最大。地图的边界是正确的。我还没有检查它是否是从演示代码中复制的。
- 检查标记是否需要 mouseout。我已经对其进行了评论,因此您可以单击标签名称的输入。
- 了解拼贴图像的工作原理,然后您可以将一张高分辨率图像拆分成许多拼贴,您将获得更好的用户体验,但对于开始,您可以先处理一张图像,然后再添加拼贴。
- 检查您是否需要图层(例如一楼或二楼)。我认为可以将其添加到传单中,但是您需要检查是否必须向标记添加可见性属性(如果传单未处理)。
angular.module("taggingApp", ["leaflet-directive"])
.controller('tagController', TagController);
//string.format helper
String.prototype.format = function() {
var formatted = this;
for (var i = 0; i < arguments.length; i++) {
var regexp = new RegExp('\{'+i+'\}', 'gi');
formatted = formatted.replace(regexp, arguments[i]);
}
return formatted;
};
function TagController($scope, $compile, $log, $timeout, leafletData, leafletBoundsHelpers) {
var markerCount = 0;
var html = '<div>Please add tag name: <input ng-model="tagNames.m{0}"/><button ng-click="remove(\'m{0}\')">remove tag</button></div>marker key: m{0}'; //.format(markerCount); //template for marker
// image size = 1.296px × 864px
var maxBounds = leafletBoundsHelpers.createBoundsFromArray([[-540, -960], [540, 960]]);
angular.extend($scope, {
tagNames: {
m0: 'first tag'
}, // tagnames
defaults: {
scrollWheelZoom: false,
crs: 'Simple',
maxZoom: 2
},
markers: {
m0: {
lat: 33,
lng: 4,
//message: "I'm a static marker - m" + markerCount,
message: html.format(markerCount++),
getMessageScope: function() { return $scope;},
icon: {},
}
},
center: {
lat: 0,
lng: 0,
zoom: 0
},
maxBounds: maxBounds,
layers: {
baselayers: {
home: {
name: 'home',
type: 'imageOverlay',
url: 'http://www.studioats.com/wp-content/uploads/2011/05/A2-1A-First-Floor-Plan-Area-A-12x18.jpg',
bounds: [[-540, -960], [540, 960]],
layerParams: {
noWrap: true,
attribution: 'demo tile...'
}
}
}
}
});
$scope.$on('leafletDirectiveMarker.mouseover', function(e, args) {
args.leafletEvent.target.openPopup();
});
/*$scope.$on('leafletDirectiveMarker.mouseout', function(e, args) {
args.leafletEvent.target.closePopup();
});*/
$scope.remove = function(markerName) {
console.log(markerName, $scope.markers);
// remove marker
if ( $scope.tagNames && $scope.tagNames[markerName] )
delete $scope.tagNames[markerName];
delete $scope.markers[markerName];
markerCount-- < 0 ? 0: markerCount;
console.log(markerCount);
};
$scope.$on('leafletDirectiveMap.click', function(scope, e) {
//console.log(e, pos);
var lat = e.leafletEvent.latlng.lat,
lng = e.leafletEvent.latlng.lng;
//alert("Lat, Lon : " + e.leafletEvent.latlng.lat + ", " + e.leafletEvent.latlng.lng)
$scope.markers['m'+(++markerCount)] = {
lat: lat,
lng: lng,
//message: "I'm a static marker - m" + markerCount,
message: html.format(markerCount),
getMessageScope: function() { return $scope;},
icon: {},
};
});
}
<link href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.js"></script>
<script src="http://tombatossals.github.io/angular-leaflet-directive/dist/angular-leaflet-directive.min.js"></script>
<script src="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.js"></script>
<div ng-app="taggingApp" ng-controller="tagController">
<leaflet width="500px" height="500px" center="center" layers="layers" defaults="defaults" markers="markers"></leaflet>
{{tagNames | json}}
</div>