Javascript 翻转svg图像的大部分,但不翻转其中的文本

Javascript 翻转svg图像的大部分,但不翻转其中的文本,javascript,css,node.js,svg,Javascript,Css,Node.js,Svg,我收集了大量svg图像,如下所示: .stroke1{fill:#BF0909;} .stroke2{fill:#BFBF09;} .stroke3{fill:#09BF09;} .stroke4{fill:#09BFBF;} .stroke5{fill:#0909BF;} .stroke6{fill:#BF09BF;} .stroke7{fill:#bfbf;} .stroke8{fill:#090909;} 以及必须在其上绘制数字的每个图像的坐标列表(请参见以下svg代码的文本元素)。

我收集了大量svg图像,如下所示:


.stroke1{fill:#BF0909;}
.stroke2{fill:#BFBF09;}
.stroke3{fill:#09BF09;}
.stroke4{fill:#09BFBF;}
.stroke5{fill:#0909BF;}
.stroke6{fill:#BF09BF;}
.stroke7{fill:#bfbf;}
.stroke8{fill:#090909;}
以及必须在其上绘制数字的每个图像的坐标列表(请参见以下svg代码的文本元素)。问题是:当我添加所需的文本元素时,它们会垂直和水平翻转:


.stroke1{fill:#BF0909;}
.stroke2{fill:#BFBF09;}
.stroke3{fill:#09BF09;}
.stroke4{fill:#09BFBF;}
.stroke5{fill:#0909BF;}
.stroke6{fill:#BF09BF;}
.stroke7{fill:#bfbf;}
.stroke8{fill:#090909;}
正文{
字体系列:Helvetica;
字号:80px;
填充:#FFFFFF;
绘画顺序:笔画;
行程:#000000;
笔画宽度:4px;
笔划线头:对接;
笔划线条连接:斜接;
字号:800;
}
1.
2.
3.
4.
5.
6.
7.
我就是想不出一种方法,在不水平和垂直翻转的情况下,让文本显示在正确的位置。我已经试着用另一个g标签包装文本,然后再次进行转换并还原,但是文本会消失。我还尝试将文本移出原始的g标签,但我的坐标不再有效

编辑:我正在寻找一种生成SVG的方法,使其与Safari(在Windows上)、Chrome和Firefox兼容


Edit2:不幸的是,我不能使用
转换框,因为我需要支持基于Safari的浏览器,但不支持它。

您可以在文本节点上使用css转换

编辑

受@enxaneta answer的启发,您可以运行这个小脚本

const text=document.queryselectoral(“text”);
text.forEach(函数(el){
el.style.transformOrigin=el.getAttribute('x')+'px'+el.getAttribute('y')+'px';
el.style.transform=“比例(1,-1)”;
});
文本{
优势基线:中心;
}

.stroke1{fill:#BF0909;}
.stroke2{fill:#BFBF09;}
.stroke3{fill:#09BF09;}
.stroke4{fill:#09BFBF;}
.stroke5{fill:#0909BF;}
.stroke6{fill:#BF09BF;}
.stroke7{fill:#bfbf;}
.stroke8{fill:#090909;}
正文{
字体系列:Helvetica;
字号:80px;
填充:#FFFFFF;
绘画顺序:笔画;
行程:#000000;
笔画宽度:4px;
笔划线头:对接;
笔划线条连接:斜接;
字号:800;
}
1.
2.
3.
4.
5.
6.
7.
我希望这有助于:

文本:第n个子项(1){
变换:比例(1,-1);
转换原点:317px 812px;/*与文本坐标相同*/
优势基线:悬挂;
}

.stroke1{fill:#BF0909;}
.stroke2{fill:#BFBF09;}
.stroke3{fill:#09BF09;}
.stroke4{fill:#09BFBF;}
.stroke5{fill:#0909BF;}
.stroke6{fill:#BF09BF;}
.stroke7{fill:#bfbf;}
.stroke8{fill:#090909;}
正文{
字体系列:Helvetica;
字号:80px;
填充:#FFFFFF;
绘画顺序:笔画;
行程:#000000;
笔画宽度:4px;
笔划线头:对接;
笔划线条连接:斜接;
字号:800;
}
1.
2.
3.
4.
5.
6.
7.

1.
2.
3.
4.
5.
6.
7.
var elements=document.querySelectorAll('*[y]');
对于(var i=0;i

958来自:900(初始转换)+58(字符高度)。

操作SVG,只需

  • 使用
    transform
    属性将
    元素移到组外
  • 使用以下命令重新计算
    y
    属性

    y -> 940 - y
    
    这假设transform属性始终为
    transform=“scale(1,-1)translate(0,-900)”
    ,字体大小为
    80px
    。一般的公式是

    y -> (negative y translation + font size / 2) - y
    
下面是一个利用ChereIO更改现有文件的节点脚本:

const cheerio = require('cheerio');
const $ = cheerio.load(xmlText, { xmlMode: true });

function flipTextInPlace ($) {
    $('text').each(() => {
       const y = $(this).attr('y');
       $(this).attr('y', 940 - y);
    }).appendTo('svg');
}

我不是落选的选民,但你检查过你的结果了吗?数字不再位于正确的位置。是的,很抱歉这个快速回答,我已经更新了我的帖子,感谢@enxanetaI的灯光。我开始认为我实际上没有数字的“正确”位置(坐标),只有翻转的数字的位置。那么负y值可能是正确的吗?不幸的是,我需要支持的基于Safari的浏览器不支持“transform box”属性。我已经将我的答案换成了另一个。请重新考虑你的投票,谢谢。使用fontSize/2后效果非常好。首先,我对你的答案投了赞成票,我不认为有理由改变这一点你说你想“生成”SVG。这是否意味着处理SVG文件以改变它们是可行的选择?在飞行中还是一劳永逸?是的,差不多。我使用NodeJs和Cheerio来操作SVG,然后保存它。
y -> 940 - y
y -> (negative y translation + font size / 2) - y
const cheerio = require('cheerio');
const $ = cheerio.load(xmlText, { xmlMode: true });

function flipTextInPlace ($) {
    $('text').each(() => {
       const y = $(this).attr('y');
       $(this).attr('y', 940 - y);
    }).appendTo('svg');
}