我有一个水平响应的 SVG 路径,可以在不保持其比例的情况下进行拉伸,并且在标签上使用
preserveAspectRatio="none"
并在路径上使用 vector-effect="non-scaling-stroke"
时可以保持其完整,它可以正常工作。但我还需要沿着相同的路径为元素设置动画,而不丢失其纵横比。
这是一个示例,您可以看到,如果您水平调整包装器的大小,它就可以工作,但对于因全局
preserveAspectRatio="none"
属性而导致失去纵横比的星形则不起作用。我找不到解决方法,并且让路径水平响应并保持星形完整并遵循路径......
.wrapper {
width: 100%;
min-width: 200px;
max-width: 100%;
height: 200px;
resize: horizontal;
overflow: hidden;
border: 1px solid blue;
}
svg {
width: 100%;
height: 100%;
}
.path {
fill: none;
stroke: black;
stroke-width: 2px;
stroke-dasharray: 6 6;
stroke-linecap:round;
}
.star {
fill: red;
}
<div class="wrapper">
<svg viewBox="0 0 400 200" preserveAspectRatio="none">
<defs>
<path id="star" d="M0,24.675L2.679,32.921L11.349,32.921L4.335,38.017L7.014,46.262L0,41.166L-7.014,46.262L-4.335,38.017L-11.349,32.921L-2.679,32.921L0,24.675Z"/>
<path id="path" d="M0,36.608C0,36.608 64.096,15.519 92.956,48.531C121.816,81.542 101.293,129.283 74.824,115.941C48.354,102.599 68.017,24.7 188.557,73.454C309.097,122.207 261.935,170.513 400,175.664" vector-effect="non-scaling-stroke"/>
</defs>
<use href="#path" class="path"/>
<use href="#star" class="star" x="0" y="-36">
<animateMotion dur="10s" repeatCount="indefinite" rotate="auto">
<mpath href="#path"/>
</animateMotion>
</use>
</svg>
</div>
我想我有一个好主意,用星锚元素替换原来的 svg 星。这样我就可以有第二个 SVG,其中包含保持其纵横比的实际星星,跟随星星锚。 随意看看。也许它给你任何想法。 但我认为这种方法的边缘无法以令人满意的方式消除。
明天我将回到我在评论中提到的想法。也就是尝试在JS中计算扭曲的路径。
const star = document.querySelector(".star-svg");
function moveStarToAnchor() {
const anchorRect = document.querySelector(".star_anchor").getBoundingClientRect();
star.style.translate = anchorRect.x+ "px " + anchorRect.y + "px";
}
setInterval(moveStarToAnchor, 100);
.wrapper {
width: 100vw;
height: 100vh;
overflow: hidden;
border: 1px solid blue;
display: grid;
position: relative;
}
.path-svg {
width: 100%;
height: 100%;
grid-column: 1/2;
grid-row: 1/2;
position: absolute;
}
.star-svg {
fill: red;
grid-column: 1/2;
grid-row: 1/2;
position: absolute;
top: 0;
left: 0;
width: 50px;
height: 50px;
transition: translate 100ms;
}
.path {
fill: none;
stroke: black;
stroke-width: 2px;
stroke-dasharray: 6 6;
stroke-linecap: round;
}
body {
margin: 0;
}
* {
box-sizing: border-box;
}
<div class="wrapper">
<svg class="path-svg" viewBox="0 0 400 200" preserveAspectRatio="none">
<defs>
<path id="star_anchor" d="M0,24.675L2.679" />
<path id="path" d="M0,36.608C0,36.608 64.096,15.519 92.956,48.531C121.816,81.542 101.293,129.283 74.824,115.941C48.354,102.599 68.017,24.7 188.557,73.454C309.097,122.207 261.935,170.513 400,175.664" vector-effect="non-scaling-stroke" />
</defs>
<use href="#path" class="path" />
<use href="#star_anchor" class="star_anchor" x="0" y="-36">
<animateMotion dur="10s" repeatCount="indefinite" rotate="auto">
<mpath href="#path" />
</animateMotion>
</use>
</svg>
<svg class="star-svg" viewBox="0 0 10 10" width="10" height="10">
<circle r="5" cx="5" cy="5" fill="red" />
</svg>
</div>