简体   繁体   English

如何缩放HTML5画布,但不缩放标记图像,又如何将它们显示在正确的位置?

[英]How can I scale an HTML5 Canvas but not scale marker images and still have them show up in the right place?

I'm successfully scaling an HTML5 canvas with a rendering of a world map. 我成功地缩放了HTML5画布并绘制了世界地图。 I have located certain cities on the map and indicated them with a marker that is placed using the drawImage method on the 2d context. 我已经在地图上找到了某些城市,并使用了drawImage方法在2d上下文中放置了一个标记来指示它们。 When I scale the map the markers are also scaled, and they are correctly placed. 当我缩放地图时,标记也会被缩放,并正确放置它们。 If I try to NOT scale the marker images then they don't follow the positional scaling that the rest of the map has had applied. 如果我尝试不缩放标记图像,则它们将不遵循地图其余部分已应用的位置缩放。

I would like the image markers to remain the same size, regardless of zoom factor and also be placed correctly. 我希望图像标记可以保持相同大小,而不管缩放系数如何,并且也可以正确放置。 Is there a way to calculate the translated point and then use that point for drawImage so I can correctly place the marker? 有没有一种方法可以计算平移点,然后将该点用于drawImage,以便我可以正确放置标记?

At first guess I think you would have at least two g's in your svg. 乍一看,我认为您的svg中至少要有2 g。 The first would be scaled for map stuff. 第一个将针对地图内容进行缩放。 The second would be for your markers. 第二个是您的标记。 You would convert the map coordinates for markers into the scale for the latter and then place your markers there. 您可以将标记的地图坐标转换为后者的比例,然后将标记放置在那里。 The basic deal is that you can apply transforms to not just the whole svg but to pieces of it, to deal with problems like this. 基本的处理方法是,您不仅可以将转换应用于整个svg,还可以应用于其中的各个部分,以处理此类问题。

A generic answer as no code was provided - 通用答案,因为未提供代码-

  • As you suggest yourselves keep the points stored as just points. 正如您建议的那样,自己将点保存为点。
  • Use a scale factor in code rather than using the scale() method. 在代码中使用比例因子,而不要使用scale()方法。
  • Use drawImage with manually set scale for width and height 使用drawImage并手动设置宽度和高度的比例
  • Draw the points using the scale factor 使用比例因子绘制点

The reason for doing this manually is that you get in control of each part of the elements drawn. 手动执行此操作的原因是您可以控制所绘制元素的每个部分。 Using a transformed canvas means you will in any case scale down the points manually. 使用变形的画布意味着无论如何您都将手动缩小点数。

But since you first scale everything up then draw the points at a different size the up-scaled version of the graphics will be the basis for the changed size which gives worst result quality-wise. 但是,由于您首先将所有内容按比例放大,然后以不同的大小绘制点,所以图形的按比例放大版本将成为更改尺寸的基础,从而导致质量最差的结果。

And since you rely on the internal scale factor you need to provide mechanisms to track the scale and changes to it as well making sure it's all synchronized. 而且,由于您依赖内部比例因子,因此需要提供跟踪比例和对其进行更改的机制,并确保它们都已同步。

The better way, IMO, is to do all steps manually - and it is simple - IMO更好的方法是手动执行所有步骤-很简单-

Here is one way you can do it (simplified): 这是一种简化的方法:

Store the points in an array as for example objects: 将点存储在数组中,例如对象:

var points = [{x:10, y:10}, {x: 100, y:100}, ...]; /// etc.

Then keep a scale factor you want to use (requirement is that scale is > 0): 然后保留您要使用的比例因子(要求比例> 0):

var scale = 1.5; /// scale (up or down 1 = 1:1, 0.5 = 50%, 2 = 200% etc.

If you want to be able to translate the map add variables for that as well: 如果您希望能够翻译地图,请为此添加变量:

var dx = 0;      /// delta X (translation)
var dy = 0;      /// delta Y

Then draw the map scaled (incl. translation): 然后按比例绘制地图(包括翻译):

ctx.drawImage(map, dx, dy, width * scale, height * scale);

Then the points: 然后要点:

for(var i = 0, p = points; p = points[i++];)
    ctx.fillRect(dx + p.x * scale, dy + p.y * scale, 10, 10);

For mouse clicks you do the same, just "reverse" the math: 对于鼠标单击,您可以执行相同的操作,只需“逆向”数学即可:

var pos = getMousePosition();  /// pseudo method, get mouse pos somehow
var x = (pos.x - dx) / scale;
var y = (pos.y - dx) / scale;

Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM