我使用javascript(不是jQuery)。
这些值需要易于更改:
如果数字会破坏圆圈,不会关注。
我需要这个的原因是我有一张谷歌地图。它有很多不同数字和颜色的标记。我找到了一个可以运行的脚本(在Chrome中)但需要D3才能工作。
这似乎是一项简单的任务。这就是为什么我希望我能在这种情况下留下D3。
这是我目前的代码。我已经阅读了更多内容,也许可以用SVG来做。什么工作。
var karta = (function () {
var fn = {};
var map;
var latitude;
var longitude;
var zoom;
var cache = {};
var colors = [];
var height = 75;
var width = 75;
// Init
fn.init = function(options) {
console.log(options);
markers = options.markers;
latitude = options.latitude;
longitude = options.longitude;
zoom = options.zoom;
colors = fn.setColors();
fn.setMap();
fn.setMarkers();
console.log(options);
};
// Set map
fn.setMap = function() {
map = new google.maps.Map(document.getElementById('map_canvas'), {
zoom: zoom,
center: {
lat: latitude,
lng: longitude
},
mapTypeId: 'satellite',
mapTypeControl: false,
zoomControl: false,
streetViewControl: false,
});
};
// Set markers
fn.setMarkers = function() {
var mytest = '<svg height="32" width="32"><foreignObject width="32" height="32" x="16" y="16" transform="translate(-16,-16)"><div class="circle" style="background: blue; border-radius: 100%; text-align: center; line-height: 32px; font-size: 12px;"><span style="display: inline-block; vertical-align: middle; color: #fff; font-weight: bold;">180</span></div></foreignObject></svg>';
var myurl = 'data:image/svg+xml;charset=UTF-8;base64,' + btoa(mytest);
console.log(myurl);
markers.forEach( function( point ) {
fn.icon( point[0], function(src) {
new google.maps.Marker({
position: new google.maps.LatLng( point[1], point[2] ),
map: map,
icon: {
url: myurl,
anchor: new google.maps.Point(25, 25),
origin: new google.maps.Point(0, 0),
scaledSize: new google.maps.Size(50, 50)
}
});
});
});
};
// Set colors
fn.setColors = function() {
colors[65] = "E50000";
colors[80] = "E52500";
colors[95] = "E54A00";
colors[110] = "E56F00";
colors[125] = "E59400";
colors[140] = "B79B00";
colors[155] = "89A200";
colors[170] = "5CA900";
colors[185] = "2EB000";
colors[250] = "00B700";
return colors;
};
// Set circle
fn.setCircle = function(svg, number) {
var circles = svg.append('circle')
.attr('cx', '27.2')
.attr('cy', '27.2')
.attr('r', '12')
.style('fill', colors[number]);
return circles;
};
// Set label
fn.setLabel = function(svg, number) {
var label = svg.append('text')
.attr('dx', 27)
.attr('dy', 32)
.attr('text-anchor', 'middle')
.attr('style', 'font-size: 12px; fill: #FFFFFF; font-family: Arial, Verdana; font-weight: bold')
.text(number);
return label;
};
// Set svg
fn.setSvg = function(number) {
var svg = d3.select(document.createElement('div')).append('svg')
.attr('viewBox', '0 0 54.4 54.4')
.append('g')
fn.setCircle(svg, number);
fn.setLabel(svg, number);
return svg;
};
// Set image
fn.setImage = function(number, node, callback) {
var image = new Image();
image.onload = (function(width, height) {
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var dataURL;
d3.select(canvas)
.attr('width', width)
.attr('height', height);
context.drawImage(image, 0, 0, width, height);
dataURL = canvas.toDataURL();
generateIconCache[number] = dataURL;
callback(dataURL);
}).bind(this, width, height);
var xmlSource = (new XMLSerializer()).serializeToString(node);
image.src = 'data:image/svg+xml;base64,' + btoa(encodeURIComponent(xmlSource).replace(/%([0-9A-F]{2})/g, function(match, p1) {
return String.fromCharCode('0x' + p1);
}));
};
// Icon
fn.icon = function( number, callback ) {
if( cache[number] !== undefined ) {
callback( cache[number] );
}
var svg = fn.setSvg(number);
var node = svg.node().parentNode.cloneNode(true);
d3.select(node).select('clippath').remove();
fn.setImage(number, node, callback);
}
return fn;
})();
答案 0 :(得分:2)
要缩放文本以适合圆形,您需要找到文本中对角线的角度。为此,您需要字体高度和字体宽度。字体高度位于2D上下文的font属性中。例如,“18px Arial”和字体宽度可以使用2D上下文textWidth = ctx.measureText(text).width
来计算。
一旦获得字体宽度和字体高度,就可以得到textDiag = Math.atan(fontheight / fontWidth)
的对角线角度。这将是圆圈上文本角落接触侧面的角度。
我们可以从圆周上的那一点到通过圆圈中间的水平线绘制一条线,为我们提供文本右边缘的位置。您可以使用halfWidth = Math.cos(textDiag) * radius
获得该文本的总宽度应为该文本的两倍。
由于找到一个匹配给定文本宽度的点大小真的很痛苦,因此使用上下文转换矩阵缩放文本会更容易。
缩放只是所需的文本宽度除以已知的文本宽度。 fontScale = halfWidth * 2) / textWidth
然后设置转换ctx.setTransform(fontScale,0,0,fontScale,r,r)
(r是圆的半径或中心)并绘制文本ctx.filltext(text,0,0)
,并将textAlign和textBaseline 2d上下文属性设置为"center"
和{分别为{1}}
该示例通过创建可在另一个画布上绘制的简单文本圈img或仅作为图像添加到DOM来显示此操作。两个属性number和radius设置要显示的数字和大小(以像素为单位)。该演示显示它正在创建并绘制到画布上,数字增加以显示它如何缩放。
"middle"