水平翻转 SVG 中的元素但保持其原始位置
flip an element inside SVG horizontally but keeps it's original position
我想在不改变原始位置的情况下翻转 SVG 元素(路径、线条、多段线、文本...)。例如
<div id="canvas" style="width: 550px; height: 550px">
<svg version="1.2" baseProfile="tiny" id="Logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 250 250" xml:space="preserve">
<text id="text" transform="matrix(1 0 0 1 31.1271 199.1222)" fill="#561010" font-family="'Roboto-Regular'" font-size="25.3945px">Nom d’entreprise</text>
<g>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="76.157" y1="87.0921" x2="70.9488" y2="44.8529"> <stop offset="0.0233" style="stop-color:#E92460"></stop> <stop offset="0.4636" style="stop-color:#F05C4B"></stop> <stop offset="0.9517" style="stop-color:#F36D38"></stop> </linearGradient>
<path transform="matrix(1 0 0 1 0 0)" fill="url(#SVGID_2_)" d="M51.75,55.77c-0.27-0.39,3.97-5.2,10.38-7.74c1.79-0.71,11.97-4.75,21.31,0.8
c8.61,5.12,11.99,15.71,10.53,24.27c-2.38,13.95-17.76,23.37-22.24,20.72c-0.97-0.57-1.32-2.75-1.99-7.09
c-1.81-11.84-1.68-20.54-1.68-20.54c0.05-3.05,0.19-4.38-0.61-6.25c-1.42-3.32-4.9-6.23-8.62-6.47
C54.84,53.21,51.97,56.08,51.75,55.77z"></path>
</g>
</svg>
</div>
我尝试了各种解决方案,例如将 transform
更改为 matrix(-1 0 0 1 -100 0)
。我也尝试添加属性 transform-origin="center"
.
我得到的只是一个放错地方的元素。我一直在尝试以下操作:
flipHorizontal(){
let viewBox_array = this.getViewBox(); // this returns ['0', '0', '250', '250']
let canvas_width = $("#canvas").width();
this.selectedElements.forEach(element =>{
let element_width = element.getBoundingClientRect().width
element.setAttribute("transform-origin", "center")
var matrix = element.transform.baseVal[0].matrix;
matrix.a = (-1) * matrix.a
let diff = (element_width / (canvas_width / Number(viewBox_array[2])) )* Math.sign(matrix.a);
matrix.e += diff;
});
this.edit_done();
}
也尝试了以下
flipHorizontal(){
this.selectedElements.forEach(element =>{
element.setAttribute("transform-origin", "center")
let bbox = element.getBBox();
var matrix = element.transform.baseVal[0].matrix;
matrix.a = (-1) * matrix.a
matrix.e += Math.sign(matrix.a) * (bbox.width + bbox.x);
});
this.edit_done();
}
您可以使用唯一的 CSS 执行此操作,例如:
.logo_text--flipped, .logo_image--flipped {
transform-origin: center center;
transform: scaleX(-1);
}
<div id="canvas" style="width: 550px; height: 550px">
<svg version="1.2" baseProfile="tiny" id="Logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 250 250" xml:space="preserve">
<g class="logo_text logo_text--flipped">
<text id="text" transform="matrix(1 0 0 1 31.1271 199.1222)" fill="#561010" font-family="'Roboto-Regular'" font-size="25.3945px">Nom d’entreprise</text>
</g>
<g class="logo_image logo_image--flipped">
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="76.157" y1="87.0921" x2="70.9488" y2="44.8529">
<stop offset="0.0233" style="stop-color:#E92460"></stop>
<stop offset="0.4636" style="stop-color:#F05C4B"></stop>
<stop offset="0.9517" style="stop-color:#F36D38"></stop>
</linearGradient>
<path transform="matrix(1 0 0 1 0 0)" fill="url(#SVGID_2_)" d="M51.75,55.77c-0.27-0.39,3.97-5.2,10.38-7.74c1.79-0.71,11.97-4.75,21.31,0.8
c8.61,5.12,11.99,15.71,10.53,24.27c-2.38,13.95-17.76,23.37-22.24,20.72c-0.97-0.57-1.32-2.75-1.99-7.09
c-1.81-11.84-1.68-20.54-1.68-20.54c0.05-3.05,0.19-4.38-0.61-6.25c-1.42-3.32-4.9-6.23-8.62-6.47
C54.84,53.21,51.97,56.08,51.75,55.77z"></path>
</g>
</svg>
</div>
因此您可以创建一个特定的 class 并通过 JS 切换它
如my answer here中所述,原地翻转所需的变换函数为:
translate(<minX+maxX>,0) scale(-1, 1)
因此,您的代码的工作版本可能如下所示:
function flipHorizontal(selectedElements) {
selectedElements.forEach(element => {
// Get the bounds of the element
let bbox = element.getBBox();
// Get the current transform attribute (if any) of the element
let currentTransform = element.getAttribute("transform") || "";
// Append translate and scale functions to the transform that will flip the element in place
element.setAttribute("transform", currentTransform + ' translate('+(bbox.x + bbox.x + bbox.width) + ',0) scale(-1, 1)');
});
}
let elementsToFlip = document.querySelectorAll("path, text");
flipHorizontal( elementsToFlip );
<div id="canvas" style="width: 550px; height: 550px">
<svg version="1.2" baseProfile="tiny" id="Logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 250 250" xml:space="preserve">
<text id="text" transform="matrix(1 0 0 1 31.1271 199.1222)" fill="#561010" font-family="'Roboto-Regular'" font-size="25.3945px">Nom d’entreprise</text>
<g>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="76.157" y1="87.0921" x2="70.9488" y2="44.8529"> <stop offset="0.0233" style="stop-color:#E92460"></stop> <stop offset="0.4636" style="stop-color:#F05C4B"></stop> <stop offset="0.9517" style="stop-color:#F36D38"></stop> </linearGradient>
<path transform="matrix(1 0 0 1 0 0)" fill="url(#SVGID_2_)" d="M51.75,55.77c-0.27-0.39,3.97-5.2,10.38-7.74c1.79-0.71,11.97-4.75,21.31,0.8
c8.61,5.12,11.99,15.71,10.53,24.27c-2.38,13.95-17.76,23.37-22.24,20.72c-0.97-0.57-1.32-2.75-1.99-7.09
c-1.81-11.84-1.68-20.54-1.68-20.54c0.05-3.05,0.19-4.38-0.61-6.25c-1.42-3.32-4.9-6.23-8.62-6.47
C54.84,53.21,51.97,56.08,51.75,55.77z"></path>
</g>
</svg>
</div>
我想在不改变原始位置的情况下翻转 SVG 元素(路径、线条、多段线、文本...)。例如
<div id="canvas" style="width: 550px; height: 550px">
<svg version="1.2" baseProfile="tiny" id="Logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 250 250" xml:space="preserve">
<text id="text" transform="matrix(1 0 0 1 31.1271 199.1222)" fill="#561010" font-family="'Roboto-Regular'" font-size="25.3945px">Nom d’entreprise</text>
<g>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="76.157" y1="87.0921" x2="70.9488" y2="44.8529"> <stop offset="0.0233" style="stop-color:#E92460"></stop> <stop offset="0.4636" style="stop-color:#F05C4B"></stop> <stop offset="0.9517" style="stop-color:#F36D38"></stop> </linearGradient>
<path transform="matrix(1 0 0 1 0 0)" fill="url(#SVGID_2_)" d="M51.75,55.77c-0.27-0.39,3.97-5.2,10.38-7.74c1.79-0.71,11.97-4.75,21.31,0.8
c8.61,5.12,11.99,15.71,10.53,24.27c-2.38,13.95-17.76,23.37-22.24,20.72c-0.97-0.57-1.32-2.75-1.99-7.09
c-1.81-11.84-1.68-20.54-1.68-20.54c0.05-3.05,0.19-4.38-0.61-6.25c-1.42-3.32-4.9-6.23-8.62-6.47
C54.84,53.21,51.97,56.08,51.75,55.77z"></path>
</g>
</svg>
</div>
我尝试了各种解决方案,例如将 transform
更改为 matrix(-1 0 0 1 -100 0)
。我也尝试添加属性 transform-origin="center"
.
我得到的只是一个放错地方的元素。我一直在尝试以下操作:
flipHorizontal(){
let viewBox_array = this.getViewBox(); // this returns ['0', '0', '250', '250']
let canvas_width = $("#canvas").width();
this.selectedElements.forEach(element =>{
let element_width = element.getBoundingClientRect().width
element.setAttribute("transform-origin", "center")
var matrix = element.transform.baseVal[0].matrix;
matrix.a = (-1) * matrix.a
let diff = (element_width / (canvas_width / Number(viewBox_array[2])) )* Math.sign(matrix.a);
matrix.e += diff;
});
this.edit_done();
}
也尝试了以下
flipHorizontal(){
this.selectedElements.forEach(element =>{
element.setAttribute("transform-origin", "center")
let bbox = element.getBBox();
var matrix = element.transform.baseVal[0].matrix;
matrix.a = (-1) * matrix.a
matrix.e += Math.sign(matrix.a) * (bbox.width + bbox.x);
});
this.edit_done();
}
您可以使用唯一的 CSS 执行此操作,例如:
.logo_text--flipped, .logo_image--flipped {
transform-origin: center center;
transform: scaleX(-1);
}
<div id="canvas" style="width: 550px; height: 550px">
<svg version="1.2" baseProfile="tiny" id="Logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 250 250" xml:space="preserve">
<g class="logo_text logo_text--flipped">
<text id="text" transform="matrix(1 0 0 1 31.1271 199.1222)" fill="#561010" font-family="'Roboto-Regular'" font-size="25.3945px">Nom d’entreprise</text>
</g>
<g class="logo_image logo_image--flipped">
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="76.157" y1="87.0921" x2="70.9488" y2="44.8529">
<stop offset="0.0233" style="stop-color:#E92460"></stop>
<stop offset="0.4636" style="stop-color:#F05C4B"></stop>
<stop offset="0.9517" style="stop-color:#F36D38"></stop>
</linearGradient>
<path transform="matrix(1 0 0 1 0 0)" fill="url(#SVGID_2_)" d="M51.75,55.77c-0.27-0.39,3.97-5.2,10.38-7.74c1.79-0.71,11.97-4.75,21.31,0.8
c8.61,5.12,11.99,15.71,10.53,24.27c-2.38,13.95-17.76,23.37-22.24,20.72c-0.97-0.57-1.32-2.75-1.99-7.09
c-1.81-11.84-1.68-20.54-1.68-20.54c0.05-3.05,0.19-4.38-0.61-6.25c-1.42-3.32-4.9-6.23-8.62-6.47
C54.84,53.21,51.97,56.08,51.75,55.77z"></path>
</g>
</svg>
</div>
因此您可以创建一个特定的 class 并通过 JS 切换它
如my answer here中所述,原地翻转所需的变换函数为:
translate(<minX+maxX>,0) scale(-1, 1)
因此,您的代码的工作版本可能如下所示:
function flipHorizontal(selectedElements) {
selectedElements.forEach(element => {
// Get the bounds of the element
let bbox = element.getBBox();
// Get the current transform attribute (if any) of the element
let currentTransform = element.getAttribute("transform") || "";
// Append translate and scale functions to the transform that will flip the element in place
element.setAttribute("transform", currentTransform + ' translate('+(bbox.x + bbox.x + bbox.width) + ',0) scale(-1, 1)');
});
}
let elementsToFlip = document.querySelectorAll("path, text");
flipHorizontal( elementsToFlip );
<div id="canvas" style="width: 550px; height: 550px">
<svg version="1.2" baseProfile="tiny" id="Logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 250 250" xml:space="preserve">
<text id="text" transform="matrix(1 0 0 1 31.1271 199.1222)" fill="#561010" font-family="'Roboto-Regular'" font-size="25.3945px">Nom d’entreprise</text>
<g>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="76.157" y1="87.0921" x2="70.9488" y2="44.8529"> <stop offset="0.0233" style="stop-color:#E92460"></stop> <stop offset="0.4636" style="stop-color:#F05C4B"></stop> <stop offset="0.9517" style="stop-color:#F36D38"></stop> </linearGradient>
<path transform="matrix(1 0 0 1 0 0)" fill="url(#SVGID_2_)" d="M51.75,55.77c-0.27-0.39,3.97-5.2,10.38-7.74c1.79-0.71,11.97-4.75,21.31,0.8
c8.61,5.12,11.99,15.71,10.53,24.27c-2.38,13.95-17.76,23.37-22.24,20.72c-0.97-0.57-1.32-2.75-1.99-7.09
c-1.81-11.84-1.68-20.54-1.68-20.54c0.05-3.05,0.19-4.38-0.61-6.25c-1.42-3.32-4.9-6.23-8.62-6.47
C54.84,53.21,51.97,56.08,51.75,55.77z"></path>
</g>
</svg>
</div>