SVG模式转换缩放图像而不翻译

时间:2015-10-28 16:07:22

标签: javascript svg

我知道这里有几个关于缩放<image>并对所述元素的中心进行排序的问题,但我的问题略有不同。

我的问题是我有一个<pattern>,其中包含我的<image>,因为它动态应用于其他SVG。我使用patternTransform属性来缩放图像并使用矩阵(而不是单独的变换)转换图像。我需要围绕图像的中心缩放图像,尽管我的理解是<pattern>是它的内容的无限画布。

我尝试了here (Transforming Coordinate system)

概述的技术

链接摘要
X = centreX *(scale_factor -1)
Y = centreY *(scale_factor -1)

它确实对图像的翻译方式产生了影响,但原点看起来更像是从左上角开始约15%而不是谚语<image>的中心。

当图片位于<pattern>内并用作fill时,如何在不翻译图像的情况下缩放图像?

以下是我用于缩放图片的代码以及它的行为方式的gif。

模式定义

<pattern id="user_image_container" patternUnits="objectBoundingBox" x="0" y="0">
  <image xlink:href="https://upload.wikimedia.org/wikipedia/commons/8/8a/Free_Unedited_Happy_Little_Yellow_Stars_in_Pink_Flower_Creative_Commons_(2898759838).jpg" id="user_image"></image>
</pattern>

控制矩阵的Javascript

/**
 * Scale the image. Called by an input event from an input[type="range"]
 * @param  {Event} event calling this function.
 * @return {void}
 */
update_image_scale: function update_image_scale(event) {
  // Stop anything automatic from happening.
  event.preventDefault()

  // Get the input and previous value.
  const target_input = $(event.target)
  const target_size = parseFloat(target_input.val())
  const image_size = App.canvas_view.image_size // Original size of the image.

  // Get the target <pattern>.
  const target_image = $("#user_image_container").get(0)

  // Get the centred X/Y position of the image.
  const cx = parseFloat(target_image.getAttribute("data-x") || 0) + (image_size.width / 2)
  const cy = parseFloat(target_image.getAttribute("data-y") || 0) + (image_size.height / 2)

  // Get the new translation position.
  const x = -cx * (target_size - 1)
  const y = -cy * (target_size - 1)

  console.log(x, y)

  // Set the new X/Y position.
  target_image.setAttribute("data-x", x)
  target_image.setAttribute("data-y", y)

  // Redraw the image.
  $("#user_image_container").get(0).setAttribute("patternTransform", `matrix(${target_size} 0 0 ${target_size} ${x} ${y})`)
},

此处此刻表现如何(对于大型GIF而言):
  这是通过input[type="range"] input事件控制的,当比例变为&gt;时,它开始变得狂野。 2.
Oddity

1 个答案:

答案 0 :(得分:2)

单独离开这几天后,我终于怀疑了。

<image>置于<pattern>中心的方法是不尝试(逻辑上)使用<image>基于translate,但事实上使用<pattern>基于translate

  /**
   * Scale the image.
   * @param  {Event} event calling this function.
   * @return {void}
   */
  update_image_scale: function update_image_scale(event) {
    // Stop anything automatic from happening.
    event.preventDefault()

    // Get the mask dimensions.
    const mask_container_size = $("#image_mask").get(0).getBBox()

    // Get the target image.
    const target_image = $("#user_image_container").get(0)

    // Get the input and previous value.
    const target_size = parseFloat($(event.target).val())

    // Get the new translation position.
    const x = (-mask_container_size.width / 2) * (target_size - 1)
    const y = (-mask_container_size.height / 2) * (target_size - 1)

    // Set the new X/Y position.
    target_image.setAttribute("data-scale-x", x)
    target_image.setAttribute("data-scale-y", y)

    // Redraw the image.
    global.App.canvas_view.render_image_in_pattern()
  }

矩阵控制器现在是单独的变换。

  /**
   * Render the image with all transforms.
   * @return {void}
   */
  render_image_in_pattern: function render_image_in_pattern() {
    // Get the target image.
    const target = this.$("#user_image_container").get(0)

    // Get the image coordinates.
    const sx = parseFloat(target.getAttribute("data-scale-x")) || 0
    const sy = parseFloat(target.getAttribute("data-scale-y")) || 0
    const x = parseFloat(target.getAttribute("data-x")) || 0
    const y = parseFloat(target.getAttribute("data-y")) || 0

    // Get the rotation.
    const r = this.rotation || 0

    // Get the scale from the range field.
    const s = $(".image-scaler").val()

    // Translate the image.
    $("#user_image_container").get(0)
      .setAttribute("patternTransform", `translate(${sx} ${sy}) rotate(${r}) scale(${s}) translate(${x} ${y})`)
  },

data-xdata-y属性由另一个函数设置,用于拖放。