我有一個半圓 ( green) 和一個物件 ( blue)。我想將該物件從起點 ( left) 移動到終點 ( right)。物件應遵循black半圓的路徑 ( )。

物件應根據特定值移動。值是從 0 到 1 的數字。開始 = 0,結束 = 1。
我目前的解決方案:
- 通過乘以 100 將值轉換為百分比。因此,0 = 0%、0.5 = 50%、1 = 100%
- 物件是放置在相對容器內的絕對元素
- 半圓也放在相對容器內,但不是絕對的
- 物件將使用 CSS
left和移動bottom,初始值為0% - 半圓的前半部分是 a
0-49%,后半部分是 a50-100% - 我也
padding用于半圓和translate物件。padding只需要漂亮的外觀,實際上并不影響解決方案。translate是必要的的合適的位置left和bottom是相對于“相對容器”

我想出了如何在 Y 軸上移動物件:
// p is from 0 to 100
const bottom = (
p < 50 ?
p * 2 :
100 - (p - 50) * 2
);
但我不知道如何正確地在 X 軸上移動。目前我有這個:
const left = p;
這給了我這個結果:

那么,如何正確地在 X 軸上移動物件? 或者,對于 X 軸和 Y 軸,也許有更好的解決方案?
請注意:
- most likely it should be JavaScript-dependent solution, not CSS only. I need to have control over
value. I will set it manually and will update it manually. Sometimes there will be no animation at all because I will not iterate from 0 to 1, but set it only once. - I need to interact with these two
<svg>elements, not create my own elements. The reason is that every<svg>have linear gradient fill, and it can't be done correctly withborder.
Here is snippet of my current solution:
async function main() {
let value = 0; // from 0 to 1
while (value < 1) {
await new Promise((resolve) => {
window.setTimeout(resolve, 10);
});
value = 0.01;
move(value);
}
}
function move(value) {
const p = 100 * value;
const bottom = (
p < 50 ?
p * 2 :
100 - (p - 50) * 2
);
const left = p;
const css = {
left: `${left}%`,
bottom: `${bottom}%`,
transform: `translate(-${left}%, ${bottom}%)`,
};
const element = document.getElementById("ellipse-2-container")
element.style.left = css.left;
element.style.bottom = css.bottom;
element.style.transform = css.transform;
}
main()
.root {
position: relative;
width: 20rem;
}
.ellipse-1 {
width: 100%;
height: auto;
box-sizing: border-box;
padding: 0.3rem;
}
.ellipse-2 {
width: 1.5rem;
height: auto;
}
.ellipse-2-container {
position: absolute;
left: 0;
bottom: 0;
display: flex;
}
<div class="root">
<svg class="ellipse-1" xmlns="http://www.w3.org/2000/svg" width="272" height="125" viewBox="0 0 272 125"
fill="none">
<path
d="M265.2 124.5C268.956 124.5 272.021 121.452 271.797 117.703C269.975 87.1607 255.916 58.2064 232.167 36.4652C206.662 13.1169 172.069 2.4929e-06 136 0C99.9306 -2.4929e-06 65.3384 13.1169 39.8335 36.4652C16.084 58.2064 2.0254 87.1607 0.202617 117.703C-0.0211153 121.452 3.04446 124.5 6.8 124.5C10.5555 124.5 13.5766 121.451 13.8251 117.704C15.6319 90.4658 28.2517 64.6746 49.4501 45.2687C72.4046 24.2552 103.538 12.45 136 12.45C168.463 12.45 199.595 24.2552 222.55 45.2687C243.748 64.6746 256.368 90.4658 258.175 117.704C258.423 121.451 261.444 124.5 265.2 124.5Z"
fill="green">
</path>
</svg>
<div class="ellipse-2-container" id="ellipse-2-container">
<svg
class="ellipse-2" xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"
fill="none">
<path
d="M27.1759 15C27.1759 21.9292 21.6265 27.5 14.838 27.5C8.04943 27.5 2.5 21.9292 2.5 15C2.5 8.07077 8.04943 2.5 14.838 2.5C21.6265 2.5 27.1759 8.07077 27.1759 15Z"
fill="blue">
</path>
</svg>
</div>
</div>
Note about solution.
我使用了 Temani Afif 解決方案,但幾乎沒有修改。在問題中我指出我需要保留這兩個<svg>元素。所以,我將div.arc邊框顏色設定為透明,洗掉不必要的:before, :after. 設定div.arc于position: relative和我的孩子<svg>作為position: absolute。對齊后,它看起來像物件在<svg>元素上移動,但實際上它移動了div.arc。
uj5u.com熱心網友回復:
僅使用 CSS 和更簡單的解決方案怎么樣:
顯示代碼片段
.arc {
width:250px;
aspect-ratio:2/1;
border:20px solid blue;
border-bottom:0;
border-radius:200px 200px 0 0;
box-sizing:border-box;
display:grid;
}
.arc:before,
.arc:after,
.arc div{
content:"";
width:20px;
aspect-ratio:1/1;
border-radius:50%;
grid-area:1/1;
background:blue;
}
.arc > div {
background:lightgreen;
margin:auto auto -10px;
animation:a 3s linear both 1s;
}
@keyframes a{ /* 115px = (250px - 20px)/2 */
from {transform:rotate(-180deg) translate(115px)}
to {transform:rotate( 0deg) translate(115px)}
}
.arc:before {
margin:auto auto -10px -20px;
}
.arc:after {
margin:auto -20px -10px auto;
}
<div class="arc">
<div></div>
</div>
使用 CSS 變數來控制值:
.arc {
width:250px;
aspect-ratio:2/1;
border:20px solid blue;
border-bottom:0;
border-radius:200px 200px 0 0;
box-sizing:border-box;
display:grid;
}
.arc:before,
.arc:after,
.arc div{
content:"";
width:20px;
aspect-ratio:1/1;
border-radius:50%;
grid-area:1/1;
background:blue;
}
.arc > div {
background:lightgreen;
margin:auto auto -10px;
transform:rotate(calc(180deg*var(--x) - 180deg)) translate(115px)
}
.arc:before {
margin:auto auto -10px -20px;
}
.arc:after {
margin:auto -20px -10px auto;
}
<div class="arc" style="--x:0">
<div></div>
</div>
<div class="arc" style="--x:0.2">
<div></div>
</div>
<div class="arc" style="--x:0.6">
<div></div>
</div>
<div class="arc" style="--x:1">
<div></div>
</div>
uj5u.com熱心網友回復:
你認為這有幫助嗎?
.dot {
width: 10px;
height: 10px;
border-radius: 50%;
background: blue;
position: absolute;
left: -7px;
top: 45px;
}
.container {
width: 100px;
height: 100px;
position: relative;
border-radius: 50%;
border: 5px solid green;
animation: rot 3s infinite;
box-sizing: content
}
@keyframes rot {
0% {
transform: rotate(0deg)
}
100% {
transform: rotate(180deg)
}
}
<div class="container">
<span class="dot"></span>
</div>
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/362838.html
標籤:javascript html css 数学 几何学
上一篇:如何用這條曲線的點生成一個陣列?
下一篇:如何使用模10^9 7
