- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在制作一个图形和图表网络应用程序,我想对其中的不同形状执行旋转操作。不使用 CSS 或任何转换属性,我想对路径数据(d 参数)本身应用旋转。那么,我如何在数学上处理“d”属性中的点(包括大写和小写命令),以便它输出一个新的“d”字符串,表示围绕原点(x,y)进行 theta 度旋转后的旋转形状?例如,在此路径字符串 d="M349,228h212v-1331h-212v133"中,我想应用 transform=rotate(24) 和 transform-origin="455px 161.5px"。应用这些转换后,最终的 d 是什么?
最佳答案
另一种方法可能是通过 matrixTransform()
转换路径坐标。
timo22345 的要点中使用了这个概念 flatten.js并且还可以将其他转换(例如 scale()
或 translate()
)转换为硬编码路径命令。
/**
* getTransformToElement polyfill
*/
SVGElement.prototype.getTransformToElement = SVGElement.prototype.getTransformToElement || function(toElement) {
let matrix = toElement.getScreenCTM().inverse().multiply(this.getScreenCTM())
return matrix;
};
function convertTransform(decimals = 3) {
let svg = document.querySelector('svg');
let transformed = svg.querySelectorAll('*[transform]');
let transformedTotal = transformed.length;
if (transformedTotal) {
transformed.forEach(function(el, i) {
let type = el.nodeName.toLowerCase();
let shapes = ['path', 'circle', 'rect', 'polygon', 'polyline', 'line', 'ellipse'];
if (shapes.indexOf(type) !== -1) {
// normalize pathdata to get absolute coordinates
let pathData = el.getPathData({
normalize: true
})
// get transform matrix
let matrix = el.getTransformToElement(el.parentNode);
el.removeAttribute('transform');
pathData.forEach(function(command, d) {
let values = command.values;
// loop through coordinates:
for (let v = 0; v < values.length - 1; v += 2) {
let [x, y] = [values[v], values[v + 1]];
let pt = svg.createSVGPoint();
pt.x = x;
pt.y = y;
// change coordinates by matrix transform
let pTrans = pt.matrixTransform(matrix);
// save coordinates to pathdata array
pathData[d]['values'][v] = +pTrans.x.toFixed(decimals);
pathData[d]['values'][v + 1] = +pTrans.y.toFixed(decimals);
}
})
//check if conversion is needed for primitives (rect, circle, polygons etc.)
if (type !== 'path') {
let newPath = document.createElementNS("http://www.w3.org/2000/svg", "path");
let atts = [...el.attributes];
let excludedAtts = ['d', 'x', 'y', 'x1', 'y1', 'x2', 'y2', 'cx', 'cy', 'r', 'rx', 'ry', 'points', 'height', 'width'];
for (let a = 0; a < atts.length; a++) {
let att = atts[a];
if (excludedAtts.indexOf(att.nodeName) === -1) {
var attrName = att.nodeName;
var attrValue = att.nodeValue;
newPath.setAttribute(attrName, attrValue + '');
}
}
el.replaceWith(newPath);
el = newPath;
}
el.setPathData(pathData)
}
})
}
}
<script src="https://cdn.jsdelivr.net/npm/path-data-polyfill@1.0.3/path-data-polyfill.min.js"></script>
<p><button type="button" onclick="convertTransform()"> Convert transforms </button></p>
<svg viewBox="0 0 100 100" overflow="visible">
<path class="" d="M25 25 h25 v25 h-25 z" fill="green" />
<rect x="0" y="0" width="33%" height="20" transform="rotate(27 20 50) translate(20 10)" fill="orange" />
<path data-att="random" transform="rotate(45 50 50) scale(1.2) translate(10 -20)" class="transform" d="M25 25 h25 v25 h-25 z" fill="red" />
</svg>
getTransformToElement()
获取每个元素的转换矩阵(包括 polyfill)point.matrixTransform(matrix)
上面的脚本被简化了:它不能转换嵌套转换(比如嵌套转换组)——timo22345 flatten.js 可以通过应用多个转换来完成这个技巧(并且它不需要辅助库/polyfills)。
let svg = document.querySelector('svg');
SVGElement.prototype.getTransformToElement = SVGElement.prototype.getTransformToElement || function(e) {
return e.getScreenCTM().inverse().multiply(this.getScreenCTM())
},
function() {
var e = /,?([achlmqrstvxz]),?/gi,
t = function(t) {
return t.join(",").replace(e, "$1")
};
function r(e, t, r, a, n, u, i, c) {
function o(e) {
return Math.abs(e) < 1e-16
}
var l, s, h, f, x, y, p, g, b, v, m, M = [];
if (l = e, s = t, h = r *= Math.PI / 180, f = parseFloat(Math.sin(h)), x = parseFloat(Math.cos(h)), M[0] = i.a * +l * x + i.c * l * f, M[1] = i.b * +l * x + i.d * l * f, M[2] = i.a * -s * f + i.c * s * x, M[3] = i.b * -s * f + i.d * s * x, b = (y = M[0] * M[0] + M[2] * M[2]) - (g = M[1] * M[1] + M[3] * M[3]), o(p = 2 * (M[0] * M[1] + M[2] * M[3]))) r = 0, v = y, m = g;
else if (o(b)) v = y + .5 * p, m = y - .5 * p, r = Math.PI / 4;
else {
var d = 1 + p * p / (b * b);
v = .5 * (y + g + (d = d < 0 ? 0 : Math.sqrt(d)) * b), m = .5 * (y + g - d * b), r = .5 * Math.atan2(p, b)
}
return v = v < 0 ? 0 : Math.sqrt(v), m = m < 0 ? 0 : Math.sqrt(m), b <= 0 ? (t = v, e = m) : (t = m, e = v), i.a * i.d - i.b * i.c < 0 && (n = n ? 0 : 1), u = u.matrixTransform(i), ["A", e, t, r = 180 * r / Math.PI, a, n, u.x, u.y]
}
var a = {},
n = "hasOwnProperty",
u = String,
i = "array",
c = {
NaN: 1,
Infinity: 1,
"-Infinity": 1
},
o = u.prototype.toLowerCase,
l = u.prototype.toUpperCase,
s = Object.prototype.toString,
h = Math,
f = h.max,
x = (h.min, h.abs, h.pow, h.PI),
y = (h.round, parseFloat),
p = (parseInt, e = /,?([achlmqrstvxz]),?/gi, /([achlmrqstvz])[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*)+)/gi),
g = /(-?\d*\.?\d*(?:e[\-+]?\d+)?)[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*/gi;
function b(e) {
if (Object(e) !== e) return e;
var t = new e.constructor;
for (var r in e) e[n](r) && (t[r] = b(e[r]));
return t
}
a.is = function(e, t) {
return "finite" == (t = o.call(t)) ? !c[n](+e) : "array" == t ? e instanceof Array : "null" == t && null === e || t == typeof e && null !== e || "object" == t && e === Object(e) || "array" == t && Array.isArray && Array.isArray(e) || s.call(e).slice(8, -1).toLowerCase() == t
}, a._path2string = function() {
return this.join(",").replace(e, "$1")
};
var v = function(e) {
var t = b(e);
return t.toString = a._path2string, t
},
m = function(e) {
var t = m.ps = m.ps || {};
return t[e] ? t[e].sleep = 100 : t[e] = {
sleep: 100
}, setTimeout((function() {
for (var r in t) t[n](r) && r != e && (t[r].sleep--, !t[r].sleep && delete t[r])
})), t[e]
},
M = function(e) {
if (!e) return null;
var t = m(e);
if (t.arr) return v(t.arr);
var r = {
a: 7,
c: 6,
h: 1,
l: 2,
m: 2,
r: 4,
q: 4,
s: 4,
t: 2,
v: 1,
z: 0
},
n = [];
return a.is(e, i) && a.is(e[0], i) && (n = v(e)), n.length || u(e).replace(p, (function(e, t, a) {
var u = [],
i = t.toLowerCase();
if (a.replace(g, (function(e, t) {
t && u.push(+t)
})), "m" == i && u.length > 2 && (n.push([t].concat(u.splice(0, 2))), i = "l", t = "m" == t ? "l" : "L"), "r" == i) n.push([t].concat(u));
else
for (; u.length >= r[i] && (n.push([t].concat(u.splice(0, r[i]))), r[i]););
})), n.toString = a._path2string, t.arr = v(n), n
};
var d = A((function(e) {
if (a.is(e, i) && a.is(e && e[0], i) || (e = M(e)), !e || !e.length) return [
["M", 0, 0]
];
var t = [],
r = 0,
n = 0,
u = 0,
c = 0,
o = 0;
"M" == e[0][0] && (u = r = +e[0][1], c = n = +e[0][2], o++, t[0] = ["M", r, n]);
for (var s, h, f = 3 == e.length && "M" == e[0][0] && "R" == e[1][0].toUpperCase() && "Z" == e[2][0].toUpperCase(), x = o, y = e.length; x < y; x++) {
if (t.push(s = []), (h = e[x])[0] != l.call(h[0])) switch (s[0] = l.call(h[0]), s[0]) {
case "A":
s[1] = h[1], s[2] = h[2], s[3] = h[3], s[4] = h[4], s[5] = h[5], s[6] = +(h[6] + r), s[7] = +(h[7] + n);
break;
case "V":
s[1] = +h[1] + n;
break;
case "H":
s[1] = +h[1] + r;
break;
case "R":
for (var p = [r, n].concat(h.slice(1)), g = 2, b = p.length; g < b; g++) p[g] = +p[g] + r, p[++g] = +p[g] + n;
t.pop(), t = t.concat(catmullRom2bezier(p, f));
break;
case "M":
u = +h[1] + r, c = +h[2] + n;
default:
for (g = 1, b = h.length; g < b; g++) s[g] = +h[g] + (g % 2 ? r : n)
} else if ("R" == h[0]) p = [r, n].concat(h.slice(1)), t.pop(), t = t.concat(catmullRom2bezier(p, f)), s = ["R"].concat(h.slice(-2));
else
for (var v = 0, m = h.length; v < m; v++) s[v] = h[v];
switch (s[0]) {
case "Z":
r = u, n = c;
break;
case "H":
r = s[1];
break;
case "V":
n = s[1];
break;
case "M":
u = s[s.length - 2], c = s[s.length - 1];
default:
r = s[s.length - 2], n = s[s.length - 1]
}
}
return t.toString = a._path2string, t
}));
function A(e, t, r) {
return function a() {
var n = Array.prototype.slice.call(arguments, 0),
u = n.join("␀"),
i = a.cache = a.cache || {},
c = a.count = a.count || [];
if (i.hasOwnProperty(u)) {
for (var o = 0, l = c.length; o < l; o++) c[o] === u && c.push(c.splice(o, 1)[0]);
return r ? r(i[u]) : i[u]
}
return c.length >= 1e3 && delete i[c.shift()], c.push(u), i[u] = e.apply(t, n), r ? r(i[u]) : i[u]
}
}
var C = function(e, t, r, a) {
return [e, t, r, a, r, a]
},
q = function(e, t, r, a, n, u) {
var i = 1 / 3,
c = 2 / 3;
return [i * e + c * r, i * t + c * a, i * n + c * r, i * u + c * a, n, u]
},
S = A((function(e, t, r, a, n, u, i, c, o, l) {
var s, h = 120 * x / 180,
f = x / 180 * (+n || 0),
y = [],
p = A((function(e, t, r) {
return {
x: e * Math.cos(r) - t * Math.sin(r),
y: e * Math.sin(r) + t * Math.cos(r)
}
}));
if (l) w = l[0], V = l[1], C = l[2], q = l[3];
else {
e = (s = p(e, t, -f)).x, t = s.y, c = (s = p(c, o, -f)).x, o = s.y;
Math.cos(x / 180 * n), Math.sin(x / 180 * n);
var g = (e - c) / 2,
b = (t - o) / 2,
v = g * g / (r * r) + b * b / (a * a);
v > 1 && (r *= v = Math.sqrt(v), a *= v);
var m = r * r,
M = a * a,
d = (u == i ? -1 : 1) * Math.sqrt(Math.abs((m * M - m * b * b - M * g * g) / (m * b * b + M * g * g))),
C = d * r * b / a + (e + c) / 2,
q = d * -a * g / r + (t + o) / 2,
w = Math.asin(((t - q) / a).toFixed(9)),
V = Math.asin(((o - q) / a).toFixed(9));
(w = e < C ? x - w : w) < 0 && (w = 2 * x + w), (V = c < C ? x - V : V) < 0 && (V = 2 * x + V), i && w > V && (w -= 2 * x), !i && V > w && (V -= 2 * x)
}
var k = V - w;
if (Math.abs(k) > h) {
var L = V,
E = c,
T = o;
V = w + h * (i && V > w ? 1 : -1), c = C + r * Math.cos(V), o = q + a * Math.sin(V), y = S(c, o, r, a, n, 0, i, E, T, [V, L, C, q])
}
k = V - w;
var G = Math.cos(w),
P = Math.sin(w),
Z = Math.cos(V),
_ = Math.sin(V),
j = Math.tan(k / 4),
z = 4 / 3 * r * j,
H = 4 / 3 * a * j,
I = [e, t],
R = [e + z * P, t - H * G],
F = [c + z * _, o - H * Z],
N = [c, o];
if (R[0] = 2 * I[0] - R[0], R[1] = 2 * I[1] - R[1], l) return [R, F, N].concat(y);
for (var O = [], U = 0, Q = (y = [R, F, N].concat(y).join().split(",")).length; U < Q; U++) O[U] = U % 2 ? p(y[U - 1], y[U], f).y : p(y[U], y[U + 1], f).x;
return O
})),
w = A((function(e, t) {
var r = !t && m(e);
if (!t && r.curve) return v(r.curve);
for (var a = d(e), n = t && d(t), u = {
x: 0,
y: 0,
bx: 0,
by: 0,
X: 0,
Y: 0,
qx: null,
qy: null
}, i = {
x: 0,
y: 0,
bx: 0,
by: 0,
X: 0,
Y: 0,
qx: null,
qy: null
}, c = function(e, t, r) {
var a, n;
if (!e) return ["C", t.x, t.y, t.x, t.y, t.x, t.y];
switch (!(e[0] in {
T: 1,
Q: 1
}) && (t.qx = t.qy = null), e[0]) {
case "M":
t.X = e[1], t.Y = e[2];
break;
case "A":
e = ["C"].concat(S.apply(0, [t.x, t.y].concat(e.slice(1))));
break;
case "S":
"C" == r || "S" == r ? (a = 2 * t.x - t.bx, n = 2 * t.y - t.by) : (a = t.x, n = t.y), e = ["C", a, n].concat(e.slice(1));
break;
case "T":
"Q" == r || "T" == r ? (t.qx = 2 * t.x - t.qx, t.qy = 2 * t.y - t.qy) : (t.qx = t.x, t.qy = t.y), e = ["C"].concat(q(t.x, t.y, t.qx, t.qy, e[1], e[2]));
break;
case "Q":
t.qx = e[1], t.qy = e[2], e = ["C"].concat(q(t.x, t.y, e[1], e[2], e[3], e[4]));
break;
case "L":
e = ["C"].concat(C(t.x, t.y, e[1], e[2]));
break;
case "H":
e = ["C"].concat(C(t.x, t.y, e[1], t.y));
break;
case "V":
e = ["C"].concat(C(t.x, t.y, t.x, e[1]));
break;
case "Z":
e = ["C"].concat(C(t.x, t.y, t.X, t.Y))
}
return e
}, o = function(e, t) {
if (e[t].length > 7) {
e[t].shift();
for (var r = e[t]; r.length;) s[t] = "A", n && (h[t] = "A"), e.splice(t++, 0, ["C"].concat(r.splice(0, 6)));
e.splice(t, 1), b = f(a.length, n && n.length || 0)
}
}, l = function(e, t, r, u, i) {
e && t && "M" == e[i][0] && "M" != t[i][0] && (t.splice(i, 0, ["M", u.x, u.y]), r.bx = 0, r.by = 0, r.x = e[i][1], r.y = e[i][2], b = f(a.length, n && n.length || 0))
}, s = [], h = [], x = "", p = "", g = 0, b = f(a.length, n && n.length || 0); g < b; g++) {
a[g] && (x = a[g][0]), "C" != x && (s[g] = x, g && (p = s[g - 1])), a[g] = c(a[g], u, p), "A" != s[g] && "C" == x && (s[g] = "C"), o(a, g), n && (n[g] && (x = n[g][0]), "C" != x && (h[g] = x, g && (p = h[g - 1])), n[g] = c(n[g], i, p), "A" != h[g] && "C" == x && (h[g] = "C"), o(n, g)), l(a, n, u, i, g), l(n, a, i, u, g);
var M = a[g],
A = n && n[g],
w = M.length,
V = n && A.length;
u.x = M[w - 2], u.y = M[w - 1], u.bx = y(M[w - 4]) || u.x, u.by = y(M[w - 3]) || u.y, i.bx = n && (y(A[V - 4]) || i.x), i.by = n && (y(A[V - 3]) || i.y), i.x = n && A[V - 2], i.y = n && A[V - 1]
}
return n || (r.curve = v(a)), n ? [a, n] : a
}), null, v);
window.flatten = function e(a, n = !1, u = !1, i = !1, c = 3) {
if (a)
if (void 0 === i && (i = !1), void 0 === n && (n = !1), void 0 === u && (u = !1), void 0 === c && (c = !1), a && a.children && a.children.length) {
for (var o = 0, l = a.children.length; o < l; o++) e(a.children[o], n, u, i, c);
a.removeAttribute("transform")
} else if (a instanceof SVGCircleElement || a instanceof SVGRectElement || a instanceof SVGEllipseElement || a instanceof SVGLineElement || a instanceof SVGPolygonElement || a instanceof SVGPolylineElement || a instanceof SVGPathElement) {
if (path_elem = function(e, r) {
if (!e) return;
var a = document.createElementNS(e.ownerSVGElement.namespaceURI, "path");
let n = [...e.attributes],
u = ["d", "x", "y", "x1", "y1", "x2", "y2", "cx", "cy", "r", "rx", "ry", "points", "height", "width"];
for (let e = 0; e < n.length; e++) {
let t = n[e];
if (-1 === u.indexOf(t.nodeName)) {
var i = t.nodeName,
c = t.nodeValue;
a.setAttribute(i, c + "")
}
}
var o = "",
l = function(e) {
return !("number" != typeof e || e == 1 / 0 || e < 0)
},
s = 1.81,
h = e.tagName;
switch (h) {
case "ellipse":
case "circle":
var f = +e.getAttribute("rx"),
x = +e.getAttribute("ry"),
y = +e.getAttribute("cx"),
p = +e.getAttribute("cy");
"circle" == h && (f = x = +e.getAttribute("r")), o += t([
["M", y - f, p],
["C", y - f, p - x / s, y - f / s, p - x, y, p - x],
["C", y + f / s, p - x, y + f, p - x / s, y + f, p],
["C", y + f, p + x / s, y + f / s, p + x, y, p + x],
["C", y - f / s, p + x, y - f, p + x / s, y - f, p],
["Z"]
]);
break;
case "path":
o = e.getAttribute("d");
break;
case "line":
var g = e.getAttribute("x1"),
b = e.getAttribute("y1");
x2 = e.getAttribute("x2"), y2 = e.getAttribute("y2"), o = "M" + g + "," + b + "L" + x2 + "," + y2;
break;
case "polyline":
o = "M" + e.getAttribute("points");
break;
case "polygon":
o = "M" + e.getAttribute("points") + "Z";
break;
case "rect":
f = +e.getAttribute("rx"), x = +e.getAttribute("ry");
var v = e.getBBox(),
m = v.x,
M = v.y,
d = v.width,
A = v.height;
if (l(f) || l(x) ? l(f) && !l(x) ? x = f : l(x) && !l(f) ? f = x : (f > d / 2 && (f = d / 2), x > A / 2 && (x = A / 2)) : f = x = 0, f || x)
if (r) o += t([
["M", m + f, M],
["H", m + d - f],
["A", f, x, 0, 0, 1, m + d, M + x],
["V", M + A - x],
["A", f, x, 0, 0, 1, m + d - f, M + A],
["H", m + f],
["A", f, x, 0, 0, 1, m, M + A - x],
["V", M + x],
["A", f, x, 0, 0, 1, m + f, M]
]);
else {
x || (x = f), o += t([
["M", m, M + x],
["C", m, M + x / (s = 2.19), m + f / s, M, m + f, M],
["L", m + d - f, M],
["C", m + d - f / s, M, m + d, M + x / s, m + d, M + x],
["L", m + d, M + A - x],
["C", m + d, M + A - x / s, m + d - f / s, M + A, m + d - f, M + A],
["L", m + f, M + A],
["C", m + f / s, M + A, m, M + A - x / s, m, M + A - x],
["L", m, M + x],
["Z"]
])
}
else o += t([
["M", m, M],
["L", m + d, M],
["L", m + d, M + A],
["L", m, M + A],
["L", m, M],
["Z"]
])
}
o && a.setAttribute("d", o);
return e.parentNode.replaceChild(a, e), a
}(a, i), !path_elem || "" == path_elem.getAttribute(f)) return "M 0 0";
var s;
c || 0 === c ? c > 15 ? c = 15 : c < 0 && (c = 0) : c = !1;
var h = path_elem,
f = h.getAttribute("d").trim();
if (n) x = s = w(f);
else {
var x = s = M(f);
s = d(s)
}
var y, p, g = h.ownerSVGElement,
b = h.getTransformToElement(g),
v = (o = 0, s.length),
m = "",
A = "",
C = 0,
q = 0,
S = [],
V = g.createSVGPoint(),
k = {},
L = 0,
E = 0;
for (k.x = null, k.y = null; o < v; o++) {
if (m = s[o][0].toUpperCase(), A = x[o][0], S[o] = [], S[o][0] = s[o][0], "A" == m) C = s[o][6], q = s[o][7], V.x = s[o][6], V.y = s[o][7], S[o] = r(s[o][1], s[o][2], s[o][3], s[o][4], s[o][5], V, b), S[o][1] = S[o][1], S[o][2] = S[o][2], S[o][3] = S[o][3], S[o][6] = S[o][6], S[o][7] = S[o][7];
else if ("Z" != m)
for (y = 1; y < s[o].length; y += 2) "V" == m ? q = s[o][y] : "H" == m ? C = s[o][y] : (C = s[o][y], q = s[o][y + 1]), V.x = C, V.y = q, p = V.matrixTransform(b), "V" == m || "H" == m ? (S[o][0] = "L", S[o][y] = p.x, S[o][y + 1] = p.y) : (S[o][y] = p.x, S[o][y + 1] = p.y);
("Z" != m && null === k.x || "M" == m) && (k.x = C, k.y = q), "Z" == m && (C = k.x, q = k.y)
}
var T = 0,
G = 0;
for (k.x = "", o = 0; o < S.length; o++) {
if ("A" == (A = x[o][0]) || "M" == A || "L" == A || "C" == A || "S" == A || "Q" == A || "T" == A || "H" == A || "V" == A) {
var P = Z = S[o].length;
if ("A" == A) S[o][6] = _(S[o][6]), S[o][7] = _(S[o][7]);
else
for (P--; --P;) S[o][P] = _(S[o][P]);
L = S[o][Z - 2], E = S[o][Z - 1]
} else if ("a" == A) T = S[o][6], G = S[o][7], S[o][0] = A, S[o][6] = _(S[o][6] - L), S[o][7] = _(S[o][7] - E), L = T, E = G;
else if ("m" == A || "l" == A || "c" == A || "s" == A || "q" == A || "t" == A || "h" == A || "v" == A) {
var Z = S[o].length;
for (T = S[o][Z - 2], G = S[o][Z - 1], y = 1; y < Z; y += 2) S[o][0] = "h" == A || "v" == A ? "l" : A, S[o][y] = _(S[o][y] - L), S[o][y + 1] = _(S[o][y + 1] - E);
L = T, E = G
}("z" != A.toLowerCase() && "" == k.x || "m" == A.toLowerCase()) && (k.x = L, k.y = E), "z" == A.toLowerCase() && (L = k.x, E = k.y)
}
S[0][1] = +S[0][1].toFixed(c), S[0][2] = +S[0][2].toFixed(c), u && (S = d(S)), path_elem.setAttribute("d", t(S)), path_elem.removeAttribute("transform")
}
function _(e) {
return !1 !== c ? Math.round(e * Math.pow(10, c)) / Math.pow(10, c) : e
}
}
}();
<p><button type="button" onclick="flatten(svg)"> Convert transforms flatten.js</button></p>
<svg viewBox="0 0 100 100" overflow="visible">
<g transform="rotate(-33 50 50) translate(-10 -10) scale(1.5)">
<g transform="rotate(-33 50 50) translate(-10 -10) scale(1.5)">
<path class="" d="M25 25 h25 v25 h-25 z" fill="green" />
<rect x="0" y="0" width="33%" height="20" transform="rotate(27 20 50) translate(20 10)" fill="orange" />
<path data-att="random" transform="rotate(45 50 50)" class="transform" d="M25 25 h25 v25 h-25 z" fill="red" />
</g>
</g>
</svg>
至少当您的用户经常更改转换时。
使用像 fabric.js 这样的 Canvas 驱动(具有 svg 导出功能)库可能是更好的解决方案。
上述路径数据操作由于坐标/数字舍入而有损。如果仅完成一次(例如,在编辑之后或将转换后的图形导出为 svg 文件之前),则可以忽略不计。
关于javascript - 如何在 SVG 路径数据 (d) 字符串本身中执行旋转?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72943080/
...沮丧。我希望我的游戏仅在横向模式下运行。我已将适当的键/值添加到 Info.plist 文件中,以强制设备方向在启动时正确。 我现在正在尝试旋转 OpenGL 坐标空间以匹配设备的坐标空间。我正
我如何创建一个旋转矩阵,将 X 旋转 a,Y 旋转 b,Z 旋转 c? 我需要公式,除非您使用的是 ardor3d api 的函数/方法。 矩阵是这样设置的 xx, xy, xz, yx, yy, y
假设我有一个包含 3 个 vector 的类(一个用于位置,一个用于缩放,一个用于旋转)我可以使用它们生成一个变换矩阵,该矩阵表示对象在 3D 空间中的位置、旋转和大小。然后我添加对象之间的父/子关系
所以我只是在玩一个小的 javascript 游戏,构建一个 pacman 游戏。你可以在这里看到它:http://codepen.io/acha5066/pen/rOyaPW 不过我对旋转有疑问。你
在我的应用程序中,我有一个 MKMapView,其中显示了多个注释。 map 根据设备的航向旋转。要旋转 map ,请执行以下语句(由方法 locationManager 调用:didUpdateHe
使用此 jquery 插件时:http://code.google.com/p/jqueryrotate/wiki/Documentation我将图像旋转 90 度,无论哪个方向,它们最终都会变得模糊
我有以下代码:CSS: .wrapper { margin:80px auto; width:300px; border:none; } .square { widt
本篇介绍Manim中的两个旋转类的动画,名称差不多,分别是Rotate和Rotating。 Rotate类主要用于对图形对象进行指定角度、围绕特定点的精确旋转,适用于几何图形演示、物理模拟和机械运动
我只想通过小部件的轴移动图像并围绕小部件的中心旋转(就像任何数字绘画软件中的 Canvas ),但它围绕其左顶点旋转...... QPainter p(this); QTransform trans;
我需要先旋转图像,然后再将其加载到 Canvas 中。据我所知,我无法使用 canvas.rotate() 旋转它,因为它会旋转整个场景。 有没有好的JS方法来旋转图片? [不依赖于浏览器的方式] 最
我需要知道我的 Android 设备屏幕何时从一个横向旋转到另一个横向(rotation_90 到 rotation_270)。在我的 Android 服务中,我重新实现了 onConfigurati
**摘要:**本篇文章主要讲解Python调用OpenCV实现图像位移操作、旋转和翻转效果,包括四部分知识:图像缩放、图像旋转、图像翻转、图像平移。 本文分享自华为云社区《[Python图像处理] 六
我只是在玩MTKView中的模板设置;并且,我一直在尝试了解以下内容: 相机的默认位置。 使用MDLMesh和MTKMesh创建基元时的默认位置。 为什么轮换还涉及翻译。 相关代码: matrix_f
我正在尝试使用包 dendexend 创建一个树状图。它创建了非常好的 gg 树状图,但不幸的是,当你把它变成一个“圆圈”时,标签跟不上。我将在下面提供一个示例。 我的距离对象在这里:http://s
我想将一个完整的 ggplot 对象旋转 90°。 我不想使用 coord_flip因为这似乎会干扰 scale="free"和 space="free"使用刻面时。 例如: qplot(as.fac
我目前可以通过首先平移到轴心点然后执行旋转最后平移回原点来围绕轴心点旋转。在我的例子中,我很容易为肩膀做到这一点。但是,我不知道如何为前臂添加绕肘部的旋转。 我已经尝试了以下围绕肘部旋转的前臂: 平移
我想使用此功能旋转然后停止在特定点或角度。现在该元素只是旋转而不停止。代码如下: $(function() { var $elie = $("#bkgimg");
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 4 年前。 Improve this ques
我正在尝试创建一个非常简单的关键帧动画,其中图形通过给定的中点从一个角度旋转到另一个角度。 (目的是能够通过大于 180 度的 OBTUSE 弧角来制作旋转动画,而不是让动画“作弊”并走最短路线,即通
我需要旋转 NSView 实例的框架,使其宽度变为其高度,其高度变为其宽度。该 View 包含一个字符串,并且该字符串也被旋转,这一点很重要。 我查看了 NSView 的 setFrameRotati
我是一名优秀的程序员,十分优秀!