对于我正在开发的游戏,
我希望能够绘制一个SVG矩形;使用百分比值(50%将绘制矩形笔画的一半)。
我需要用Javascript执行此操作,因为我会经常更新该值。
<svg id="rectangle-timer" style="width:100%;height:100%;">
<rect width="100%" height="100%"/>
</svg>
我看到了不错的JS库,例如drawSVG或Vivus,但似乎它们可以使用路径,而不能使用矩形等基本形状。
任何人都可以帮忙吗?
谢谢。
答案 0 :(得分:2)
大多数库使用path
元素的原因是因为它们继承自SVGGeometryElement
原型,这为您提供了方便的函数来计算路径长度。因此,如果我们将这个矩形换成这样的路径:
<path d="M 0 0 L 1 0 L 1 1 L 0 1 z" />
我们得到完全相同的输出,但是它的可控性要强得多。之后,我们只需调整样式中的strokeDasharray
值即可扩展和删除一些笔触。对于此属性,我们只需要两个值:初始破折号和初始空白空间。因此,当进度为0时,我们希望第一个值为0,第二个为路径长度,而当我们接近1时,我们希望第二个值为0,第一个值增加为路径长度。
function update( amount ){
const total = rect.getTotalLength();
const filled = total * amount;
const none = total - filled;
rect.style.strokeDasharray = `${filled} ${none}`;
}
const rect = document.getElementById( 'rectangle' );
const input = document.getElementById( 'input' );
input.addEventListener( 'mousemove', event => update( input.value ));
update( input.value );
<svg width="200px" height="200px" viewBox="0 0 200 200">
<path d="M 20 20 L 180 20 L 180 180 L 20 180 z" id="rectangle" fill="none" stroke="black" stroke-width="10" />
</svg>
<input id="input" type="range" min="0" max="1" step=".01" />
如果您坚持使用rect
,则可以通过两次获取矩形的宽度和高度来获得其路径长度,如下所示:
function update( amount ){
const total = rect.width.baseVal.value * 2 + rect.height.baseVal.value * 2;
const filled = total * amount;
const none = total - filled;
rect.style.strokeDasharray = `${filled} ${none}`;
}
const rect = document.getElementById( 'rectangle' );
const input = document.getElementById( 'input' );
input.addEventListener( 'mousemove', event => update( input.value ));
update( input.value );
<svg width="200px" height="200px" viewBox="0 0 200 200">
<rect x="20" y="20" width="160" height="160" id="rectangle" fill="none" stroke="black" stroke-width="10" />
</svg>
<input id="input" type="range" min="0" max="1" step=".01" />
但是,从长远来看,这将意味着通用性会降低,因此我建议切换到path
。
答案 1 :(得分:1)
这是我的解决方案:SVG具有preserveAspectRatio ="none" style="width:100%;height:100vh;"
路径的总长度为2*window.innerWidth + 2*window.innerHeight;
stroke-dasharray
和stroke-dashoffset
都等于路径的总长度。
我正在使用输入type =“ range”为stroke-dashoffset
设置动画。
为了保留笔触宽度并避免拉伸,我使用vector-effect="non-scaling-stroke"
我希望这是您所需要的。
function timer(){
let totalLength = 2*window.innerWidth + 2*window.innerHeight;
thePath.setAttributeNS(null, "style", `stroke-dashoffset:${totalLength * (1-range.value)}`)
}
timer()
range.addEventListener("input",timer);
setTimeout(function() {
timer()
addEventListener('resize', timer, false);
}, 15);
*{margin:0; padding:0;}
#thePath {
stroke-dasharray: calc(2 * 100vw + 2* 100vh);
stroke-dashoffset: calc(2 * 100vw + 2* 100vh);
}
#rectangle-timer{background:#dfdfdf}
[type="range"] {
position: absolute;
display: block;
width: 200px;
height: 20px;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
<svg id="rectangle-timer" viewBox="0 0 100 100" preserveAspectRatio ="none" style="width:100%;height:100vh;">
<path id="thePath" d="M0,0L100,0 100,100 0,100 0,0" fill="none" stroke="skyBlue" stroke-width="25" vector-effect="non-scaling-stroke" />
</svg>
<input type="range" id="range" value=".5" min="0" max="1" step=".01" />