JavaScript: SVG-Animationen
Mit JavaScript lassen sich SVGrafiken auch animieren. Dazu müssen diese in den HTML-Quelltext eingebunden sein.
Code kopieren
<svg width='320px' height='320px'>
<!-- Hauptachsen; umlaufende Strecke; Endpunkte; -->
<line class='line2c' x1='0' y1='160.5' x2='320' y2='160.5' />
<line class='line2c' x1='160.5' y1='0' x2='160.5' y2='320' />
<line id='l1_0' class='line2' x1='320.5' y1='160.5' x2='160.5' y2='160.5' />
<circle id='c1_0' class='line2' cx='320.5' cy='160.5' r='1' />
<circle id='c2_0' class='line2' cx='160.5' cy='160.5' r='1' />
<!-- Ellipse; Brennpunkte; Strecken PF1, PF2 -->
<ellipse class='line1' cx='160.5' cy='160.5' rx='100' ry='60' />
<circle class='line1b' cx='80.5' cy='160.5' r='2' />
<circle class='line1b' cx='240.5' cy='160.5' r='2' />
<line id='l2_0' class='line1c' x1='260.5' y1='160.5' x2='80.5' y2='160.5' />
<line id='l3_0' class='line1c' x1='260.5' y1='160.5' x2='240.5' y2='160.5' />
<!-- Schnittpunkt; Mittelpunkt; -->
<circle id='c3_0' cx='260.5' cy='160.5' r='3' />
<circle class='line2b' cx='160.5' cy='160.5' r='2' />
</svg>
<script>
var a_0 = 100;
var b_0 = 60;
var tu_0 = 360;
var t_0 = 0;
doAnimation_0 = function() {
alpha_0 = t_0 / tu_0 * 2 * Math.PI;
var x1_0 = Math.cos(alpha_0) * (a_0 + b_0);
var y2_0 = Math.sin(alpha_0) * (a_0 + b_0);
var px_0 = Math.cos(alpha_0) * a_0;
var py_0 = Math.sin(alpha_0) * b_0;
document.getElementById('l1_0').setAttribute('x1', 160.5 + x1_0);
document.getElementById('l1_0').setAttribute('y2', 160.5 - y2_0);
document.getElementById('l2_0').setAttribute('x1', 160.5 + px_0);
document.getElementById('l2_0').setAttribute('y1', 160.5 - py_0);
document.getElementById('l3_0').setAttribute('x1', 160.5 + px_0);
document.getElementById('l3_0').setAttribute('y1', 160.5 - py_0);
document.getElementById('c1_0').setAttribute('cx', 160.5 + x1_0);
document.getElementById('c2_0').setAttribute('cy', 160.5 - y2_0);
document.getElementById('c3_0').setAttribute('cx', 160.5 + px_0);
document.getElementById('c3_0').setAttribute('cy', 160.5 - py_0);
t_0++;
}
setInterval(doAnimation_0, 50);
</script>
Oder eine „analoge“ Uhr:
Code kopieren
<svg id='clock' width='225' height='225'>
<defs>
<filter id='shadow' filterUnits='userSpaceOnUse'>
<feGaussianBlur in='SourceAlpha' stdDeviation='1' />
<feOffset dx='2' dy='2' result='offsetblur' />
<feComponentTransfer>
<feFuncA type='linear' slope='.8'/>
</feComponentTransfer>
<feMerge>
<feMergeNode />
<feMergeNode in='SourceGraphic' />
</feMerge>
</filter>
<radialGradient id='grad1' r='100%' cx='51.077062133199%' cy='51.077062133199%' spreadMethod='pad'>
<stop offset='46.238402061856%' stop-color='hsl(220,35%,30%)' />
<stop offset='47.738402061856%' stop-color='hsl(220,35%,10%)' />
<stop offset='49.261597938144%' stop-color='hsl(220,35%,10%)' />
<stop offset='50.761597938144%' stop-color='hsl(220,35%,30%)' />
</radialGradient>
</defs>
<circle id='c1' cx='50%' cy='50%' r='50%' fill='url(#grad1)' />
<circle id='c2' cx='50%' cy='50%' r='47%' fill='hsl(220,10%,50%)' />
<g id='scales'></g>
<line stroke='hsl(220,10%,10%)' stroke-width='7.5' filter='url(#shadow)' />
<line stroke='hsl(220,10%,10%)' stroke-width='5.625' filter='url(#shadow)' />
<line stroke='hsl(0,85%,32%)' stroke-width='2.25' filter='url(#shadow)' />
</svg>
<script>
r = document.getElementById('clock').getAttribute('width') / 2;
out = '';
for (i = 0; i < 60; i++) {
out += '<line stroke=\'hsl(23,35%,10%)\' />';
}
document.getElementById('scales').innerHTML = out;
lines = document.getElementById('clock').getElementsByTagName('line');
d = [
[r * .05, r * .91, r * .76],
[r * .01, r * .90, r * .83]
];
for (i = 0; i < 60; i++) {
if (i % 5) e = 1; else e = 0;
lines[i].setAttribute('stroke-width', d[e][0]);
rad = i * Math.PI / 30;
lines[i].setAttribute('x1', r + d[e][1] * Math.cos(rad));
lines[i].setAttribute('y1', r + d[e][1] * Math.sin(rad));
lines[i].setAttribute('x2', r + d[e][2] * Math.cos(rad));
lines[i].setAttribute('y2', r + d[e][2] * Math.sin(rad));
}
function setNeedle(id, l, rad) {
lines[id].setAttribute('x1', r + l * Math.cos(rad));
lines[id].setAttribute('y1', r + l * Math.sin(rad));
lines[id].setAttribute('x2', r - r * .1 * Math.cos(rad));
lines[id].setAttribute('y2', r - r * .1 * Math.sin(rad));
}
function setClock() {
dateObject = new Date();
hours = dateObject.getHours();
minutes = dateObject.getMinutes();
seconds = dateObject.getSeconds();
setNeedle(60, r * .5, (hours + minutes / 60 + seconds / 3600) * Math.PI / 6 - Math.PI / 2); // needle for hours
setNeedle(61, r * .71, (minutes + seconds / 60) * Math.PI / 30 - Math.PI / 2); // needle for minutes
setNeedle(62, r * .71, seconds * Math.PI / 30 - Math.PI / 2); // needle for seconds
}
setInterval(setClock, 100);
</script>
Oder eine Uhr mit 7-Segmente-LCD-Anzeige:
Code kopieren
<svg id='digiclock'></svg>
<script>
scale = 1.5; /// scale factor
m = 20; // outer margin
u = scale * 10; // base unit (segment width)
width = 2 * m + u * 34;
height = 2 * m + u * 8;
segs = [
"M-1,-2 L2,-5 L33,-5 L36,-2 L29,5 L6,5 Z",
"M-2,-1 L5,6 L5,29 L0,34 L-5,29 L-5,2 Z",
"M37,-1 L40,2 L40,29 L35,34 L30,29 L30,6 Z",
"M1,35 L6,30 L29,30 L34,35 L29,40 L6,40 Z",
"M0,36 L5,41 L5,64 L-2,71 L-5,68 L-5,41 Z",
"M35,36 L40,41 L40,68 L37,71 L30,64 L30,41 Z",
"M-1,72 L6,65 L29,65 L36,72 L33,75 L2,75 Z"
];
out = "<rect fill='hsl(80,10%,40%)' x='0' y='0' width='" + width + "' height='" + height + "' />";
out += "<g transform='translate(" + (u * .6 + m + u / 2) + " " + (m + u / 2) + ") skewX(-5) scale(" + scale + ")'>";
for (d = 0; d < 6; d++) {
out += "<g transform='translate(" + ([0, 55, 130, 185, 254, 298][d]) + " " + (d > 3 ? 15 : 0) + ")" + (d > 3 ? " scale(.8)" : "") + "'>";
for (s = 0; s < 7; s++) out += "<path id='seg" + d.toString() + s.toString() + "' d='" + segs[s] + "' fill='hsl(80,10%,17%)' opacity='0' />";
out += "</g>";
}
out += "<circle id='ci1' fill='hsl(80,10%,17%)' opacity='0' cx='110' cy='20' r='6' />";
out += "<circle id='ci2' fill='hsl(80,10%,17%)' opacity='0' cx='110' cy='55' r='6' />";
out += "</g>";
svg = document.getElementById('digiclock');
svg.setAttribute("width", width );
svg.setAttribute("height", height);
svg.innerHTML = out;
b = [
"1110111", "0010010", "1011101", "1011011", "0111010",
"1101011", "1101111", "1010010", "1111111", "1111011"
];
function digiclock() {
now = new Date(Date.now());
hrs = now.getHours();
min = now.getMinutes();
sec = now.getSeconds();
digits = hrs.toString().padStart(2, "0") + min.toString().padStart(2, "0") + sec.toString().padStart(2, "0");
for (d = 0; d < 6; d++) for (s = 0; s < 7; s++) document.getElementById("seg" + d.toString() + s.toString()).setAttribute("opacity", b[digits[d]][s]);
document.getElementById("ci1").setAttribute("opacity", sec % 2 ? 0 : 1);
document.getElementById("ci2").setAttribute("opacity", sec % 2 ? 0 : 1);
requestAnimationFrame(digiclock);
}
requestAnimationFrame(digiclock);
</script>
Oder die Berlin-Uhr:
Code kopieren
<div class='center'><svg id='berlinuhr'></svg></div>
<script>
function initClock() {
u = 8; // this value controls the size of the clock (width of segment border)
g = u * 1.5; // gap between rows
sw1 = u * 6.5; // width of wide segments
sw2 = (4 * sw1 - 7 * u) / 11; // width of narrow segments
h = u * 4.8; // height of segments
offset = 2 * (h + u) + g; // y-pos of top row
width = 4 * sw1 + 5 * u; // overall width
height = offset + 4 * (h + 2 * u) - u + 3 * g; // overall height
cx = width / 2; // horizontal center of top light
cy = h + u / 2; // vertical center of top light
yellow = "hsl(45,100%,20%)";
red = "hsl(10,100%,20%)";
defs = "<defs>";
for (i = 0; i < 3; i++) {
defs += "<radialGradient id='yellow" + i + "' r='50%' cx='50%' cy='50%' fx='50%' fy='50%' spreadMethod='pad'>";
defs += "<stop offset='0%' stop-color='hsl(45,100%,75%)' />";
defs += "<stop offset='100%' stop-color='hsl(45,100%,50%)' />";
defs += "</radialGradient>";
}
for (i = 1; i < 3; i++) {
defs += "<radialGradient id='red" + i + "' r='50%' cx='50%' cy='50%' fx='50%' fy='50%' spreadMethod='pad'>";
defs += "<stop offset='0%' stop-color='hsl(40,100%,65%)' />";
defs += "<stop offset='100%' stop-color='hsl(10,100%,45%)' />";
defs += "</radialGradient>";
}
defs += "</defs>";
out = "<circle id='seg1' fill='" + yellow + "' cx='" + (cx) + "' cy='" + (cy) + "' r='" + (h) + "' />";
out2 = "<circle stroke='silver' stroke-width='" + (u) + "' fill='none' cx='" + (cx) + "' cy='" + (cy) + "' r='" + (h) + "' />";
out3 = "<path fill='gray' d='M" + (12.5 * u) + "," + (offset - u) + " A" + (g / 2) + "," + (g / 2) + " 0 0,0 " + (12.5 * u) + "," + (offset - 3.2 * u) + " L" + (width - 12.5 * u) + "," + (offset - 3.2 * u) + " A" + (g / 2) + "," + (g / 2) + " 0 0,0 " + (width - 12.5 * u) + "," + (offset - u) + " Z' />";
for (y = 0; y < 4; y++) {
for (x = 0; x < (y == 2 ? 11 : 4); x++) {
w = (y == 2 ? sw2 : sw1);
xpos = u + x * (w + u);
ypos = offset + y * (h + 2 * u + g);
fill = (y < 2 || (y == 2 && !((x + 1) % 3)) ? red : yellow);
out += "<rect id='seg" + (y + 2) + "_" + (x) + "' fill='" + fill + "' x='" + (xpos) + "' y='" + (ypos) + "' width='" + (w) + "' height='" + (h) + "' />";
xpos -= u / 2;
if (x) out2 += "<line stroke='silver' stroke-width='" + (u) + "' stroke-linecap='square' x1='" + (xpos) + "' y1='" + (ypos) + "' x2='" + (xpos) + "' y2='" + (ypos + h) + "' />";
}
out2 += "<rect stroke='silver' stroke-width='" + (u) + "' fill='none' x='" + (u / 2) + "' y='" + (offset + y * (h + 2 * u + g) - u / 2) + "' width='" + (4 * (sw1 + u)) + "' height='" + (h + u) + "' rx='" + (u * 1.75) + "' />";
if (y) {
for (i = 0; i < 2; i++) {
xs = u + 2 * i * (u + sw1);
out3 += "<path fill='gray' d='M" + (xs + .5 * sw1 - g / 4) + "," + (ypos - u) + " A" + (g / 2) + "," + (g / 2) + " 0 0,0 " + (xs + .5 * sw1 - g / 4) + "," + (ypos - u - g) + " L" + (xs + u + 1.5 * sw1 + g / 4) + "," + (ypos - u - g) + " A" + (g / 2) + "," + (g / 2) + " 0 0,0 " + (xs + u + 1.5 * sw1 + g / 4) + "," + (ypos - u) + " Z' />";
}
}
}
svg = document.getElementById("berlinuhr");
svg.setAttribute("width", width);
svg.setAttribute("height", height);
svg.innerHTML = defs + out + out3 + out2;
document.getElementById("yellow0").setAttribute("r", "30%");
document.getElementById("yellow1").setAttribute("gradientTransform", "scale(1, .4) translate(0, .7)");
document.getElementById("yellow2").setAttribute("gradientTransform", "scale(.7, 1) translate(.22, 0)");
document.getElementById("red1").setAttribute("gradientTransform", "scale(1, .4) translate(0, .7)");
document.getElementById("red2").setAttribute("gradientTransform", "scale(.7, 1) translate(.22, 0)");
}
function setClock2() {
dObj = new Date();
hours = dObj.getHours();
minutes = dObj.getMinutes();
seconds = dObj.getSeconds();
tests = [hours / 5, hours % 5, minutes / 5, minutes % 5];
document.getElementById("seg1").setAttribute("fill", (seconds % 2 ? yellow : "url(#yellow0)"));
for (y = 0; y < 4; y++) {
n = +(y != 2) + 1;
for (x = 0; x < (y == 2 ? 11 : 4); x++) {
cond = +(Math.floor(tests[y]) > x);
fill = (
y < 2 || (y == 2 && !((x + 1) % 3)) ?
[red, "url(#red" + n + ")"][cond] :
[yellow, "url(#yellow" + n + ")"][cond]
);
document.getElementById("seg" + (y + 2) + "_" + x).setAttribute("fill", fill);
}
}
}
initClock();
setInterval(setClock2, 100);
</script>
Beschreibung: JavaScript: SVG-Animationen
Stichworte: webdesign,webgestaltung,programmierung,javascript,anleitung,tutorial,svg,animationen
Stichworte: webdesign,webgestaltung,programmierung,javascript,anleitung,tutorial,svg,animationen