在Google地图V3上旋转图像/标记图像

Hor*_*ter 27 javascript google-maps-api-3

如何在Google地图V3上旋转图像(标记图像)?

  • 没有为V2一个很好的例子在这里,到底做什么,我需要的.但对于GMap2!他们用旋转帆布做到了.
  • 使用JS/JQuery旋转的图像经常被使用,关于此有多个答案.但是我怎么能将它应用到我的地图图像?
  • 一种提到的方法是针对不同的角度使用不同的图像并在它们之间切换 - 这不是我想要的.我不喜欢有这么多图像,我想通过代码旋转.

备注:有类似的问题,但都是V2而不是V3(据我所知).我需要它为V3.

ErD*_*mKo 16

我解决这个问题的js课程是:

var RotateIcon = function(options){
    this.options = options || {};
    this.rImg = options.img || new Image();
    this.rImg.src = this.rImg.src || this.options.url || '';
    this.options.width = this.options.width || this.rImg.width || 52;
    this.options.height = this.options.height || this.rImg.height || 60;
    var canvas = document.createElement("canvas");
    canvas.width = this.options.width;
    canvas.height = this.options.height;
    this.context = canvas.getContext("2d");
    this.canvas = canvas;
};
RotateIcon.makeIcon = function(url) {
    return new RotateIcon({url: url});
};
RotateIcon.prototype.setRotation = function(options){
    var canvas = this.context,
        angle = options.deg ? options.deg * Math.PI / 180:
            options.rad,
        centerX = this.options.width/2,
        centerY = this.options.height/2;

    canvas.clearRect(0, 0, this.options.width, this.options.height);
    canvas.save();
    canvas.translate(centerX, centerY);
    canvas.rotate(angle);
    canvas.translate(-centerX, -centerY);
    canvas.drawImage(this.rImg, 0, 0);
    canvas.restore();
    return this;
};
RotateIcon.prototype.getUrl = function(){
    return this.canvas.toDataURL('image/png');
};
Run Code Online (Sandbox Code Playgroud)

像这样称呼它:

var marker = new google.maps.Marker({
    icon: {
        url: RotateIcon
            .makeIcon(
                'https://ru.gravatar.com/userimage/54712272/b8eb5f2d540a606f4a6c07c238a0bf40.png')
            .setRotation({deg: 92})
            .getUrl()
    }})
Run Code Online (Sandbox Code Playgroud)

在这里查看实例.http://jsfiddle.net/fe9grwdf/39/

  • 谢谢您的摘录。但是请注意,浏览器是异步加载的,因此有可能在加载图像之前调用`getUrl()`,并且有一个空白标记。setRotation和getUrl应该包装在promise中以解决此问题。 (2认同)

Hor*_*ter 11

我发现了Google MAP V3的两个扩展:infobox.jsmarkerwithlabel.js 两者都可以将图像DOM元素作为内容处理,而我可以通过jQuery 图像旋转插件进行旋转.

这甚至可以在旋转后不再设置标记图像.

编辑:如下问题/评论:

标签的扩展名是必需的,因为它可以处理其他DOM元素.所以我可以添加任意HTML作为标签,在我的特殊情况下我添加图像.然后我用旋转插件旋转这个图像(标签的孩子).因此,为图像分配一个id,以便轻松访问它.实际上我只使用一个标签用于图像,另一个用于描述性文本.

编辑2:由于Stephan对DOM准备情况的评论

在我的代码中,我找到了以下几行.这表明我在旋转图像之前强制在标签上绘图.

    if (!this._drawn) myImageLabel.draw(); // 1st time force a draw, otherwise rotating the image will fail because an asynchronously drawn object has not all tags in place
    if (this.heading != 0) this.rotateImage(this.heading, true);
Run Code Online (Sandbox Code Playgroud)

编辑3:代码示例如何创建Infobox.js

this._img = document.createElement('img');
... further manipulations of _img / Size / Id / ...
var planeImageLabelOptions = {
            content: this._img,
            disableAutoPan: true,
            boxStyle: planeImageLabelBoxStyle,
            pixelOffset: new google.maps.Size(-imgOffsetW / 2, -imgOffsetH / 2),
            closeBoxURL: "",
            position: latlng,
            zIndex: this.altitude < 0 ? 100 : this.altitude
 };
 var planeImageLabel = new InfoBox(planeImageLabelOptions);
Run Code Online (Sandbox Code Playgroud)

  • 你什么时候旋转图像?我的意思是,你做的事情如下吗?`var marker = new MarkerWithLabel({position:p,map:map,labelContent:"some html with <img rel="nofollow noreferrer" id ='myimg'>"}); $("#myimg").rotate(35);`因为我试过这种方式,但是它不起作用(导致dom尚未被修改以插入图像).有什么暗示吗?我正在使用jQM.(虽然这可能是一个不同的问题......) (2认同)

小智 8

我也很难找出旋转.png标记的方法.我解决了下面的问题.您可以使用相同的自定义图像创建许多标记,并旋转要旋转的特定标记.我希望它对你有所帮助.

var id = 'my_marker_01';
var img_url = "../img/car.png";
var my_icon = img_url + "#" + id;
var marker = new google.maps.Marker({
    icon: my_icon,
    ...
});

var rotate = 45;
$(`img[src="${my_icon}"]`).css(
    {'-webkit-transform' : 'rotate('+ rotate +'deg)',
       '-moz-transform' : 'rotate('+ rotate +'deg)',
       '-ms-transform' : 'rotate('+ rotate +'deg)',
       'transform' : 'rotate('+ rotate +'deg)'}); 
Run Code Online (Sandbox Code Playgroud)


Muh*_*laa 5

我已经使用以下代码在 v3 中完成了旋转:

<canvas id="carcanvas" width="1" height="1"></canvas>


    if (document.getElementById('carcanvas').getContext) {
        var supportsCanvas = true;
    } else {
        var supportsCanvas = false;
    }

    var rImg = new Image();
    rImg.src='/images/cariconl.png';

    // Returns the bearing in radians between two points.
    function bearing( from, to ) {
        // Convert to radians.
        var lat1 = from.latRadians();
        var lon1 = from.lngRadians();
        var lat2 = to.latRadians();
        var lon2 = to.lngRadians();
        // Compute the angle.
        var angle = - Math.atan2( Math.sin( lon1 - lon2 ) * Math.cos( lat2 ), Math.cos( lat1 ) * Math.sin( lat2 ) - Math.sin( lat1 ) * Math.cos( lat2 ) * Math.cos( lon1 - lon2 ) );
        if ( angle < 0.0 )
            angle  += Math.PI * 2.0;
        if (angle == 0) {angle=1.5;}
        return angle;
    }

    function plotcar() {
        canvas = document.getElementById("carcanvas").getContext('2d');
        var cosa = Math.cos(angle);
        var sina = Math.sin(angle);
        canvas.clearRect(0,0,32,32);
        canvas.save();
        canvas.rotate(angle);
        canvas.translate(16*sina+16*cosa,16*cosa-16*sina);
        canvas.drawImage(rImg,-16,-16);
        canvas.restore();
    }
Run Code Online (Sandbox Code Playgroud)

并在动画方法中:

if (supportsCanvas) {
                    angle = bearing(new google.maps.LatLng(lat1, lng1),new google.maps.LatLng(lat2, lng2));
                    plotcar();
                }
Run Code Online (Sandbox Code Playgroud)

我希望有帮助。


Epi*_*any 5

您没有在问题中陈述它,但我假设您希望相对于点a和点b之间的直线进行旋转,这将是它们的路径。为了制作可以旋转的Google SVG图标,您将需要使用Google Symbol类对象来定义标记符号的属性。这不会使用完整的.svg文件,而只会使用路径的d属性。请注意,Google符号类每个标记只能采用一个路径。

在使用javascript(直接更新标记对象属性)或CSS(通过添加和删除类更新标记属性)创建标记后,可以设置颜色,笔触,宽度,不透明度等其他属性。

例如,以下示例将创建一个可以拖动的箭头标记,即使在移动标记之后,该标记也会围绕地图上为纬度和经度长的点旋转。

HTML

<body id="document_body" onload="init();">
  <div id="rotation_control">
    Heading&deg;<input id="rotation_value" type="number" size="3" value="0" onchange="setRotation();" />
  </div>
  <div id="map_canvas"></div>
</body>
Run Code Online (Sandbox Code Playgroud)

CSS(是的,冗长的...我讨厌丑陋的)

#document_body {
    margin:0;
    border: 0;
    padding: 10px;
    font-family: Arial,sans-serif;
    font-size: 14px;
    font-weight: bold;
    color: #f0f9f9;
    text-align: center;
    text-shadow: 1px 1px 1px #000;
    background:#1f1f1f;
  }
  #map_canvas, #rotation_control {
    margin: 1px;
    border:1px solid #000;
    background:#444;
    -webkit-border-radius: 4px;
       -moz-border-radius: 4px;
            border-radius: 4px;
  }
  #map_canvas { 
    width: 100%;
    height: 360px;
  }
  #rotation_control { 
    width: auto;
    padding:5px;
  }
  #rotation_value { 
    margin: 1px;
    border:1px solid #999;
    width: 60px;
    padding:2px;
    font-weight: bold;
    color: #00cc00;
    text-align: center;
    background:#111;
    border-radius: 4px;
  }
Run Code Online (Sandbox Code Playgroud)

Javascript(以简单的香草味理解核心概念)

var map, arrow_marker, arrow_options;
var map_center = {lat:41.0, lng:-103.0};
var arrow_icon = {
  path: 'M -1.1500216e-4,0 C 0.281648,0 0.547084,-0.13447 0.718801,-0.36481 l 17.093151,-22.89064 c 0.125766,-0.16746 0.188044,-0.36854 0.188044,-0.56899 0,-0.19797 -0.06107,-0.39532 -0.182601,-0.56215 -0.245484,-0.33555 -0.678404,-0.46068 -1.057513,-0.30629 l -11.318243,4.60303 0,-26.97635 C 5.441639,-47.58228 5.035926,-48 4.534681,-48 l -9.06959,0 c -0.501246,0 -0.906959,0.41772 -0.906959,0.9338 l 0,26.97635 -11.317637,-4.60303 c -0.379109,-0.15439 -0.812031,-0.0286 -1.057515,0.30629 -0.245483,0.33492 -0.244275,0.79809 0.0055,1.13114 L -0.718973,-0.36481 C -0.547255,-0.13509 -0.281818,0 -5.7002158e-5,0 Z',
  strokeColor: 'black',
  strokeOpacity: 1,
  strokeWeight: 1,
  fillColor: '#fefe99',
  fillOpacity: 1,
  rotation: 0,
  scale: 1.0
};

function init(){
  map = new google.maps.Map(document.getElementById('map_canvas'), {
    center: map_center,
    zoom: 4,
    mapTypeId: google.maps.MapTypeId.HYBRID
  });
  arrow_options = {
    position: map_center,
    icon: arrow_icon,
    clickable: false,
    draggable: true,
    crossOnDrag: true,
    visible: true,
    animation: 0,
    title: 'I am a Draggable-Rotatable Marker!' 
  };
  arrow_marker = new google.maps.Marker(arrow_options);
  arrow_marker.setMap(map);
}

function setRotation(){
  var heading = parseInt(document.getElementById('rotation_value').value);
  if (isNaN(heading)) heading = 0;
  if (heading < 0) heading = 359;
  if (heading > 359) heading = 0;
  arrow_icon.rotation = heading;
  arrow_marker.setOptions({icon:arrow_icon});
  document.getElementById('rotation_value').value = heading;
}
Run Code Online (Sandbox Code Playgroud)

最好的办法是,以这种方式确保标记是Google MVC对象,并为它提供MVC对象提供的所有其他方法。

如果您必须使用彩色图像作为标记,请创建一个.png精灵表,并以您希望显示的所有角度呈现该图像,然后根据计算出的方位角有问题地选择要使用的正确图像您正在使用的两点之间。但是,这不是SVG图像,而是常规标记图像。

希望这有助于做出有关地图标记的决策。


Jes*_*ela 5

如何在Google地图V3上旋转图像(标记图像)?

我有同样的问题,我用下一个代码解决了它:

var gmap;
NgMap.getMap(function(map){
    gmap = map;
});
Run Code Online (Sandbox Code Playgroud)

我想你有一个带图标的变量,例如:

var imagePath = 'img/customMarker.png';
Run Code Online (Sandbox Code Playgroud)

首先,我们需要创建标记选项:

var markerOptions = {
    location: [x, y],
    title:'some text',
    draggable: true,
    .
    .
    .
    icon: imagePath
};
Run Code Online (Sandbox Code Playgroud)

让我们创建一个标记:

var marker = new google.maps.Marker(markerOptions);
Run Code Online (Sandbox Code Playgroud)

我们必须设置地图:

marker.setMap(map);
Run Code Online (Sandbox Code Playgroud)

现在,如果要旋转图像,则需要执行下一步操作:

  • 将imagePath变量的值更改为'img/customMarker.png#yourId'
  • 用css设置旋转值(例如用JQuery)

让我们来看看

imagePath = 'img/customMarker.png#markerOne';

$('img[src="img/customMarker.png#markerOne"]').css({
     'transform': 'rotate(45deg)'
});
Run Code Online (Sandbox Code Playgroud)

当然你可以做得更漂亮:

function rotateMarker(selector, degree){
     $('img[src="img/customMarker.png#'+selector+'"]').css({
         'transform': 'rotate('+degree+'deg)'
     });
}
Run Code Online (Sandbox Code Playgroud)

你的电话:

rotateMarker('markerOne', 45);
Run Code Online (Sandbox Code Playgroud)

就这样.

我希望它可以有所帮助.


Rya*_*pel 5

没有人提到使用预先旋转的图标。根据您的应用程序,您可以选择一个图标并将其旋转 +10 度、+20 度...+350 度,而不是旋转标记本身,只需为其指定不同的图标 - 如果 10 度分辨率较好,则为 36 中的一个足够的。这对客户的资源也非常少。

在下面的示例中,我生成了 36 个图标,每个图标都旋转了 10 度。它们的名称是:icon0.png、 icon10.png、 icon20.png、... icon340.png、 icon350.png、 icon360.png。0 和 360 是完全相同的图标(例如符号链接)

var rotation = 123 // degrees
var iconName = "icon" + (Math.round(rotation/10)*10).toString() + ".png"
var marker = new google.maps.Marker({
    icon: iconName
})
Run Code Online (Sandbox Code Playgroud)