我已经陷入一个无法找到任何信息的问题,也许某个在svg方面有丰富经验的人可以伸出援手。
我以编程方式(以下代码)创建了svg星,并希望动态更改其linearGradient
offset
。当您在检查器中查看时,该值将按预期随着时间变化,到达目标时动画将被取消。问题是-svg不再出现...
HTML:
<div id="newStars"></div>
CSS:
svg[id*='svg'] {
transform: scale(0);
}
#icon-star1, .animation {
transform-origin: 50% 50%;
animation: animateStar 1s linear forwards;
}
@keyframes animateStar {
0% {
transform: scale(0) rotate(0deg);
}
50% {
transform: scale(1.1) rotate(180deg);
}
75% {
transform: rotate(360deg);
}
100% {
transform: scale(1);
}
}
JS:
function createStar(nb) {
const svgns = 'http://www.w3.org/2000/svg';
const svg = document.createElementNS(svgns, 'svg');
const defs = document.createElementNS(svgns, 'defs');
const gradient = document.createElementNS(svgns, 'linearGradient');
const g = document.createElementNS(svgns, 'g');
const path = document.createElementNS(svgns, 'path');
const div = document.createElement('div');
const stops = [
{
'color': 'red',
'offset': '0%',
}, {
'color': 'lightgrey',
'offset': '0%',
},
];
for (let i = 0; i < stops.length; i++) {
const stop = document.createElementNS(svgns, 'stop');
stop.setAttribute('stop-color', stops[i].color);
stop.setAttribute('offset', stops[i].offset);
gradient.appendChild(stop);
}
// Apply the <lineargradient> to <defs>
gradient.id = `Gradient${nb}`;
gradient.setAttribute('x1', '0');
gradient.setAttribute('x2', '100%');
gradient.setAttribute('y1', '0');
gradient.setAttribute('y2', '0');
defs.appendChild(gradient);
g.id = `g${nb}`;
path.setAttribute('stroke', 'blue');
path.setAttribute('stroke-width', '2');
path.setAttribute('width', '100%');
path.setAttribute('height', '100%');
path.setAttribute('d', 'M20.388,10.918L32,12.118l-8.735,7.749L25.914,31.4l-9.893-6.088L6.127,31.4l2.695-11.533L0,12.118 l11.547-1.2L16.026,0.6L20.388,10.918z');
path.setAttribute('fill', `url(#Gradient${nb})`);
svg.setAttribute('width', '100%');
svg.setAttribute('height', '100%');
svg.setAttribute('version', '1.1');
svg.setAttribute('xmlns', svgns);
// svg.setAttribute('viewBox', '0 0 50 50');
svg.id = `svg${nb}`;
div.setAttribute('style', 'width:35px; height:35px;');
svg.appendChild(defs);
svg.appendChild(g);
g.appendChild(path);
div.appendChild(svg);
document.querySelector('#newStars').appendChild(div);
let ii=0;
function anim() {
ii++;
$(`#Gradient${ nb } stop`)[0].setAttribute('offset', `${ii / 10}%`);
$(`#Gradient${ nb } stop`)[1].setAttribute('offset', `${ii / 10}%`);
if (ii >= 1000) {cancelAnimationFrame(anim_id)} else requestAnimationFrame(anim);
}
let anim_id = requestAnimationFrame(anim);
}
createStar(1);
createStar(2);
createStar(3);
第一次尝试是在循环中创建setTimeout's
,但是即使按预期工作,我也发现它效率很低,并且在最后一次setTimeout
发生之后同步调用另一个函数特别麻烦。这是可供参考的工作代码:
setTimeout(() => {
for (let i = 1; i <= 1000; i++) {
setTimeout(() => {
$(`#Gradient${ nb } stop`)[0].setAttribute('offset', `${i / 10}%`);
$(`#Gradient${ nb } stop`)[1].setAttribute('offset', `${i / 10}%`);
}, i);
}
$(`#svg${nb}`).addClass('animation');
}, 1000 * (nb - 1));