2015-10-28 43 views
1

我知道这里有几个关于缩放<image>的问题,并且按照所述元素的中心排序,但我有一个稍微不同的问题。SVG pattern无转换的转换比例图像

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

我已经尝试列出的链接
X = CENTREX *的here (Transforming Coordinate system)

摘要(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事件,随着规模变大> 2,它开始变得狂野。
Oddity

回答

2

独自离开这几天后,我终于明白了。

<pattern>居中的<image>的方式是不尝试和(逻辑)使用<image>上,但,实际上使用<pattern>上立足translate立足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属性通过拖放目的另一个功能设置。