首先,想法是在隐藏的画布上绘制旋转的标记图像。
假设您有一个隐藏的画布:
<canvas id="carCanvas" width="50" height="50" style="display:none"></canvas>
现在,您可以这样做:
function updateCarMarker(i,lat, lng, icon = "img/carIcon.png") {
var latLong = new google.maps.LatLng(lat, lng);
if (!carMarkers[i]){
var carImage = new Image();
carImage.onload = ()=>{
drawMovedCar(i,latLong,carImage);
}
carImage.src=icon;
} else {
drawMovedCar(i,latLong,carMarkers[i].carImage);
}
}
function drawMovedCar(i,latLong,I){
let m=carMarkers[i];
let canvas = document.getElementById("carCanvas");
let C = canvas.getContext('2d');
if (m){
var distance = google.maps.geometry.spherical.computeDistanceBetween(
m.getPosition(), latLong);
var deg = (distance<2)?carMarkers[i].deg
:google.maps.geometry.spherical.computeHeading(m, latLong);
carMarkers[i].setMap(null);
} else {
var deg=0;
}
C.save();
C.clearRect(0, 0, canvas.width, canvas.height);
C.translate(canvas.width/2,canvas.height/2);
C.rotate(deg * Math.PI / 180);
C.scale(0.4,0.4);
C.drawImage(I,-I.width/2,-I.height/2,I.width,I.height);
C.restore();
if (!m){
m = new google.maps.Marker({
position: latLong,
map: map,
icon: canvas.toDataURL("image/png",1)
});
m.deg = deg;
m.carImage = I;
carMarkers[i]=m;
} else {
m.setIcon(canvas.toDataURL("image/png",1));
m.setPosition(latLong);
}
}
var ico = document.createElement('img');
ico.src = 'ImageSource';
ico.setAttribute('style', 'transform:rotate('30deg);');
mapMarkers[0].labelContent = ico;
mapMarkers[0].label.draw();
let marker_, svg_, size_ = 100, rotation_ = 50
// Get SVG
fetch('https://upload.wikimedia.org/wikipedia/commons/7/78/Space-shuttle.svg')
.then(response => response.text())
.then(text => {
svg_ = text;
svg_ = svg_
.replace(/^<\?(.+)\?>$/gm, '') // unsupported unnecessary line
// You can replace anything you want, but first of all check your svg code
.replace(/width.+\Wheight\S+/,
'width="{{width}}" height="{{height}}" transform="{{transform}}" ')
// Load Map
initMap()
})
function getIcon(rotation){
return {url:`data:image/svg+xml;charset=utf-8,
${encodeURIComponent(svg_
.replace('{{width}}', 100)
.replace('{{height}}', 100)
.replace('{{transform}}', `rotate(${rotation},0,0)`))}`,anchor: new google.maps.Point(50, 50),
origin: new google.maps.Point(0, 0)}
}
// Map
function initMap() {
const position = {lat: 36.720426, lng: -4.412573};
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 19,
center: position
})
marker_ = new google.maps.Marker({
position: position,
map: map,
icon: getIcon(rotation_)
})
}
// Change rotation
$input_ = document.querySelector('input')
$input_.value = rotation_
$input_.onchange = () => {
marker_.setIcon(getIcon(parseInt($input_.value))
)
}
* {
padding: 0;
margin: 0;
}
#map {
width: 100%;
height: 100vh;
}
input {
position: fixed;
z-index: 1;
margin: 100px;
padding: 10px;
border-radius: 2px;
background-color: red;
border: none;
color: white;
font-family: 'Roboto';
width: 70px;
}
<script src="https://maps.google.com/maps/api/js"></script>
<input type="number" placeholder="rotation">
<div id="map"></div>
bearing = 20
document.querySelectorAll('img[src="/images/imageName"]').forEach((node) => {
node.style['transform'] = `rotate(${bearing}deg)`
node.style['webkitTransform'] = `rotate(${bearing}deg)`
node.style['MozTransform'] = `rotate(${bearing}deg)`
node.style['msTransform'] = `rotate(${bearing}deg)`
node.style['OTransform'] = `rotate(${bearing}deg)`
})
imageName
应该面向北方。我找到了一种简单的方法来旋转Google标记的PNG图像标记。通过创建一个自定义标记覆盖google.maps.OverlayView并使用CSS/内联样式轻松旋转图像。
export const createCustomMarker = ({ OverlayView = google.maps.OverlayView, ...args }) => {
class GoogleMarker extends OverlayView {
options: any = {};
div: any = null;
innerHtml: any = null;
constructor(options) {
super();
this.options = options;
this.setMap(options.map);
}
createDiv() {
const options = this.options;
this.div = document.createElement('div');
this.div.style.position = 'absolute';
this.setRotation(this.options.rotation);
if (options.icon) {
this.setInnerHtml(this.getInnerImageHtml(options));
}
}
getInnerImageHtml(options) {
const size = this.getSize(options);
const label = this.options.label;
const labelHtml = label ? `<span style="color:black;margin-left: -40px;width: 100px;text-align: center;display: block;font-weight:bold;">${label}</span>` : "";
return `<img style="height:${size.height}px;width:${size.width}px" id="${options.id || ''}" src="${options.icon}">${labelHtml}`;
}
addListeners() {
const self = this;
google.maps.event.addDomListener(this.div, 'click', event => {
google.maps.event.trigger(self, 'click');
});
this.div.onmouseenter = function () {
debugger
google.maps.event.trigger(self, 'onmouseenter');
}
this.div.onmouseover = function () {
google.maps.event.trigger(self, 'onmouseover');
}
this.div.onmouseleave = function () {
google.maps.event.trigger(self, 'onmouseleave');
}
this.div.onmouseout = function () {
google.maps.event.trigger(self, 'onmouseout');
}
}
appendDivToOverlay(appendDiv: any) {
const panes: google.maps.MapPanes = this.getPanes();
panes.floatPane.appendChild(appendDiv);
}
setRotation(degrees: number) {
if (this.div) {
this.div.style.transform = 'rotate(' + degrees + 'deg)';
}
this.options.rotation = degrees;
}
getRotation() {
return this.options.rotation;
}
setInnerHtml(html: string) {
this.innerHtml = html;
this.div.innerHTML = this.innerHtml;
}
private positionDiv(div: any, options: any) {
if (div != null) {
const point = this.getProjection().fromLatLngToDivPixel(options.latlng);
if (point) {
const size = this.getSize(options);
const anchor = options.anchor ? options.anchor : new google.maps.Point((size.width / 2), (size.height / 2))
const leftAnchor = anchor.x;
const topAnchor = anchor.y;
div.style.left = `${point.x - leftAnchor}px`;
div.style.top = `${point.y - topAnchor}px`;
}
}
}
private getSize(options) {
const size = options.size || { height: 52, width: 52 };
return size;
}
draw() {
if (!this.div) {
this.createDiv();
this.appendDivToOverlay(this.div);
this.addListeners();
}
this.positionDiv(this.div, this.options);
}
remove() {
if (this.div) {
this.div.parentNode.removeChild(this.div);
this.div = null;
}
}
setVisible(value: boolean) {
if (this.div) {
this.div.style["display"] = value ? "block" : "none";
}
}
getVisible() {
if (this.div) {
return this.div.style["display"] == "none";
}
return false;
}
setPosition(position) {
this.options.latlng = position;
this.infoOptions.latlng = position;
this.positionDiv(this.div, this.options);
}
getPosition() {
return this.options.latlng;
}
getDraggable() {
return false;
}
isHTML(html: string) {
return /<([A-Za-z][A-Za-z0-9]*)\b[^>]*>(.*?)<\/\1>/.test(html);
}
}
return new GoogleMarker(args)
}
创建此自定义标记后,按以下方式初始化标记。import { createCarMarker } from "./marker.component"; // dynamic path to component
let marker = createCarMarker({
id: id, // will add id to the parent container div
latlng: new google.maps.LatLng(0, 0), // replace latitude-longitude with your values
map: this.map,
size: new google.maps.Size(52, 52), // replace the image size with your values
rotation: markerData.direction, // Provide values in degrees
icon: iconUrl, // Replace it with your image url
label: markerLabel // Provide marker label. Optional field
});
现在只需使用以下方法旋转标记
marker.setRotation(180); // You just need to call only this method every-time the degrees changes.
监听标记的变化。
google.maps.event.addDomListener(marker, 'click', function (event) {
});
google.maps.event.addListener(marker, 'onmouseenter', function (event) {
});
google.maps.event.addListener(marker, 'onmouseleave', function (event) {
});
google.maps.event.addListener(marker, 'onmouseover', function (event) {
});
google.maps.event.addListener(marker, 'onmouseout', function (event) {
});
您可以根据需要自定义监听器或在自定义标记类中添加新的/更新。
var icon = {
path: aeroplanePath/image,
fillColor: '#0000FF',
fillOpacity: .6,
anchor: new google.maps.Point(0,0),
strokeWeight: 0,
scale: 1,
rotation: 180
}
var marker = new google.maps.Marker({
position: positions[k],
icon: icon,
draggable: true,
title: "BOING-707",
});