Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 带有数字填充圆的画布_Javascript_Canvas - Fatal编程技术网

Javascript 带有数字填充圆的画布

Javascript 带有数字填充圆的画布,javascript,canvas,Javascript,Canvas,我使用javascript(不是jQuery) 简言之 填充圆 圈后透明 中间居中的数字 这些值需要易于更改: 半径 背景色 字号 字体系列 它应该不关心数字是否会打破圆圈 理由 我之所以需要这个是因为我有一个谷歌地图。它有很多不同数字和颜色的标记。我发现了一个可以工作的脚本(在Chrome中),但需要它才能工作 这似乎是一项简单的任务。这就是为什么我希望我能在这种情况下离开 更新 这是我目前的代码。我已经读了更多,也许可以用SVG实现。什么都管用 var karta = (funct

我使用javascript(不是jQuery)

简言之
  • 填充圆
  • 圈后透明
  • 中间居中的数字
这些值需要易于更改:

  • 半径
  • 背景色
  • 字号
  • 字体系列
它应该关心数字是否会打破圆圈

理由 我之所以需要这个是因为我有一个谷歌地图。它有很多不同数字和颜色的标记。我发现了一个可以工作的脚本(在Chrome中),但需要它才能工作

这似乎是一项简单的任务。这就是为什么我希望我能在这种情况下离开

更新 这是我目前的代码。我已经读了更多,也许可以用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;
})();
var karta=(函数(){
var fn={};
var映射;
纬度;
var经度;
变焦;
var cache={};
var颜色=[];
var高度=75;
var宽度=75;
//初始化
fn.init=函数(选项){
console.log(选项);
markers=options.markers;
纬度=选项。纬度;
经度=选项。经度;
zoom=options.zoom;
colors=fn.setColors();
fn.setMap();
fn.setMarkers();
console.log(选项);
};
//集合图
fn.setMap=函数(){
map=new google.maps.map(document.getElementById('map_canvas'){
缩放:缩放,
中心:{
纬度,
经度
},
mapTypeId:'卫星',
mapTypeControl:false,
动物控制:错误,
街景控制:错误,
});
};
//设置标记
fn.setMarkers=函数(){
var mytest='180';
var myurl='data:image/svg+xml;charset=UTF-8;base64'+btoa(mytest);
console.log(myurl);
markers.forEach(函数(点){
fn.图标(点[0],函数(src){
新的google.maps.Marker({
位置:新的google.maps.LatLng(点[1],点[2]),
地图:地图,
图标:{
url:myurl,
主播:新谷歌地图点(25,25),
来源:新google.maps.Point(0,0),
scaledSize:new google.maps.Size(50,50)
}
});
});
});
};
//定色
fn.setColors=函数(){
颜色[65]=“E50000”;
颜色[80]=“E52500”;
颜色[95]=“E54A00”;
颜色[110]=“E56F00”;
颜色[125]=“E59400”;
颜色[140]=“B79B00”;
颜色[155]=“89A200”;
颜色[170]=“5CA900”;
颜色[185]=“2EB000”;
颜色[250]=“00B700”;
返回颜色;
};
//设定圆
fn.setCircle=函数(svg,编号){
var circles=svg.append('circle')
.attr('cx','27.2')
.attr('cy','27.2')
.attr('r','12')
.样式('填充'、颜色[编号]);
返回圈;
};
//设置标签
fn.setLabel=函数(svg,编号){
var label=svg.append('text')
.attr('dx',27)
.attr('dy',32)
.attr('text-anchor','middle')
.attr('style','font size:12px;fill:#FFFFFF;字体系列:Arial,Verdana;字体重量:粗体')
.文本(编号);
退货标签;
};
//设置svg
fn.setSvg=功能(编号){
var svg=d3.select(document.createElement('div')).append('svg'))
.attr('viewBox','0 0 54.4 54.4')
.append('g')
fn.设置圆(svg,编号);
fn.设置标签(svg,编号);
返回svg;
};
//设置图像
fn.setImage=函数(编号、节点、回调){
var image=新图像();
image.onload=(函数(宽度、高度){
var canvas=document.createElement('canvas');
var context=canvas.getContext('2d');
var-dataURL;
d3.选择(画布)
.attr('width',width)
.attr('高度'),高度;
drawImage(图像,0,0,宽度,高度);
dataURL=canvas.toDataURL();
GenerateConCache[number]=数据URL;
回调(dataURL);
}).捆扎(此尺寸、宽度、高度);
var xmlSource=(新的XMLSerializer()).serializeToString(节点);
image.src='data:image/svg+xml;base64'+btoa(encodeURIComponent(xmlSource).替换(/%([0-9A-F]{2})/g,函数(匹配,p1){
返回字符串.fromCharCode('0x'+p1);
}));
};
//图标
fn.icon=函数(编号、回调){
if(缓存[编号]!==未定义){
回调(缓存[number]);
}
var svg=fn.setSvg(编号);
var node=svg.node().parentNode.cloneNode(true);
d3.select(节点).select('clippath').remove();
fn.setImage(编号、节点、回调);
}
返回fn;
})();
缩放文本以适合圆形。 要缩放文本以适合圆形,您需要找到穿过文本的对角线的角度。要得到它,您需要字体高度和字体宽度。字体高度在二维上下文的字体属性中。例如“18px Arial”,可以使用2D上下文
textWidth=ctx.measureText(text.width
计算字体宽度

一旦有了字体宽度和字体高度,就可以使用
textDiag=Math.atan(fontweath/fontweadth)
获得对角线角度。这将是圆圈上文本角接触侧面的角度

我们可以画一条线,从圆圈圆周上的那个点到穿过圆圈中间的水平线,从而给出文本右边缘的位置。你可以通过
halfWidth=Math.cos(textDiag)*radius
T得到它