css - 使用组元素旋转 SVG 圆
问题描述
我想旋转一个 SVG 圆圈,同时保持其他元素不旋转
当我尝试使用rotateZ(15deg)旋转圆圈(白色)时,这就是我得到的:
这是我到目前为止的进展: https ://jsfiddle.net/41hrnojs/
<svg viewBox="0 0 1400 900" style="outline:1px solid red;">
<g>
<clipPath id="hexagonal-mask">
<circle cx="700" cy="100" r="705" ></circle>
</clipPath>
</g>
<a>
<image clip-path="url(#hexagonal-mask)" height="100%" width="100%" xlink:href="{{ asset('images/H3z50J2.jpg') }}" style="transform: translateY(-140px);"/>
</a>
<g style="transform-origin: 701px -5%; transform: rotateZ(15deg)">
<circle cx="701" cy="0" r="665" stroke="#fff" stroke-width="1px" fill="transparent" style="transform: translateY(-50px);" ></circle>
<!-- center dot -->
<g id="g1" >
<circle cx="701" cy="615" r="15" fill="#fff">
</circle>
<path stroke="#000" stroke-width="1px" d="M701 630 701 690"></path>
<text x="672" y="720" font-family="'Playfair Display', serif" font-size="2em" font-weight="bold" fill="#9d9e9f">2007</text>
<text x="640" y="730" font-family="'Playfair Display', serif" font-size="2.85em" font-weight="bold" fill="#000">
<tspan x="640" dy="40">Lorem</tspan>
<tspan x="640" dy="45">Ipsum</tspan>
</text>
<animateMotion
xlink:href="#g1"
dur="1s"
begin="click"
fill="freeze"
path="M0 100 Q50 80 -399 -135"
repeatCount="1">
</animateMotion>
</g>
<!-- left dot -->
<g>
<!-- <circle cx="305" cy="485" r="15" fill="#fff"></circle> -->
<circle cx="302" cy="480" r="15" fill="#fff"></circle>
<path stroke="#000" stroke-width="1px" d="M302 495 305 675"></path>
</g>
<!-- right dot -->
<g>
<circle cx="1100" cy="480" r="15" fill="#fff"></circle>
<path stroke="#000" stroke-width="1px" d="M1100 495 1100 675"></path>
</g>
</g>
</svg>
我想实现
单击白色圆圈上的点,圆圈(白色)旋转
解决方案
我不会旋转所有东西,而是计算圆上点的位置,并使用点的坐标来绘制线条和文本。
为此,我正在使用 javascript。脚本中最重要的部分是一个用于计算旋转点新位置的函数:rotatePoint(p, c, rot)
请注意,在 svg 中,我已经消除了无用的转换。
let theG = document.querySelector("#theG");
//the center of the circle
let center = { x: 700, y: -40 };
//thr rotation in radians
let rot = .6;
//a function to calculate the new position of a rotated point
function rotatePoint(p, c, rot) {
// p: the point
// c: the center of rotation
// rot: the rotation
let cos = Math.cos(rot);
let sin = Math.sin(rot);
return {
x: c.x + (p.x - c.x) * cos - (p.y - c.y) * sin,
y: c.y + (p.x - c.x) * sin + (p.y - c.y) * cos
};
}
//all the groups with a class of dot
let groups = theG.querySelectorAll(".dot");
let points = [];
groups.forEach((g) => {
let dot = g.querySelector("circle");
let p = {};
p.x = dot.getAttribute("cx");
p.y = dot.getAttribute("cy");
points.push(p)
});
itr.addEventListener("input",()=>{
let rot = itr.value;
groups.forEach((g,i) => {
let dot = g.querySelector("circle");
let line = g.querySelector("line");
let t1 = g.querySelectorAll("text")[0];
let newPoint = rotatePoint(points[i], center, rot);
dot.setAttribute("cx", newPoint.x);
dot.setAttribute("cy", newPoint.y);
line.setAttribute("x1", newPoint.x);
line.setAttribute("x2", newPoint.x);
line.setAttribute("y1", newPoint.y);
line.setAttribute("y2", newPoint.y + 180);
t1.setAttribute("x", newPoint.x);
t1.setAttribute("y", newPoint.y + 200);
});
});
input{width:90vw;}
p{text-align:center;}
text{text-anchor:middle}
line{stroke:#000; stroke-width:1px; }
<p><input type="range" id="itr" min="-.85" max=".85" value="0" step=".01" /></p>
<svg viewBox="0 0 1400 900" style="outline:1px solid red;" >
<defs>
<clipPath id="hexagonal-mask">
<circle cx="700" cy="-40" r="705"></circle>
</clipPath>
</defs>
<image clip-path="url(#hexagonal-mask)" height="100%" width="100%" xlink:href="https://assets.codepen.io/222579/castell.jpg"></image>
<circle cx="700" cy="-40" r="655" stroke="#fff" stroke-width="1px" fill="transparent"></circle>
<g id="theG">
<g class="dot">
<circle cx="700" cy="615" r="15" fill="#fff"></circle>
<line x1="700" y1="615" x2="700" y2="795"></line>
<text x="700" y="815" font-family="'Playfair Display', serif" font-size="2em" font-weight="bold" fill="#9d9e9f">2007</text>
</g>
<g class="dot">
<circle cx="302" cy="480" r="15" fill="#fff"></circle>
<line x1="302" y1="480" x2="302" y2="660"></line>
<text x="302" y="680" font-family="'Playfair Display', serif" font-size="2em" font-weight="bold" fill="#9d9e9f">2006</text>
</g>
<g class="dot">
<circle cx="1100" cy="480" r="15" fill="#fff"></circle>
<line x1="1100" y1="480" x2="1100" y2="660"></line>
<text x="1100" y="680" font-family="'Playfair Display', serif" font-size="2em" font-weight="bold" fill="#9d9e9f">2008</text>
</g>
</g>
</svg>
推荐阅读
- c++ - 函数“do_compare”的汇编代码究竟做了什么?
- python - 如何获取使用 JavaScript 构建的锚标记的重定向链接?
- mysql - MySQL 5.6 中的内联查询
- jenkins - 无法将 Jenkins 从 2.156 更新到 2.164
- amazon-web-services - 如何仅跨某些维度聚合 CloudWatch SEARCH 指标
- ibm-watson - 如何使用 YAJL 库读取 Watson Visual Recognition JSON Respsonse?
- c# - 如何在 .NET 中反序列化为本地集合?
- python - 如何在 Python 的列表中找到最小值或最大值
- discord.js - 如何检查反应成员 discord.js 的角色
- php - the_category function is not working properly; the categories are not showing where they are supposed to be