【发布时间】:2021-03-19 13:16:15
【问题描述】:
我想控制 SVG 在浏览器中的位置(视口?)
我正在使用某种地图 API。所以我想将 SVG 图像添加到地图中。
但是有一个问题是我无法应用 SVG 图像的绝对位置。
当我使用 Canvas 时,它工作得很好。
我认为改变协调时有错误。
使用画布:它工作正常。 // 创建画布元素
function GroundOverlay(bounds) {
this.bounds = bounds;
this.node = document.createElement("canvas");
//this.node.style.backgroundColor = "yellow";
//this.node.style.opacity = "0.5";
this.node.style.position = "absolute";
this.node.style.border = "1px solid red";
this.node.width = 300;
this.node.height = 200;
this.node.style.zIndex = 3;
this.ctx = this.node.getContext("2d");
this.width = 300;
this.height = 10;
this.startX = 0;
this.startY = 100;
this.ctx.translate(200, 30);
this.ctx.rotate((31.5 * Math.PI) / -180);
this.ctx.translate(-225, -69);
// calculate gradient line based on angle
this.x1 = 60;
this.y1 = 10;
this.x2 = this.x1 + Math.cos(31.5) * 600;
this.y2 = this.y1 + Math.sin(31.5) * 600;
this.gradientUp = this.ctx.createLinearGradient(this.x1, this.y1, this.x2, this.y2);
this.gradientUp.addColorStop(0, "grey");
this.gradientUp.addColorStop(1, "rgba(0, 0, 255, 0.5)");
this.ctx.fillStyle = this.gradientUp;
this.ctx.fillRect(this.startX, this.startY, this.width, this.height);
}
GroundOverlay.prototype = new kakao.maps.AbstractOverlay();
GroundOverlay.prototype.onAdd = function() {
var panel = this.getPanels().overlayLayer;
panel.appendChild(this.node);
};
// when event happend (zoom, center, mapType)
// location of element is changed.
GroundOverlay.prototype.draw = function() {
var projection = this.getProjection();
var ne = projection.pointFromCoords(this.bounds.getNorthEast());
var sw = projection.pointFromCoords(this.bounds.getSouthWest());
var width = ne.x - sw.x;
var height = sw.y - ne.y;
this.node.style.top = ne.y + "px";
this.node.style.left = sw.x + "px";
this.node.style.width = width + "px";
this.node.style.height = height + "px";
};
使用 SVG:当事件发生时,位置不是绝对的
function GroundOverlay(bounds) {
this.bounds = bounds;
this.node = document.createElement("div");
this.node.style.position = "absolute";
this.svg1 = document.createElementNS("http://www.w3.org/2000/svg", "svg");
this.svg1.setAttribute("position", "absolute");
this.svg1.style.position = "absolute";
// create a circle
this.cir1 = document.createElementNS("http://www.w3.org/2000/svg", "circle");
this.cir1.style.position = "absolute";
this.cir1.setAttribute("cx", "80");
this.cir1.setAttribute("cy", "80");
this.cir1.setAttribute("r", "30");
this.cir1.setAttribute("fill", "red");
this.cir1.setAttribute("position", "absolute");
// attach it to the container
this.svg1.appendChild(this.cir1);
// attach container to document
this.node.appendChild(this.svg1);
}
GroundOverlay.prototype = new kakao.maps.AbstractOverlay();
GroundOverlay.prototype.onAdd = function() {
var panel = this.getPanels().overlayLayer;
panel.appendChild(this.node);
};
GroundOverlay.prototype.draw = function() {
var projection = this.getProjection();
var ne = projection.pointFromCoords(this.bounds.getNorthEast());
var sw = projection.pointFromCoords(this.bounds.getSouthWest());
var width = ne.x - sw.x;
var height = sw.y - ne.y;
this.node.style.top = ne.y + "px";
this.node.style.left = sw.x + "px";
this.node.style.width = width + "px";
this.node.style.height = height + "px";
};
svg(circle): 不能是绝对位置
https://s8.gifyu.com/images/marker1.gif
canvas(square): 可以是绝对位置
https://s8.gifyu.com/images/marker2.gif
我试过这种方式(https://www.sitepoint.com/how-to-translate-from-dom-to-svg-coordinates-and-back-again/)
-
强调 svgPoint
-
将此点更改为顶部,浏览器的左侧
GroundOverlay.prototype.draw = function() {
var projection = this.getProjection(); var ne = projection.pointFromCoords(this.bounds.getNorthEast()); var sw = projection.pointFromCoords(this.bounds.getSouthWest()); var width = ne.x - sw.x; var height = sw.y - ne.y; this.node.style.top = ne.y + "px"; this.node.style.left = sw.x + "px"; this.node.style.width = width + "px"; this.node.style.height = height + "px"; var pt = this.svg1.createSVGPoint(); pt.x = sw.x; pt.y = ne.y; };
【问题讨论】:
-
正确,SVG 不能那样工作。
-
将整个 SVG 直接放置在与图像尺寸相同的图像顶部。现在您不再需要绝对定位,因为所有点都是相对于图像的。
标签: javascript html svg canvas