Новогодний конкурс 2020 года!

311
08 января 2022, 11:30

В прошлом году подобный конкурс неожиданно привлек большой интерес участников RUso.

Было весело, люди хотели продолжение праздника вновь и вновь.
К слову, было проведено 4 конкурса с вознаграждением.

Почему бы нам не устроить точно такой же, а может быть ещё лучше праздник в наступающем Новом 2020 году!

Я выбрал достаточно нейтральную картинку с тёмным фоном, так как слышал мнения, что неплохо было бы в этом году сделать работы с гирляндами, фейерверками.

Рекомендуемые объекты в решении конкурсного задания:

  1. Анимация заголовка С Новым 2020 годом!
  2. Анимация Деда Мороза, Снегурочки и других новогодних персонажей
  3. Новогодняя ёлочка: ёлочные игрушки, гирлянды
  4. Анимация звездного неба
  5. Анимация снежинок
  6. Фейерверки, хлопушки

Для примера анимация луны:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"  viewBox="0 0 73 73" >
<defs>
 <radialGradient id="RadialGrad"
           fx="50%" fy="50%" r="65%"
           spreadMethod="pad">
          <stop offset="0%"   stop-color="#E7D68C" stop-opacity="1"/>
          <stop offset="100%" stop-color="#FFFEED" stop-opacity="1" />
        </radialGradient>
</defs>
<rect width="100%" height="100%" />
<g transform="rotate(-20 35.5 35.5)">
<circle cx="35.5" cy="35.5" r="35" stroke="none"  fill="url(#RadialGrad)" />
 <circle cx="35.5" cy="35.5" r="35" stroke="none" fill="black" >
 
 <animate id="youngMoon" attributeName="cx" values="35.5;-35.5;" begin="1s;oldMoon.end+1s" dur="10s" fill="freeze" />
<animate id="oldMoon" attributeName="cx" values="105;35.5;" begin="youngMoon.end+1s" dur="10s"  fill="freeze" /> 
</circle> 
</g>
</svg>

Анимация звезды на ёлочке

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
       width="100%" height="100%" viewBox="0 0 1680 1050" preserveAspectRatio="xMinYMin meet" > 
  <defs>
  <filter id="glow" filterUnits="userSpaceOnUse"
            x="-50%" y="-50%" width="300%" height="300%">
       
      <feGaussianBlur in="SourceGraphic" stdDeviation="25" result="blur5"/>
      <feGaussianBlur in="SourceGraphic" stdDeviation="30" result="blur10"/>
      <feGaussianBlur in="SourceGraphic" stdDeviation="40" result="blur20"/>
      <feGaussianBlur in="SourceGraphic" stdDeviation="50" result="blur30"/>
      <feGaussianBlur in="SourceGraphic" stdDeviation="70" result="blur50"/>
       <feMerge result="blur-merged">
        <feMergeNode in="blur10"/>
        <feMergeNode in="blur20"/>
        <feMergeNode in="blur30"/>
        <feMergeNode in="blur50"/>
      </feMerge>
      
      <feColorMatrix result="yellow-blur" in="blur-merged" type="matrix"
                     values="0 0 0 0 0
                             0 1 0 0 0
                             0 0 1 0 0
                             0 0 0 0.7 0" />
      <feMerge>
        <feMergeNode in="yellow-blur"/>       
        <feMergeNode in="blur5"/>          
        <feMergeNode in="SourceGraphic"/>  
      </feMerge>
    </filter>
  </defs>  
<image xlink:href="https://i.stack.imgur.com/PBRad.jpg" width="100%" height="100%" />
    
  <path id="star_Full" fill="#E4F6A3"  filter="url(#glow)" opacity="0" d="M580.2 76.2 837.2 71.3 774.7 5.7 845.1 62.7 850.1 8c0 0 6.8 54.2 6 54.7-4.3 2.8 70.9-57.5 70.9-57.5L862.8 71.2 1131.2 76.2 864.4 81.8 982.3 203C960.8 189.7 856.8 91.3 856.7 91.2L849.8 194.2 845.7 91.1 714.3 203.7 832.8 82.5Z">
    <animate
        id="an_star"
        attributeName="opacity"
        dur="1.5s"
        begin="1s;pause_star.end"
        values="1;1;0"              
        fill="freeze"
        repeatCount="5" /> 
    <animate
        id="pause_star"
        attributeName="opacity"
        dur="1.5s"
        begin="an_star.end"
        values="0;0"                
        fill="freeze"
        repeatCount="1" />  
   </path>      
     
<svg> 

От одного участника может быть от одного до трех ответов, в отдельных постах.

Поздравляем победителя Stranger in the Q!

Добавлено объявление в топик-приглашение к конкурсу

Answer 1

Салют в лесу

let s; 
Math.random = () => (2**31-1&(s=Math.imul(48271,s)))/2**31; 
 
let rnd = n => (Math.random()-0.5)*(n||1); 
let many = (n,f) => Array(n).fill(0).map((e,i) => f(i)); 
let fireworks = fireworksCanvas.getContext("2d"); 
let forest = forestCanvas.getContext("2d"); 
let g, i, c; 
 
function newSeg(s, dir, da, w){ 
    return { 
      da, // шаг изменения угла 
      col: s.col, // цвет 
      width: w||s.width - 0.02, // толщина 
      pts: [s.pts[2], s.pts[3]], // точки сегмента 
      dir: dir+da, // направление (угол) текущего сегмента 
      len: s.len, // длина сегмента 
      sw: s.sw  // коэффициент для поворота (наследуется от прошлого сегмента) 
    }; 
} 
 
// алгоритм "роста" сегментов на основе данных о прошлом сегменте 
function grow() { 
    i = 0, c = rnd(360); 
    let da = rnd(); // случайный компонент поворота 
    let n = 5+Math.floor(Math.random()*19); // кол-во ветвей 
    let s = 2 + rnd(1); // размер сегмента 
    let pts = [(0.25+Math.random()*0.5)*innerWidth, (0.2+Math.random())*innerHeight/3] 
    g = many(n, i => ({ 
        pts, 
        dir: Math.PI/n*i*2 + rnd() + da, 
        len: s,  
        width: 10, 
        sw:  1.01 + rnd(0.02), 
        col: `hsl(${Math.random()*360},66%,66%)` 
    })) 
    requestAnimationFrame(growIteration); 
} 
 
function growStep(count) { 
  fireworks.fillStyle="#00000014"  
  fireworks.fillRect(-1e5,-1e5,2e5,2e5) 
  for (var j=0; j<count; j++, i++){ 
    g = g.flat().map(s => { 
        calcSegment(s); 
        paintSegment(s); 
        return growAlgorithm(s); 
    }); 
  } 
} 
 
// алгоритм "роста" 
function growAlgorithm(s) { 
 
  let result = [] 
 
  if(s.width < 0) 
     return result;  
    
   let sw = rnd(0.05) // небольшой коэф. для поворота 
 
   //  если толщина сегмента больше 1 то с какой-то вероятностью делим ветвь на 3 
   if (s.width>1 && rnd() > 0.45) { 
 
     let dir = 0.5 + rnd(0.5); // случайное направление 
     let w = s.width/2 +0.5; // делаем новые ветви тоньше 
     result.push(newSeg(s, s.dir+dir + rnd(), sw, w));  
     result.push(newSeg(s, s.dir-dir+ rnd(), -sw, w)); 
     result.push(newSeg(s, s.dir,-sw, w)); 
        
   } else if (rnd() > 0.45) {  
      
     // растем дальше и поворачиваем на коэф. этой итерации 
     result.push(newSeg(s, s.dir, sw)); 
 
   } else { //  или растем дальше и поворачиваем на коэф. текущей ветки 
 
     result.push(newSeg(s, s.dir, (s.da||0)*s.sw)); 
        
   } 
 
   return result; 
} 
 
function calcSegment(s) { 
  let x = s.pts[0] + Math.cos(s.dir)*s.len; 
  let y = s.pts[1] + Math.sin(s.dir)*s.len; 
  s.pts.push(x,y) 
} 
 
function growIteration() { 
    if (g.length)  
        requestAnimationFrame(growIteration); 
    else grow(0,0) 
    growStep(1) 
} 
 
function paintSegment(s) { 
  fireworks.lineWidth = 1; 
  fireworks.lineCap ="round" 
  fireworks.strokeStyle=s.col; 
  fireworks.beginPath(); 
  fireworks.moveTo(s.pts[0], s.pts[1]) 
  fireworks.lineTo(s.pts[2], s.pts[3]); 
  fireworks.stroke(); 
} 
 
function star(c) { 
    c.beginPath(); 
    c.arc(Math.random()*innerWidth,  
          Math.random()*innerHeight, 
          Math.random(),  
          0,  
          2 * Math.PI 
    ); 
    c.fill(); 
} 
 
function moon(c) { 
  c.beginPath(); 
  c.arc(100, 100, 30, Math.PI/2, -Math.PI/2); 
  c.bezierCurveTo(75, 85, 75, 115, 100, 130); 
  c.fill(); 
} 
 
function snowHill(c){ 
   c.beginPath(); 
   c.arc(Math.random()*innerWidth,  
         innerHeight*5+(Math.random()*0.3+0.7)*innerHeight,  
         innerHeight*5,  
         0, Math.PI*2);  
   c.fill();  
} 
 
function resize() { 
  s = 1; 
  resizeCanvas(fireworksCanvas); 
  resizeCanvas(forestCanvas); 
  forest.fillStyle = 'white'   
  moon(forest); 
  forest.shadowColor = "black"; 
  many(100, i => star(forest));  
  forest.shadowBlur = 7; 
  many(6, i => snowHill(forest)); 
  forest.shadowBlur = 13;      
  many(parseInt(innerWidth/20), i => [ 
      Math.random()*innerWidth, 
      innerHeight - Math.random()*Math.random()*innerHeight/6-Math.min(90,innerHeight/5) 
  ]).sort((a, b) => a[1] - b[1]).map(p => { 
      let ky = p[1]/innerHeight; 
      let h = 88+Math.random()*33; 
      let s = 44+Math.random()*10; 
      many(5, i => { 
          forest.fillStyle = `hsl(${h},${s}%,${15 + i*(5 + Math.random()*5)}%)`; 
          level(p[0], p[1] - 10*i, ky*70-(i*10), i) 
      }) 
  }) 
} 
 
let treeLevel = [ 
    [ 
        -0.25, 1, 
        -0.5,  2, 
        -1,    2 
    ], [ 
        -0.5, 2, 
        -0.35, 1.75, 
        -0.2, 1.5 
    ], [ 
        -0.15, 1.7, 
        -0.15, 1.7, 
        0,    2.25 
    ], [ 
        0.15, 1.7, 
        0.15, 1.7, 
        0.15, 1.5 
    ], [ 
        0.35, 1.75, 
        0.5, 2, 
        1,    2 
    ],[ 
        0.5, 2, 
        0.25, 1, 
        0,   0 
    ] 
] 
 
function level(x,y,s) { 
  s = Math.max(0,s) 
  let c = forest; 
  c.beginPath(); 
  c.moveTo(x, y); 
  let d = 2 
  treeLevel.forEach(curve => c.bezierCurveTo( 
      x+s*curve[0]+rnd(d), y+s*curve[1]+rnd(d),  
      x+s*curve[2]+rnd(d), y+s*curve[3]+rnd(d),  
      x+s*curve[4]+rnd(d), y+s*curve[5]+rnd(d) 
  )); 
  c.closePath(); 
  c.fill(); 
} 
 
function resizeCanvas(canvas) { 
  if (canvas.width !== innerWidth || canvas.height !== innerHeight) { 
     canvas.width = innerWidth; 
     canvas.height = innerHeight; 
  } 
} 
 
addEventListener("resize", resize); 
resize(); 
grow()
body { 
    background-color: black; 
    margin: 0; 
    overflow: hidden; 
} 
 
canvas { 
    position: fixed; 
}
<canvas id=fireworksCanvas ></canvas> 
<canvas id=forestCanvas ></canvas>

Answer 2

Осторожно, тут нужна видеокарта.

let toy = new ShaderToy(` 
 
// перевод из палитры hsl в палитру rgb 
vec3 hsl2rgb(vec3 c) { 
  vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0); 
  return c.z + c.y * (rgb-0.5)*(1.0-abs(2.0*c.z-1.0)); 
} 
 
// генератор псевдослучайных чисел 
float random (vec2 p) { 
    return fract(sin(dot(p,vec2(12.9898,78.233)))*43758.5453123); 
} 
 
// один залп 
vec4 firework(vec2 p, float n) { 
 
    float dur = 3000.; // время анимации одного фейерверка 
    float id = floor(time/dur-n) + n*8.; // число - идентификатор залпа 
    float t = smoothstep(0., 1., fract(time/dur-n)); // время анимации 
    float t1 = max(0.0, 0.5 - t); // время второй фазы (взрыва) 
    float t2 = max(0.0, t - 0.5); // 
     
    p.y += t1; // первую половину времени летим снизу вверх  
    p.y -= random(vec2(n*35.+id, n*45.+id))*0.3; // немного по оси y на случ. величину 
 
    p.x += n - 0.5 + mix(0., sin(id)*0.4, t1); // немного по оси x на случ. 
     
    vec4 c; 
    if ( dot(p,p) > 0.002 + t2 *0.1 ) // если пиксель слишком далеко 
        return c;  
         
    // цвет частицы     
    vec3 rgb = hsl2rgb(vec3(id*0.3, .8, .7));  
     
    for (float i = 0.; i < 77.; i += 1.) { 
     
        // угол отлета отлёта 
        float angle = i+sin(i*1234. + t);  
         
        // дистанция отлёта 
        float dist = 0.2 + 0.2 * random(vec2(i*351. + id, i*135. + id));  
         
        // конечная точка частицы 
        vec2 pt = p + vec2(dist*sin(angle), dist*cos(angle));  
         
        // находим интерполяцией текущее положение 
        pt = mix(p, pt, t2);  
 
        // радиус частицы 
        float r = .03 * (1. - t) * t2 + 
                  .002*t*t*(1. - max(.0, t - .9)*10.);   
                   
        // яркость пикселя 
        float d = 1. - smoothstep(sqrt(dot(pt, pt)), .0, r);  
         
        if (t>0.75 && fract(id/3.)<0.3) 
          d *= 0.6 + sin(111.*(i+id*88.+t))*0.4; 
 
        c += vec4(rgb, 1.) * d; 
    } 
    return c; 
} 
 
void main(void) { 
  vec2 uv = gl_FragCoord.xy/resolution - 0.5; 
  uv.x *= resolution.x/resolution.y;  
  for (float n = 0.; n < 6.; n += 1.)  
      gl_FragColor += firework(uv, n/6.) - 0.05; // рисуем несколько фейерверков 
}`); 
 
addEventListener("resize", () => toy.resize(innerWidth, innerHeight)); 
toy.resize(innerWidth, innerHeight); 
requestAnimationFrame(draw); 
 
function draw(t) { 
   requestAnimationFrame(draw); 
   toy.draw(t)  
}
canvas { 
  background: url('https://i.stack.imgur.com/PBRad.jpg'); 
  background-size: cover; 
  position: fixed; 
  top: 0; 
  left: 0; 
}
<script src="https://raw.githack.com/strangerintheq/ShaderToy/master/ShaderToy.js"></script>

PS: если кому-то будет интересно как это работает - спрашивайте...

Answer 3

Для затравки первая работа :)

Осторожно, при запуске включается музыкальное сопровождение.

Используется трек Дискотека Авария - Новогодняя

Это было только начало сюжета. Полную версию анимации смотрите в этом же - топике

<div class="container"> 
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"  
    xmlns:xlink="http://www.w3.org/1999/xlink" 
       width="100%" height="100%" viewBox="0 0 1680 1050" preserveAspectRatio="xMinYMin meet" >   
<defs> 
 <filter id="shadow" x="-20%" y="-20%" width="140%" height="140%"> 
            <feDropShadow dx="4" dy="8" stdDeviation="4"/> 
        </filter> 
</defs> 
 
	   <!-- Изображение Ёлочки --> 
<image xlink:href="https://i.stack.imgur.com/PBRad.jpg" width="100%" height="100%" /> 
 
    
	  <path id="path1" d="m1648.6 24.4c0 0-341.5 179.4-456.4 327.2-102.2 131.4-97.5 174.6-169 242.2-125.1 118.5-275.2 220.3-439.5 272.1-61.6 19.4-193.6 11-193.6 11v0" style="fill:none;stroke-opacity:0.9;stroke-width:2;stroke:none"/> 
	    
 
<image  id="fly"   xlink:href="https://i.stack.imgur.com/qnNmf.png" width="2%" height="2%"  opacity="1" > 
  	 	 
	<animateMotion 
	  id="MotionHal" 
	  begin="btn.click+8s" 
	  dur="14s" 
	  fill="freeze" 
	  rotate="auto-reverse" 
	  repeatCount="1"  > 
    <mpath xlink:href="#path1" /> 
    </animateMotion>  
	<animateTransform id="an_fly" attributeName="transform" type="scale" begin="MotionHal.begin" dur="14s"   values="1;2;2;2;4;6;8;9" fill="freeze" repeatCount="1" />   
	 
</image>     
                 <!-- Анимация зайчика с гитарой  --> 
     <image  id="zayka" filter="url(#shadow)" transform="translate(1050 750) scale(1 1)" x="0" xlink:href="https://i.stack.imgur.com/3xzEW.png"  height="20vh" 
           	 opacity="0"   >  
			  <!-- Появление зайца --> 
			 <animate id="zayka_Hide" attributeName="opacity" begin="btn.click+8s" dur="1s" to="1" fill="freeze" /> 
 			 <animateTransform id="zayka_Up" attributeName="transform" type="translate" values="1070 750;1075 730;1080 710;1075 730;1070 750" dur="0.5s"  begin="zayka_Hide.end" repeatCount="indefinite" />  
		 	<animate attributeName="x" begin="zayka_Hide.end" dur="2.5s" values="0;50;70;100;70;50;50;0" repeatCount="indefinite" />   
		</image>   
    
   <!-- Анимация текста Новый Год!   -->  
	   
	  <path id="NY_path" d="m1207.8 682.9c0 0 24.8-274.1 4.6-497.1C1193.5-23.4 777.1 18.3 579.3 97.4 360.1 185.1 336 782.2 139.1 652.1-3.1 558.3 41.8 317.2 53.1 95.6c3.9-75.7 19.5 7.8 250.5 6.4 235.6-1.5 261-34.5 261-34.5" style="fill:none;stroke:none"/> 
<text text-anchor="middle" font-size="52" font-weght="900" fill="gold" stroke="white" stroke-width="1" filter="url(#shadow)"  opacity="0" > 
  <textPath id="result" method="align" spacing="auto" startOffset="0%" xlink:href="#NY_path"><tspan dx="0" dy="-2">С Новым 2020 годом!</tspan> 
 <!-- Движение фразы вдоль кривой линии begin ="80s" -->   
  <animate id="NY_move"  
   begin ="btn.click+10s" 
   dur="10s" 
   repeatCount="1" 
   attributeName="startOffset" 
   values="0%;9%;9%;9%;73%;73%;73%;92%;92%" 
   fill="freeze"/>  
   </textPath>  
   <!-- Появление Нового Года -->  
   <!--NY_move.begin--> 
   <animate attributeName="opacity" begin="NY_move.begin" dur="0.1s" values="0;1" fill="freeze" />  
   <!-- Перемещение текста--> 
  <animateTransform id="text_Up2" attributeName="transform" type="translate" values="0 0;120 20;-40 -20;120 60;-40 60;120 0;-20 80;120 80;0 0" dur="3.5s"  begin="NY_move.end;98.5s;106;114.5s" repeatCount="1" />  
   <!-- Увеличение текста--> 
  <animateTransform id="text_scale" attributeName="transform" type="scale" calcMode="discrete" values="1;1.2;1.3;1.4;1.5;2;2;2;2;1.5;1.4;1.3;1.2;1" dur="5s"  begin="text_Up2.end" repeatCount="1" />  
  <set id="red" attributeName="fill" to="red" begin="28.5s" /> 
  <set id="lime" attributeName="fill" to="lime" begin="32s" /> 
  <set id="purple" attributeName="fill" to="purple" begin="36.5s" /> 
  <animateTransform id="Scale_purple" attributeName="transform" type="scale" dur="1.5s" from="1" to="2.5" begin="36.5s" fill="freeze" /> 
  <animateTransform id="T_skew" attributeName="transform" attributeType="XML"  
                type="skewY" values="1;-1.4;1" additive="sum" 
                begin="Scale_purple.end;T2_skew.end" dur="0.8s" fill="freeze" repeatCount="3"/> 
	<animateTransform id="T2_skew" attributeName="transform" attributeType="XML"  
                type="skewY" values="-4;1;-4" additive="sum" 
                begin="T_skew.end" dur="1.5s" fill="freeze" repeatCount="2"/>			 
 
</text>		 
	<g id="btn" onclick='play()' > 
   <rect  x="5" y="10" rx="15"  id="rec1" width="100px" height="40px" fill="#4975B2" /> 
    <text x="23" y="40" font-size="32"  fill="white"> Start </text> 
 </g>	 	 
		 
</svg>	  
</div>   
 
<script> 
var zodiac = new Audio(); 
zodiac.src = 'https://svg-art.ru/files/diskoteka_avariya_novogodnyaya.mp3'; 
 
function play() { 
  zodiac.play(); 
} 
</script>

Answer 4

Сырая версия 1.0, в идеале надо добавить еще пару сценок и доработать создание ёлки йолки:

let img = new Image(); 
    img.onload = startScene; 
    img.onerror = () => console.log("Что-то пошло не так"); 
    img.src = "https://images.vexels.com/media/users/3/157970/isolated/preview/c156b4270aea292b9b335dd463ea17eb-earth-planet-icon-earth-icon-by-vexels.png"; 
 
/* Каждую сценку писал отдельно в песочнице. 
Показалось легче завернуть каждую в свою функцию, а не заваливать в кучу, 
чтобы в будущем легче было переносить-редактировать. */ 
 
function startScene() { 
  let main = document.getElementById('main'); 
 
  (function enteringEarth() { 
    let time = 15; 
 
    setCSS(` 
      .scene { 
        background-color: #001; 
      } 
   
      .earth { 
        position: absolute; 
        width: 15px; 
        animation: closeup ${time}s linear forwards; 
      } 
   
      @keyframes closeup { 
        0% { width: 15px; } 
      100% { width: 250px; } 
      } 
   
      .rocket { 
        fill: white; 
        transition: ${time + 5}s; 
      } 
    `); 
 
    setHTML(` 
      <svg class="scene" width="100%" height="100%"> 
        <image class="earth" x="150" y="150" href="https://images.vexels.com/media/users/3/157970/isolated/preview/c156b4270aea292b9b335dd463ea17eb-earth-planet-icon-earth-icon-by-vexels.png"></image> 
        <circle class="rocket" cx="200" cy="-5" r="0.5"/> 
        <circle class="rocket" cx="250" cy="-25" r="0.5"/> 
      </svg> 
    `); 
 
    setTimeout(() => { 
      main.querySelectorAll('.rocket').forEach( rocket => { 
        setAttributes(rocket, { 
          'cx': 190, 
          'cy': 190, 
          'r': 1, 
        }); 
      }); 
 
      setTimeout(enteringEarth_closerView, time*1000); 
    }, 0); 
  })(); 
 
  function enteringEarth_closerView() { 
    setCSS(` 
      .scene { 
        background-color: #001; 
      } 
       
      .earth { 
        fill: #124; 
        filter: url(#earth-shadow); 
      } 
       
      .rocket-head { 
        width: 11px; 
        height: 5px; 
        fill: url(#rocket-light); 
      } 
      .rocket-top-1 { 
        width: 15px; 
        height: 2px; 
        fill: url(#rocket-light); 
      } 
      .rocket-top-2 { 
        width: 15px; 
        height: 10px; 
        fill: url(#rocket-dark); 
      } 
      .rocket-body { 
        width: 15px; 
        height: 140px; 
        fill: url(#rocket-light); 
      } 
      .rocket-foot { 
        width: 3px; 
        height: 18px; 
        fill: #111; 
      } 
      .rocket.first { 
        position: absolute; 
        animation: rocket_1 6s linear forwards; 
      } 
       
      @keyframes rocket_1 { 
        0% { transform: rotate(0deg) scale(2); left: 60%; top: 5%; } 
      84% { transform: rotate(360deg) scale(0.9); left: 40%; top: 50%; } 
      100% { transform: rotate(400deg) scale(0.9); left: 40%; top: 50%; } 
      } 
       
      .line { 
        opacity: 0; 
        stroke: #fff5; 
        stroke-width: 1px; 
        stroke-dasharray: 1; 
        animation: spray 2s linear; 
        animation-delay: 4s; 
      } 
       
      @keyframes spray { 
        0% { opacity: 1; } 
      40% { opacity: 1; } 
      45% { opacity: 0; } 
      55% { opacity: 0; } 
      60% { opacity: 1; } 
      100% { opacity: 0; } 
      } 
       
      .rocket.second { 
        position: absolute; 
        animation: rocket_2 6s linear forwards; 
      } 
       
      @keyframes rocket_2 { 
        0% { transform: rotateZ(-30deg) rotateX(20deg) scale(1.5); left: 80%; top: 5%} 
      100% { transform: rotateZ(-40deg) rotateX(30deg) scale(0.9); left: 40%; top: 50%} 
      } 
    `); 
 
    setHTML(` 
      <svg class="scene" width="100%" height="100%"> 
        <defs> 
          <linearGradient id="rocket-light"> 
            <stop offset="0" stop-color="#666"></stop> 
            <stop offset="40%" stop-color="#bbb"></stop> 
            <stop offset="50%" stop-color="#ccc"></stop> 
            <stop offset="60%" stop-color="#bbb"></stop> 
            <stop offset="100%" stop-color="#666"></stop> 
          </linearGradient> 
           
          <linearGradient id="rocket-dark"> 
            <stop offset="0" stop-color="#111"></stop> 
            <stop offset="40%" stop-color="#444"></stop> 
            <stop offset="50%" stop-color="#555"></stop> 
            <stop offset="60%" stop-color="#444"></stop> 
            <stop offset="100%" stop-color="#111"></stop> 
          </linearGradient> 
           
          <filter id="earth-shadow"> 
            <feDropShadow dx="-2" dy="-2" stdDeviation="100" flood-color="#045acf"/> 
          </filter> 
        </defs> 
         
        <circle class="earth" cx="80vw" cy="calc(800vw + 80vh)" r="800vw"/> 
      </svg>   
       
      <svg class="rocket second" width="39px" height="163px"> 
        <rect class="rocket-head" x="12px"/> 
        <rect class="rocket-top-1" x="10" y="5px"/> 
        <rect class="rocket-top-2" x="10" y="7px"/> 
        <rect class="rocket-body" x="10" y="17px"/> 
           
        <polygon points="9,157 26,157 28,163 7,163"></polygon> 
        <rect class="rocket-foot" y="138px" x="12px"/> 
        <rect class="rocket-foot" y="138px" x="21px"/> 
      </svg> 
       
      <svg class="rocket first" width="39px" height="163px"> 
        <rect class="rocket-head" x="12px"/> 
        <rect class="rocket-top-1" x="10" y="5px"/> 
        <rect class="rocket-top-2" x="10" y="7px"/> 
        <rect class="rocket-body" x="10" y="17px"/> 
           
        <polygon points="9,157 26,157 28,163 7,163"></polygon> 
        <rect class="rocket-foot" y="138px" x="12px"/> 
        <rect class="rocket-foot" y="138px" x="21px"/> 
         
        <g class="spray"> 
          <line class="line" x1="26" y1="15" x2="38" y2="13"/> 
          <line class="line" x1="26" y1="15" x2="39" y2="14"/> 
          <line class="line" x1="26" y1="15" x2="40" y2="15"/> 
          <line class="line" x1="26" y1="15" x2="39" y2="16"/> 
          <line class="line" x1="26" y1="15" x2="38" y2="17"/> 
        </g> 
      </svg> 
    `); 
 
    setTimeout(skyViewBeforeLanding,5900); 
  } 
 
  function skyViewBeforeLanding(){ 
    setCSS(` 
      .scene { 
        background-color: #66c5ff; 
      } 
 
      .rocket-head { 
        width: 11px; 
        height: 5px; 
        fill: url(#rocket-light); 
      } 
       
      .rocket-top-1 { 
        width: 15px; 
        height: 2px; 
        fill: url(#rocket-light); 
      } 
       
      .rocket-top-2 { 
        width: 15px; 
        height: 10px; 
        fill: url(#rocket-dark); 
      } 
       
      .rocket-body { 
        width: 15px; 
        height: 140px; 
        fill: url(#rocket-light); 
      } 
       
      .rocket-feet { 
        stroke: #111; 
        stroke-width: 2px; 
        fill: none; 
      } 
       
      .rocket text { 
        fill: black; 
        font-size: 13px; 
      } 
       
      .main-fire { 
        fill: #ffff76; 
        animation: rocket-fire 0.1s linear infinite; 
      } 
       
      @keyframes rocket-fire { 
        0% { transform: scaleY(0.80); fill: #ffcc76; } 
      } 
    `); 
 
    setHTML(` 
      <svg class="scene" width="100%" height="100%"> 
        <defs> 
          <linearGradient id="rocket-light"> 
            <stop offset="0" stop-color="#666"></stop> 
            <stop offset="40%" stop-color="#bbb"></stop> 
            <stop offset="50%" stop-color="#ccc"></stop> 
            <stop offset="60%" stop-color="#bbb"></stop> 
            <stop offset="100%" stop-color="#666"></stop> 
          </linearGradient> 
 
          <linearGradient id="rocket-dark"> 
            <stop offset="0" stop-color="#111"></stop> 
            <stop offset="40%" stop-color="#444"></stop> 
            <stop offset="50%" stop-color="#555"></stop> 
            <stop offset="60%" stop-color="#444"></stop> 
            <stop offset="100%" stop-color="#111"></stop> 
          </linearGradient> 
        </defs> 
         
        <g class="rocket first"> 
          <rect class="rocket-head" x="12px" /> 
          <rect class="rocket-top-1" x="10" y="5px" /> 
          <rect class="rocket-top-2" x="10" y="7px" /> 
          <rect class="rocket-body" x="10" y="17px" /> 
 
          <polygon points="9,157 26,157 28,163 7,163"></polygon> 
           
          <g class="rocket-feet" transform="translate(0,142)"> 
            <polygon points="10,0 -6,22 -2,22 10,13"></polygon> 
            <polygon points="16,1 18,1 19,26 15,26"></polygon> 
            <polygon points="25,0 25,13 37,22 41,22"></polygon> 
          </g> 
 
          <g transform="translate(14 40)"> 
            <text x="0" y="0"> 
              <tspan x="0" dy="1.2em">S</tspan> 
              <tspan x="0" dy="1.2em">A</tspan> 
              <tspan x="0" dy="1.2em">N</tspan> 
              <tspan x="0" dy="1.2em">T</tspan> 
              <tspan x="0" dy="1.2em">A</tspan> 
              <tspan x="0" dy="1.2em" fill="#045acf">X</tspan> 
            </text> 
          </g> 
           
          <g class="engine-fire" transform="translate(10 163)"> 
            <polygon class="main-fire" points="1,0 14,0 16,10 8,70 -1,10"></polygon> 
          </g> 
        </g> 
         
        <g class="rocket second"> 
          <rect class="rocket-head" x="12px" /> 
          <rect class="rocket-top-1" x="10" y="5px" /> 
          <rect class="rocket-top-2" x="10" y="7px" /> 
          <rect class="rocket-body" x="10" y="17px" /> 
 
          <polygon points="9,157 26,157 28,163 7,163"></polygon> 
           
          <g class="rocket-feet" transform="translate(0,142)"> 
            <polygon points="10,0 -6,22 -2,22 10,13"></polygon> 
            <polygon points="16,1 18,1 19,26 15,26"></polygon> 
            <polygon points="25,0 25,13 37,22 41,22"></polygon> 
          </g> 
           
          <g class="engine-fire" transform="translate(10 163)"> 
            <polygon class="main-fire" points="1,0 14,0 16,10 8,70 -1,10"></polygon> 
          </g> 
        </g> 
      </svg>   
    `); 
 
    let wid = window.innerWidth; 
    let hei = window.innerHeight; 
 
    let rocket = main.querySelectorAll('.rocket'); 
    let coors = [ 
      {x: wid*0.3, y: hei*0.5 - 50}, 
      {x: wid*0.3 + 150, y: hei*0.5 - 90}, 
    ]; 
    let dir = { 
      x: 0.5, 
      y: 0.8 
    }; 
    let count = 0; 
 
    setRocketCoors(0.1, 150); 
 
    let interval = setInterval(function(){ 
      setRocketCoors(0.1, 150); 
       
      if( ++count == 140 ){ 
        clearInterval(interval); 
        coors = [ 
          {x: wid*0.3, y: hei*0.5 - 50}, 
          {x: wid*0.3 + 150, y: hei*0.5 - 90}, 
        ]; 
         
        interval = setInterval(function(){ 
          setRocketCoors(0.4); 
        }, 20); 
      } 
    }, 50); 
 
    function setRocketCoors(scale, distance = 0){ 
      rocket[0].setAttribute('transform', ` 
        translate(${(coors[0].x += dir.x)} ${(coors[0].y += dir.y)}) 
        rotate(-35) 
        scale(${scale}) 
      `); 
      rocket[1].setAttribute('transform', ` 
        translate(${(coors[1].x += dir.x) - distance} ${(coors[1].y += dir.y)}) 
        rotate(-35) 
        scale(${scale*0.8}) 
      `); 
    } 
 
    setTimeout(function(){ 
      clearInterval(interval); 
      landing(); 
    }, 11000); 
  } 
 
  function landing(){ 
    setCSS(` 
      .scene { 
        background-color: #66c5ff; 
      } 
       
      .ground { 
        fill: #aaa; 
      } 
       
      .perspective { 
        stroke: #666; 
      } 
       
      .rocket-head { 
        width: 11px; 
        height: 5px; 
        fill: url(#rocket-light); 
      } 
       
      .rocket-top-1 { 
        width: 15px; 
        height: 2px; 
        fill: url(#rocket-light); 
      } 
       
      .rocket-top-2 { 
        width: 15px; 
        height: 10px; 
        fill: url(#rocket-dark); 
      } 
       
      .rocket-body { 
        width: 15px; 
        height: 140px; 
        fill: url(#rocket-light); 
      } 
       
      .rocket-feet { 
        stroke: #111; 
        stroke-width: 2px; 
        fill: none; 
      } 
       
      .rocket text { 
        fill: black; 
        font-size: 13px; 
      } 
       
      .main-fire { 
        fill: #ffff76; 
        animation: rocket-fire 0.1s linear infinite; 
      } 
       
      @keyframes rocket-fire { 
        0% { transform: scaleY(0.80); fill: #ffcc76; } 
      } 
    `); 
 
    setHTML(` 
      <svg class="scene" width="100%" height="100%"> 
        <g class="land"> 
          <rect class="ground" y="50%" width="100%" height="50%" /> 
          <line class="perspective" x1="0" y1="80%" x2="48%" y2="50%" /> 
          <line class="perspective" x1="100%" y1="80%" x2="52%" y2="50%" /> 
        </g> 
 
        <defs> 
          <linearGradient id="rocket-light"> 
            <stop offset="0" stop-color="#666"></stop> 
            <stop offset="40%" stop-color="#bbb"></stop> 
            <stop offset="50%" stop-color="#ccc"></stop> 
            <stop offset="60%" stop-color="#bbb"></stop> 
            <stop offset="100%" stop-color="#666"></stop> 
          </linearGradient> 
 
          <linearGradient id="rocket-dark"> 
            <stop offset="0" stop-color="#111"></stop> 
            <stop offset="40%" stop-color="#444"></stop> 
            <stop offset="50%" stop-color="#555"></stop> 
            <stop offset="60%" stop-color="#444"></stop> 
            <stop offset="100%" stop-color="#111"></stop> 
          </linearGradient> 
        </defs> 
         
        <g class="rocket first"> 
          <rect class="rocket-head" x="12px" /> 
          <rect class="rocket-top-1" x="10" y="5px" /> 
          <rect class="rocket-top-2" x="10" y="7px" /> 
          <rect class="rocket-body" x="10" y="17px" /> 
 
          <polygon points="9,157 26,157 28,163 7,163"></polygon> 
           
          <g class="rocket-feet" transform="translate(0,142)"> 
            <polygon points="10,0 -6,22 -2,22 10,13"></polygon> 
            <polygon points="16,1 18,1 19,26 15,26"></polygon> 
            <polygon points="25,0 25,13 37,22 41,22"></polygon> 
          </g> 
 
          <g transform="translate(14 40)"> 
            <text x="0" y="0"> 
              <tspan x="0" dy="1.2em">S</tspan> 
              <tspan x="0" dy="1.2em">A</tspan> 
              <tspan x="0" dy="1.2em">N</tspan> 
              <tspan x="0" dy="1.2em">T</tspan> 
              <tspan x="0" dy="1.2em">A</tspan> 
              <tspan x="0" dy="1.2em" fill="#045acf">X</tspan> 
            </text> 
          </g> 
           
          <g class="engine-fire" transform="translate(10 163)"> 
            <polygon class="main-fire" points="1,0 14,0 16,10 8,70 -1,10"></polygon> 
          </g> 
        </g> 
         
        <g class="rocket second"> 
          <rect class="rocket-head" x="12px" /> 
          <rect class="rocket-top-1" x="10" y="5px" /> 
          <rect class="rocket-top-2" x="10" y="7px" /> 
          <rect class="rocket-body" x="10" y="17px" /> 
 
          <polygon points="9,157 26,157 28,163 7,163"></polygon> 
           
          <g class="rocket-feet" transform="translate(0,142)"> 
            <polygon points="10,0 -6,22 -2,22 10,13"></polygon> 
            <polygon points="16,1 18,1 19,26 15,26"></polygon> 
            <polygon points="25,0 25,13 37,22 41,22"></polygon> 
          </g> 
           
          <g class="engine-fire" transform="translate(10 163)"> 
            <polygon class="main-fire" points="1,0 14,0 16,10 8,70 -1,10"></polygon> 
          </g> 
        </g> 
      </svg> 
    `); 
 
    let wid = window.innerWidth; 
    let hei = window.innerHeight; 
 
    let rocket = main.querySelectorAll('.rocket'); 
    let coors = [ 
      {x: wid*0.3, y: - 250}, 
      {x: wid*0.3 + 150, y: - 290}, 
    ]; 
    let move = 1; 
    let stop = hei*0.5 - 50; 
    let landing = stop/2.5; 
 
    let tick = 5; 
    setTimeout(handleRocketCoors, tick); 
 
    function handleRocketCoors(){ 
      rocket[0].setAttribute('transform', ` 
        translate(${coors[0].x} ${(coors[0].y += move)}) 
      `); 
      rocket[1].setAttribute('transform', ` 
        translate(${coors[1].x} ${(coors[1].y += move)}) 
      `); 
       
      if( coors[0].y >= landing ){ 
        launchLandingFire(); 
        shakeCamera(); 
      } 
       
      if( coors[0].y <= stop ) { 
        setTimeout(handleRocketCoors, tick += 0.05); 
      } else { 
        let fire = main.querySelectorAll('.engine-fire'); 
        [...fire].forEach(el => el.outerHTML = ""); 
         
        setTimeout( transformAndRollout, 2000 ); 
      } 
    } 
  } 
 
  function launchLandingFire(){ 
    // ?! 
  } 
 
  function shakeCamera(){ 
    let scene = main.querySelector('.scene'); 
    let count = 0; 
    let interval = setInterval(function(){ 
      let x = (Math.random() < 0.5 ) ? 1 : -1; 
      let y = (Math.random() < 0.5 ) ? 1 : -1; 
      scene.style.transform = `translate(${x}px, ${y}px)` 
      if( ++count >= 250 ) { 
        clearInterval(interval);         
        scene.style.transform = "none"; 
      } 
    }, 5); 
  } 
 
  function transformAndRollout(){ 
    let rocket = main.querySelectorAll('.rocket'); 
    appendTree(rocket[0]); 
    appendTree(rocket[1]); 
 
    function appendTree(rocket){ 
      let tree = document.createElementNS("http://www.w3.org/2000/svg", 'g'); 
      for( let i = 0; i < 500; i++ ){ 
        let points = getRandomPoints(); 
        let leaf = ` 
          <polygon 
            class="leaf" 
            points="${points.from}" 
            fill="${getRandomGreen()}" 
          > 
            <animate 
              attributeName="points" 
              begin="10s" 
              dur="5s" 
              fill="freeze" 
              from="${points.from}" 
              to="${points.to}"/> 
          </polygon> 
        `; 
       
        tree.insertAdjacentHTML('beforeend', leaf); 
      } 
       
      rocket.appendChild(tree); 
    } 
     
    function getRandomPoints(){ 
      let x1 = rand(15) + 10 
      let y1 = rand(140); 
       
      let x2 = x1; 
      let y2 = y1 + rand(25) + 7; 
       
      let x3 = rand(y2) - y2/2; 
      let y3 = y2 + y2**0.5; 
       
      return { 
        from: `${x1},${y1} ${x2},${y2} ${x2+1},${y3}`, 
        to: `${x1},${y1} ${x2},${y2} ${x3},${y3}` 
      } 
    } 
     
    function getRandomGreen(){ 
      let r = Math.random() * 50; 
      let g = 2 * r; 
      let b = Math.random() * 50; 
      return `RGB(${r}, ${g}, ${b})`; 
    } 
     
    function rand(n){ 
      return Math.floor( Math.random() * n ); 
    } 
  } 
} 
 
function setCSS(str){ 
  document.getElementById('css').textContent = str; 
} 
function setHTML(str){ 
  document.getElementById('main').innerHTML = str; 
} 
function setAttributes(elem, obj){ 
  for( let attr in obj ){ 
    elem.setAttribute( attr, obj[attr] ); 
  } 
}
html, body { margin: 0; padding: 0; } 
 
#main { 
  width: 100%; 
  height: 100vh; 
  overflow: hidden; 
}
<style id="css"></style> 
<div id="main"></div>

P.s. впервые работал с SVG... чтение кода может вызвать боль и страдания. Анимировал то в SVG, то на CSS, то JS, "лишь бы работало"))

Answer 5

Попытка номер 2.

За основу взят первый пример. Добавлены новые персонажи.

Update 23.12.2019

  • Добавлена анимация луны. Анимация начинается с 36-ой секунды.

Update 24.12.2019

  • Добавлена анимация звезды на ёлке с 70-ой секунды

  • Добавлена анимация полёта автомобиля снегурочки.
    Анимация начинается с 45-ой секунды.

Update 28.12.2019

На первой минуте ёлка стоит вся в снегу. Работает маска - mask id="msk1" по контуру ёлки.

Затем с момента времени - 1м. 20 сек., после появления снегурочки начинает работать анимация смены заполнения цвета маски, создавая эффект мерцания гирлянд.

Дождитесь :), на мой взгляд, интересно получилось.

 <div class="container"> 
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg"  
        xmlns:xlink="http://www.w3.org/1999/xlink" 
           width="100%" height="100%" viewBox="0 0 1680 1050" preserveAspectRatio="xMinYMin meet" >   
    <defs> 
     <filter id="shadow" x="-20%" y="-20%" width="140%" height="140%"> 
                <feDropShadow dx="4" dy="8" stdDeviation="4"/> 
            </filter>  
    		 <!-- Траектория движения Деда Мороза --> 
    	<path id="path1" d="m1648.6 24.4c0 0-297.1 119.8-421 217.9-78.8 62.4-107.2 182.8-196.5 228.8C866.6 555.9 658.8 532.4 478.3 521.4 243.9 507.1 306.7 176.5 680.3 210c110.3 9.9 224.9-25.6 328 11 87.5 31.1 232 76.1 221.8 168.3-17.4 156.9-281.3 146.3-431 196.6-136 45.8-420 94.4-420 94.4" style="fill:none;stroke-opacity:0.9;stroke-width:2;stroke:none"/> 
    		     <!-- Траектория движения снегурочки --> 
    	<path id="Girl_Path" d="m1648.6 24.4c0 0-297.1 119.8-421 217.9-78.8 62.4-107.2 182.8-196.5 228.8C866.6 555.9 658.8 532.4 478.3 521.4 243.9 507.1 306.7 176.5 680.3 210c110.3 9.9 224.9-25.6 328 11 87.5 31.1 224.8 75.6 221.8 168.3-6.3 195.5-306.6 254.1-489.2 324-170.8 65.4-542.7 80.2-542.7 80.2" style="fill:none;stroke-width:2;stroke:#f00"/>     
       <radialGradient id="RadialGrad" 
               fx="50%" fy="50%" r="65%" 
               spreadMethod="pad"> 
              <stop offset="0%"   stop-color="#E7D68C" stop-opacity="1"/> 
              <stop offset="100%" stop-color="#FFFEED" stop-opacity="1" /> 
        </radialGradient>   
   <filter id="glow" filterUnits="userSpaceOnUse" 
            x="-50%" y="-50%" width="300%" height="300%"> 
        
      <feGaussianBlur in="SourceGraphic" stdDeviation="25" result="blur5"/> 
      <feGaussianBlur in="SourceGraphic" stdDeviation="30" result="blur10"/> 
      <feGaussianBlur in="SourceGraphic" stdDeviation="40" result="blur20"/> 
      <feGaussianBlur in="SourceGraphic" stdDeviation="50" result="blur30"/> 
      <feGaussianBlur in="SourceGraphic" stdDeviation="70" result="blur50"/> 
       <feMerge result="blur-merged"> 
        <feMergeNode in="blur10"/> 
        <feMergeNode in="blur20"/> 
        <feMergeNode in="blur30"/> 
        <feMergeNode in="blur50"/> 
      </feMerge> 
       
      <feColorMatrix result="yellow-blur" in="blur-merged" type="matrix" 
                     values="0 0 0 0 0 
                             0 1 0 0 0 
                             0 0 0 0 0 
                             0 0 0 0.7 0" /> 
      <feMerge> 
        <feMergeNode in="yellow-blur"/>        
        <feMergeNode in="blur5"/>           
        <feMergeNode in="SourceGraphic"/>   
      </feMerge> 
    </filter>   
	   
	   <mask id="msk1"> 
    <rect fill="white" width="100%" height="100%"/> 
  <path fill="#9939CD"  d="m832.5 54.2c-25 19.3-14.5 57.9-13.8 93.8 0.2 11.8-8 22.2-12.5 33.1-2.3 5.7-7.5 17-7.5 17 0 0-8.4 18.5-12 28.1-5.5 15-12.7 29.7-14.5 45.6-1 9.1 3.7 18.2 2.5 27.3-1.7 12.3-11.3 22.5-13.1 34.8-1.1 7.5 1.6 15.1 1.5 22.7-0.1 8.4-2.2 25-2.2 25 0 0-0.6 8.1-2.8 11.4-3.6 5.5-12.9 6-15.6 12-2.2 4.9 1.4 10.7 1.1 16.1-0.5 10-7.2 19.7-5.3 29.5 1 5.1 6.3 8.2 8.3 13.1 1.5 3.6-2.4 15.9-6.7 23.9-2.7 5.2-9.3 4.9-10 9.5-1.4 8.4 12 22.5 12 22.5l-8.9 17.8-4.4 30 1.7 30 9.5 10c1 20.7-2.8 6-8.9 11.1-6.3 6.1 2.1 17.9-0.8 26.1-1.7 4.7-9.2 11.7-9.2 11.7 0 0-5.5 11-4.4 16.7 1.1 5.5 8.9 7.9 10 13.3 1.4 7.1-4 14-5.6 21.1-1 4.8-3.3 9.6-2.5 14.5 0.7 4.1 6 6.9 5.8 11.1-0.2 6.5-8.5 10.4-10 16.7-2.4 9.9 1.1 20.4 1.9 30.6 0.4 4.3 0.5 8.6 1.4 12.8 1.4 7 3 14.1 6.1 20.6 2.7 5.5 4.7 13.4 10.6 15 7 1.9 12.8-8.2 20-8.9 14.8-1.4 29.1 6 43.4 10 8.2 2.3 18.7 2 24.1 7.9 10.5 11.5 10.1 15.7 18 17.4 7.7 1.7 21.5 3.3 28.6-1 7.2-4.3 10-12.8 15.3-17 8.3-6.6 14-3.5 20.7-6.3 6.6-2.7 12.1-7.9 18.9-10 6.4-2 13.3-1.9 20-2.2 7-0.4 15.3 4 21.1 0 5.9-4 4.8-13.5 7.8-20 2.5-5.5 6.5-10.4 8.3-16.1 1.3-4.1 0.5-8.7 1.7-12.8 1.7-5.9 6.7-10.7 7.8-16.7 2-10.6-0.8-21.6-2.2-32.3-0.9-6.4-4.2-12.5-3.9-18.9 0.3-5.8 2.4-11.5 5-16.7 1.8-3.7 6.8-5.9 7.2-10 1.2-10.4-4-22.5-12.2-28.9-4.6-3.6-14.9 2.6-17.2-2.8-5.6-13 23.5-20.9 23.9-35 0.3-8.6-13.3-22.2-13.3-22.2l-5-60.1c0 0-1.6-8.9-1.1-13.3 0.6-5.8 6-11 5-16.7-0.9-4.8-8.8-6.8-8.9-11.7-0.1-6.1 10.2-8.9 10.6-15 0.5-7.8-7.4-13.7-11.1-20.6-4.1-7.6-9.4-14.7-12.2-22.8-1.4-3.9-3.2 0.5-2.2-12.2 0.1-9.5-14.8-18.5-10-26.7 2.5-4.2 11.7 1.8 14.5-2.2 14.2-21.2-16.9-49-17.8-74.5-0.2-4.5 4.3-9.3 2.2-13.3-1.9-3.7-8-2.8-11.1-5.6-3-2.7-5.5-6.2-6.7-10-1.5-5 0-10.4 0-15.6 0-4.4 1.2-9.1 0-13.3-1.4-4.6-5-8.3-7.8-12.2-1.1-1.5-3.1-2.6-3.3-4.4-0.6-4.8 3.9-8.8 5.6-13.3 1.2-3.3 3.9-6.5 3.3-10-0.9-5.5-4.3-12.8-9.8-13.3-1.9-0.2-2.3 4.2-4.2 4-8-1.1-10.4-12.9-12.6-20.7-3.6-26.5-14.5-23.1-15.4-35.2-1.3-25.9 11.6-67.9-9.4-89-8.7-8.8-27.1-11.6-36.9-4z"> 
  <!-- Анимация цветов маски --> 
 <animate 
    id="Three_fire" 
    attributeName="fill" 
    dur="0.5s" 
	begin="btn.click+80s;Three_pause.end" 
	values=" #CD9AE9; white;white;#CD9AE9" 
	fill="freeze" 
	repeatCount="10" /> 
 <!-- Пауза анимации цветов маски --> 
 <animate 
    id="Three_pause" 
    attributeName="fill" 
	dur="5s" 
	begin="Three_fire.end" 
	values=" white;white" 
	fill="freeze" 
	repeatCount="1" />	  
   </path> 
 </mask>  
	 
    </defs> 
    	   <!-- Изображение Ёлочки --> 
    <image mask="url(#msk1)" xlink:href="https://i.stack.imgur.com/PBRad.jpg" height="100%" width="100%"/> 
           <!-- Луна --> 
      <g transform="translate(1200 220)"> 
       <g transform="rotate(-20 35.5 35.5)"> 
    <circle cx="35.5" cy="35.5" r="35" stroke="none"  fill="url(#RadialGrad)" /> 
     <circle cx="35.5" cy="35.5" r="35" stroke="none" fill="black" > 
     <animate 
       id="youngMoon" 
       attributeName="cx" 
       values="35.5;-35.5" 
       begin="btn.click+35s;oldMoon.end+1s" 
       dur="10s" 
       fill="freeze" /> 
    <animate id="oldMoon" attributeName="cx" values="105;35.5;" begin="youngMoon.end+1s" dur="10s"  fill="freeze" />  
 
    </circle>  
    </g> 
     </g>   
          <!-- Звезда на ёлке -->  
    	<path id="star_Full" fill="#E4F6A3"  filter="url(#glow)" opacity="0" d="M580.2 76.2 837.2 71.3 774.7 5.7 845.1 62.7 850.1 8c0 0 6.8 54.2 6 54.7-4.3 2.8 70.9-57.5 70.9-57.5L862.8 71.2 1131.2 76.2 864.4 81.8 982.3 203C960.8 189.7 856.8 91.3 856.7 91.2L849.8 194.2 845.7 91.1 714.3 203.7 832.8 82.5Z"> 
          <!-- Анимация opacity звезды --> 
	<animate 
	    id="an_star" 
		attributeName="opacity" 
	    dur="2.5s" 
		begin="btn.click+70s;pause_star.end" 
		values="1;1;0"		         
		fill="freeze" 
		repeatCount="5" />  
	  <!-- Пауза анимация opacity звезды --> 
	<animate 
	    id="pause_star" 
		attributeName="opacity" 
	    dur="1.5s" 
		begin="an_star.end" 
		values="0;0"		         
		fill="freeze" 
		repeatCount="1" /> 	 
       <!-- Замена цвета у звезды    --> 
   <animate 
	    id="fill_change_star" 
		attributeName="fill" 
	    dur="11s" 
		begin="svg1.click;pause_star.end" 
		values="#CDE7FB;red;#B34EE9;#15C14E"		         
		fill="freeze" 
		repeatCount="1" /> 	 
       </path>		   
    	   
    <image  id="fly"   xlink:href="https://i.stack.imgur.com/qnNmf.png" width="2%" height="2%"  opacity="1" > 
        
      <!-- Анимация самолёта с Дедом морозом --> 
    	<animateMotion 
    	  id="MotionHal" 
    	  begin="btn.click+8s" 
    	  dur="14s" 
    	  fill="freeze" 
    	  rotate="auto-reverse" 
    	  repeatCount="1"  > 
        <mpath xlink:href="#path1" /> 
        </animateMotion>  
    	      <!-- Увеличение самолёта --> 
    		<animateTransform 
    		    id="an_fly" 
    			attributeName="transform" 
    			type="scale" 
    			begin="MotionHal.begin" 
    			dur="14s" 
    			values="1;2;2;2;4;6;8;9" 
    			fill="freeze" 
    			repeatCount="1" />   
    	 
    	    <!-- Исчезновение самолёта --> 
    	<animate 
    	    id="fly_hide" 
    		attributeName="opacity" 
    		dur="1.5s" 
    		values="1;0" 
    		begin="an_fly.end+5s" 
    		repeatCount="1" 
    		fill="freeze" /> 		 
    	 
    </image>      
           	<!-- Анимация снеговика  -->  
        <image  id="Snowman" transform="translate(950 720) scale(1 1)" x="0" xlink:href="https://i.stack.imgur.com/mbefD.png" width="13%" height="13%"  opacity="0"  filter="url(#shadow)" > 
    			  <!-- Снеговик появляется --> 
    		 	<animate 
    			    id="Snowman_Vis" 
    				attributeName="opacity" 
    				begin="W2_hide_back.end+1s;Snowman_Pause.end" 
    				dur="1.5s" 
    				values="0;1" 
    				repeatCount="1" 
    				fill="freeze" />  
    			 
    			<!-- Анимация движения снеговика   --> 
    			<animateTransform 
    			    id="Snowman_TR" 
    				attributeName="transform" 
    				type="translate" 
    				values=" 
    				       950 720; 
    					   1050 720; 
    					   1170 720; 
    					   1050 720; 
    					   950 720" 
    					   dur="2s" 
    					   begin="Snowman_Vis.end" 
    					   keyTimes="0;0.2;0.6;0.75;1" 
    					   repeatCount="5" />  
    			 
    			<animate 
    			    id="Snowman_Hide" 
    				attributeName="opacity" 
    				begin="Snowman_TR.end+0.5s" 
    				dur="1s" 
    				values="1;0" 
    				repeatCount="1" 
    				fill="freeze" />   
    			<animate 
    			    id="Snowman_Pause" 
    				attributeName="opacity" 
    				begin="Snowman_Hide.end+0.5s" 
    				dur="10s" 
    				values="0;0" 
    				repeatCount="1" 
    				fill="freeze" />  	 
    	 </image> 
           
                     <!-- Анимация зайчика с гитарой  --> 
        <image  id="zayka" filter="url(#shadow)" transform="translate(1050 850) scale(1 1)" 
    	     x="0" xlink:href=" https://i.stack.imgur.com/3xzEW.png" 
    		 height="20vh" 
    		 opacity="0"   >  
    			  <!-- Появление зайца --> 
    			 <animate 
    			   id="zayka_Hide" 
    			   attributeName="opacity" 
    			   begin="btn.click+8s" 
    			   dur="1s" 
    			   to="1" 
    			   fill="freeze" />  
    			   <!-- Прыжки зайца --> 
     		<animateTransform 
    			 id="zayka_Up" 
    			 attributeName="transform" 
    			 type="translate" 
    			 values="1070 850;1075 830;1080 810;1075 830;1070 850" 
    			 dur="0.5s" 
    			 begin="zayka_Hide.end" 
    			 end="W2_Tr.end" 
    			 repeatCount="indefinite" />  
    		 <!-- Движение зайца --> 
    		<animate 
    		  id="zayka_Tr" 
    		  attributeName="x" 
    		  begin="zayka_Hide.end" 
    		  end="W2_Tr.end" 
    		  dur="2.5s" 
    		  values="0;50;70;100;70;50;50;0" 
    		  repeatCount="indefinite" />  
    		   
           <!-- Заяц резко поворачивается к волку --> 
    	 <animateTransform 
    	   id="zayka_Rotate" 
    	   attributeName="transform" 
    	   type="scale" 
    	   dur="1s" 
    	   begin="W2_Tr.end" 
    	   values="1 1;-1 1;1 1;-1 1" 
    	   additive="sum" 
    	   repaeatCount="1" 
    	    />	 
    		    <!-- Прыжки зайца2 --> 
     		<animateTransform 
    			 id="zayka_Up2" 
    			 attributeName="transform" 
    			 type="translate" 
    			 values="1070 850;1075 830;1080 810;1075 830;1070 850" 
    			 dur="0.5s" 
    			 begin="zayka_Rotate.end+0.5s" 
    			 repeatCount="indefinite" />  
    		 <!-- Движение зайца2 --> 
    		<animate 
    		  id="zayka_Tr2" 
    		  attributeName="x" 
    		  begin="zayka_Rotate.end+0.5s" 
    		  dur="2.5s" 
    		  values="0;50;70;100;70;50;50;0" 
    		  repeatCount="indefinite" />  
    	</image>   
        
       <!-- Анимация текста Новый Год!   -->  
    	   
    	  <path id="NY_path" d="m1207.8 682.9c0 0 24.8-274.1 4.6-497.1C1193.5-23.4 777.1 18.3 579.3 97.4 360.1 185.1 336 782.2 139.1 652.1-3.1 558.3 41.8 317.2 53.1 95.6c3.9-75.7 19.5 7.8 250.5 6.4 235.6-1.5 261-34.5 261-34.5" style="fill:none;stroke:none"/> 
    <text text-anchor="middle" font-size="52" font-weght="900" fill="gold" stroke="white" stroke-width="1" filter="url(#shadow)"  opacity="0" > 
      <textPath id="result" method="align" spacing="auto" startOffset="0%" xlink:href="#NY_path"><tspan dx="0" dy="-2">С Новым 2020 годом!</tspan> 
     <!-- Движение фразы вдоль кривой линии begin ="80s" -->   
      <animate id="NY_move"  
       begin ="btn.click+10s" 
       dur="10s" 
       repeatCount="1" 
       attributeName="startOffset" 
       values="0%;9%;9%;9%;73%;73%;73%;92%;92%" 
       fill="freeze"/>  
       </textPath>  
       <!-- Появление Нового Года -->  
        
       <animate attributeName="opacity" begin="NY_move.begin" dur="0.1s" values="0;1" fill="freeze" />  
       <!-- Перемещение текста--> 
      <animateTransform id="text_Up2" attributeName="transform" type="translate" values="0 0;120 20;-40 -20;120 60;-40 60;120 0;-20 80;120 80;0 0" dur="3.5s"  begin="NY_move.end;98.5s;106;114.5s" repeatCount="1" />  
       <!-- Увеличение текста--> 
      <animateTransform id="text_scale" attributeName="transform" type="scale" calcMode="discrete" values="1;1.2;1.3;1.4;1.5;2;2;2;2;1.5;1.4;1.3;1.2;1" dur="5s"  begin="text_Up2.end" repeatCount="1" />  
      <set id="red" attributeName="fill" to="red" begin="28.5s" /> 
      <set id="lime" attributeName="fill" to="lime" begin="32s" /> 
      <set id="purple" attributeName="fill" to="purple" begin="36.5s" /> 
      <animateTransform id="Scale_purple" attributeName="transform" type="scale" dur="1.5s" from="1" to="2.5" begin="36.5s" fill="freeze" /> 
      <animateTransform id="T_skew" attributeName="transform" attributeType="XML"  
                    type="skewY" values="1;-1.4;1" additive="sum" 
                    begin="Scale_purple.end;T2_skew.end" dur="0.8s" fill="freeze" repeatCount="3"/> 
    	<animateTransform id="T2_skew" attributeName="transform" attributeType="XML"  
                    type="skewY" values="-4;1;-4" additive="sum" 
                    begin="T_skew.end" dur="1.5s" fill="freeze" repeatCount="2"/>			 
 
    </text>		 
    	 
    	    <!-- Аватарка Рыжий волк --> 
        <image id="red_wolf" xlink:href="https://i.stack.imgur.com/4TxIO.png" x="620" y="735" opacity="0" 
             width="8%" height="8%" > 
         <animate 
    	    id="W_OP" 
    		attributeName="opacity" 
    		dur="2.5s" 
    		values="0;1;1;1;0" 
    		begin="btn.click+0.3s" 
    		repeatCount="3" />  
    	</image>     
    		<!-- Аватарка Рыжий волк2 в углу--> 
      <image id="red_wolf" xlink:href="https://i.stack.imgur.com/4TxIO.png" width="8%" height="8%" x="60" y="935" opacity="0"> 
    	        <!-- Появление аватарки волка в углу --> 
    	<animate 
    		id="W1_ava" 
    		attributeName="opacity" 
    		dur="2s" 
    		additive="sum" 
    		values="0;1;1;1;0" 
    		begin="W2_hide_back.end+1s;W1_pausa.end" 
    		repeatCount="3" 
    		fill="freeze" /> 
    		<!-- Движениее аватарки --> 
    		 
    	<animateTransform 
    	        id="W1_Tr" 
    		    attributeName="transform" 
    		    attributeType="XML" 
    		    type="translate" values="0;30;60;60;30;0" 
    		    additive="sum" 
    		    begin="W1_ava.end-7s" 
    		    dur="6s" 
    		    fill="freeze" 
    		    repeatCount="1"/> 	  
    	    <!-- Пауза аватарки --> 
    	<animate 
    		id="W1_pausa" 
    		attributeName="opacity" 
    		dur="6s" 
    		additive="sum" 
    		values="0;0" 
    		begin="W1_Tr.end" 
    		repeatCount="1" 
    		fill="freeze" />	 
     </image>		 
    	           <!-- Сидящий волк   --> 
        <image xlink:href="https://i.stack.imgur.com/zFbSq.png" x="50" y="860" 
    	  opacity="0"   width="20%" height="20%" >  
    	     <!-- Появление волка --> 
    	  <animate 
    	    id="W2_OP" 
    		attributeName="opacity" 
    		dur="1.5s" 
    		values="0;1" 
    		begin="btn.click+20s" 
    		repeatCount="1" 
    		fill="freeze" />  
    	   <!-- Волк подпрыгает вверх --> 
    	 <animateTransform 
    	    id="W2_skew" 
    	    attributeName="transform" 
    	    attributeType="XML"  
            type="skewY" values="1;-0.1;1"  
            begin="W2_OP.end" 
    		dur="0.5s" 
    		fill="freeze" 
    		repeatCount="20"/>  
             <!-- Волк движется к зайцу --> 
    	    <animateTransform 
    	        id="W2_Tr" 
    		    attributeName="transform" 
    		    attributeType="XML" 
    		    type="translate" values="0;30;60;90;120;150;180;210;240;270;300;330;360;390;420;450;480;510;540;570" 
    		    additive="sum" 
    		    begin="W2_OP.end" 
    		    dur="11s" 
    		    fill="freeze" 
    		    repeatCount="1"/>  
    		   <!-- Поворот волка от зайца --> 
                <animateTransform 
    			   id="W2_Rotate" 
    			   attributeName="transform" 
    			   type="scale" 
    			   dur="0.5s" 
    			   begin="zayka_Rotate.end" 
    			   values="1 1;-1 1" 
    			   additive="sum" 
    			   repaeatCount="1" 
    			   fill="freeze" />	 
    		   <!-- Движение волка после удара --> 
    		<animateTransform 
    	        id="W2_back" 
    		    attributeName="transform" 
    		    attributeType="XML" 
    		    type="translate" 
    			values="0;430" 
    		    additive="sum" 
    		    begin="W2_Rotate.end" 
    		    dur="1.5s" 
    		    fill="freeze" 
    		    repeatCount="1"/> 	    
            <!-- Исчезновение волка --> 
    	<animate 
    	    id="W2_hide_back" 
    		attributeName="opacity" 
    		dur="1.5s" 
    		additive="sum" 
    		values="0;1" 
    		begin="W2_Rotate.end" 
    		repeatCount="1" 
    		fill="freeze" />  
    	</image>	 
         
      	   <!-- Снегурочка --> 
    <image id="Girl" transform="translate(450 570) scale(1 1)" xlink:href="https://i.stack.imgur.com/RDght.png" width="30%" height="30%" opacity="0"> 
         <!-- Появление Снегурочки --> 
    	  
        <animate 
    	  id="Yes_Girl" 
    	  attributeName="opacity" 
    	  begin="Horse_hide.end+1s"                          
    	  dur="1.5s" 
    	  values="0;1"  
          repeatCount="1" 
    	  fill="freeze" />   
    	       <!-- Движения Снегурочки --> 
    		 <animateTransform 
    		   attributeName="transform"                             
    		   type="translate" 
    		   begin="Yes_Girl.end+1s" 
    		   values=" 
    		          450 550; 
    				  580 590; 
    				  480 550; 
    				  580 590; 
    				  530 550; 
    				  500 590; 
    				  450 550" 
    			dur="2.5s" 
    			repeatCount="indefinite" />    
       
      </image>      
         	 
    	   <!-- Дед мороз --> 
    <image id="Ded_Moroz" transform="translate(250 550) scale(1 1)" xlink:href="https://i.stack.imgur.com/TYaVo.png" width="30%" height="30%" opacity="0"> 
         <!-- Появление деда Мороза --> 
    	  
        <animate 
    	  id="Yes_Ded" 
    	  attributeName="opacity" 
    	  begin="fly_hide.end+8s"                          
    	  dur="2.5s" 
    	  values="0;1"  
          repeatCount="1" 
    	  fill="freeze" />  
    	       <!-- Движения Деда Мороза --> 
    		 <animateTransform 
    		    id="Ded_TR" 
    		    attributeName="transform"                             
    		    type="translate" 
    		    begin="Yes_Ded.end+1s" 
    		    values=" 
    		          250 550; 
    				  280 580; 
    				  280 550; 
    				  300 580; 
    				  280 550; 
    				  250 580; 
    				  250 550" 
    			dur="2s" 
    			repeatCount="indefinite" />    
       
      </image>   
      <!-- Полет снегурочки на автомобиле --> 
    <image  id="flyG"   xlink:href="https://i.stack.imgur.com/3Jxdw.png"  width="3%" height="3%"  opacity="1" > 
            	<!-- Движение автомобиля вдоль пути --> 
    	 <!--  begin="btn.click+70s" --> 
    	<animateMotion 
    	  id="MotionGirl" 
    	  begin="btn.click+45s" 
    	  dur="20s" 
    	  fill="freeze" 
    	  additive="sum" 
    	  rotate="auto-reverse" 
    	  repeatCount="1"  > 
        <mpath xlink:href="#Girl_Path" /> 
        </animateMotion>  
    	      <!-- Увеличение автомобиля --> 
    		<animateTransform 
    		    id="Horse_TR" 
    			attributeName="transform" 
    			type="scale" 
    			begin="MotionGirl.begin" 
    			dur="20s" 
    			additive="sum" 
    			values="1.2;1.4;2;3.5;4.5;5.5;8" 
    			fill="freeze" 
    			repeatCount="1" />   
    	 
    	    <!-- Исчезновение автомобиля --> 
    	 
    	 	<animate xlink:href="#flyG" 
    			id="Horse_hide" 
    			attributeName="opacity" 
    			dur="1.5s" 
    			values="1;0" 
    			begin="Horse_TR.end+4s" 
    			repeatCount="1" 
    			 
    			fill="freeze" />  
    </image>			 
                    
           <g id="btn" onclick='play()' > 
       <rect  x="2" y="3" rx="15"  id="rec1" width="100px" height="40px" fill="#4975B2" /> 
        <text x="20" y="33" font-size="32"  fill="white"> Start </text> 
     </g>	 	 
    </svg>	  
    </div>   
 
    <script> 
    var zodiac = new Audio(); 
    zodiac.src = 'https://svg-art.ru/files/diskoteka_avariya_novogodnyaya.mp3'; 
 
    function play() { 
      zodiac.play(); 
    } 
    </script>

Answer 6

Это не конкурсный ответ, а скорее призыв участвовать в конкурсе

===================================================================== Конкурс завершен 30.12.2019

Очень долго раскачивались в этом году потенциальные участники конкурса и видимо просто не рассчитали время или вмешались какие-то неожиданные события, например: предновогодние хлопоты :)))

Не бросайте свои начатые работы, они ещё пригодятся!

Все уже опубликованные ответы, кроме победившей в прошлом конкурсе, также как и новые ответы будут участвовать в новом конкурсе.

Новогодний конкурс анимации открыт вновь! 30. 12.2019

Все благодарности @HamSter за продолжение Новогоднего праздника!

Поздравляем победителя Harry Heman!

==========================================================================

Новогодний конкурс анимации открыт вновь! 05.01.2020

Все благодарности @Leks за продолжение Новогоднего праздника с плавным переходом к Рождеству!

==========================================================================

На приглашения принять и опубликовать ответы часто слышу

  1. Фронтенд не моё
  2. Не умею рисовать
  3. Никогда не занимался анимацией
  4. Совсем нет свободного времени

Но ведь всё это можно реализовать другими средствами.

Все благодарности за идею @A K♦

Не обязательно рисовать, можно взять готовую картинку и подвигать её.
Можно с помощью JS или другого языка, используя символы Юникода или Dos написать код, рисующий анимацию.

Всё зависит от вашей фантазии:

<canvas id ='NewYear'></canvas>
<script>
  var db = document.body;
  var c = document.getElementById('NewYear');
  var $ = c.getContext('2d');
  c.width = window.innerWidth;
  c.height = window.innerHeight;
  var resume;
  function relay(){
  window.requestAnimationFrame(relay);
  resume();
}
</script>
  <!--Script to Relay!-->
<script>
  //BEGIN SCRIPT RELAY TO ru.StackOverflow.com... 
  
  _s = db.querySelectorAll("script")[1].innerHTML.split("\n");
  x = 0; 
  y = 1; 
  c.width = w = window.innerWidth;
  c.height = h = _s.length*20;
  db.style.margin = 0;
  db.style.background = "hsla(0,0%,0%,1)";
  db.style.overflow = "hidden";
  $.textBaseline = "top";
  $.font = "1.1em monospace";
  
//PAUSE RELAY: ...
//С  НОВЫМ  2020 ГОДОМ! 
// УДАЧИ И ВЕЗЕНИЯ ВО ВСЕХ НАЧИНАНИЯХ, КАК В ВИРТУАЛЬНОМ,
// ТАК И В РЕАЛЬНОМ МИРЕ!
/*
          ★ 
         *o* 
        *♥*o*
       ***o*** 
      **o**♥*o* 
     **♥**o**o** 
    **o**♥***♥*o* 
   *****♥*o**o**** 
  **♥**o*****o**♥** 
 ******o*****♥**o*** 
****o***♥**o***o***♥* 
        || 
  \____ ||_____/
╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬ 
  
*/
  
resume = function(){
    $.globalCompositeOperation = "source-over";
    $.shadowBlur = 0; $.fillStyle = "hsla(0,0%,0%,0.4)";
    $.fillRect(0,0,w,h);
    $.shadowColor = "hsla(120,100%,50%,0.5)";
    $.shadowBlur = 9; $.fillStyle = "hsla(120,100%,20%,1)";
    $.globalCompositeOperation = "lighter";
  _s.forEach(function(t, i) {
      if (i <= y) {
        if (i == y) { t = t.substr(0, x); }
        $.fillText(t, 100, 100+i*16);       }
    });
                 
    $.fillStyle = "hsla(120,100%,50%,1)";
    $.fillRect(100+$.measureText(_s[y].substr(0, x)).width, 102+y*16, 10, 14);
    x++;
        if (x >= _s[y].length) { y++; x = 0;}
            if (y*16 > innerHeight-340) { $.translate(0, -0.5);}
                if (y >= _s.length-1) { window.clearInterval();}}
  
relay();
  
</script>

Источник Там есть и другие примеры

**Простой пример создания персонажа**

Наступает год металлической Крысы.
Нашел в сети рисунок крысы с минимальным количеством деталей.

Техника создания по шагам:

  • Загружаем рисунок в векторный редактор

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
       width="800" height="500" viewBox="0 0 800 500" preserveAspectRatio="xMinYMin meet">  
<image xlink:href="https://i.stack.imgur.com/F9rB3.jpg" width="100%" height="100%" />
</svg>

и наносим по контуру узловые точки

  • Сохраняем файл в векторном редакторе в формате SVG и копируем path в другой файл SVG

Добавляем анимацию рисования линии с помощью изменения атрибута stroke-dasharray для path На сайте много примеров создания подобных анимаций

<animate id="an_body" attributeName="stroke-dasharray" dur="4s" begin="0s" values="0 2482;2482 0" fill="freeze" />

Анимация готова. Я думаю, при желании её можно будет повторить для других картинок

let eye = document.getElementById("an_eye");
let mustache_1 = document.getElementById("an_mustache_1");
let mustache_2 = document.getElementById("an_mustache_2");
let mustache_3 = document.getElementById("an_mustache_3");
const btn = document.getElementById('btn1');
btn.addEventListener("click", () => {
  an_body.beginElement();
  eye = fRestartAnim(eye, 3600);
  mustache_1 = fRestartAnim(mustache_1, 5000);
  mustache_2 = fRestartAnim(mustache_2, 5000);
  mustache_3 = fRestartAnim(mustache_3, 5000);
});
function fRestartAnim(an, delay = 0) {
  const anClone = an.cloneNode(true);
  const anParent = an.parentNode;
  anParent.replaceChild(anClone, an);
  anClone.setAttribute("begin", performance.now() + delay + "ms");
  return anClone;
}
<div><button id="btn1">Click me</button></div>
<svg id="svg1" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="800" height="500" viewBox="0 0 800 500" preserveAspectRatio="xMinYMin meet">
  <style>
  .s0 {
    fill: none;
    stroke: black;
    stroke-width: 5;
  }
  #mustache_1, #mustache_2, #mustache_3 {
    stroke-width: 3;
  }
  </style>
  <rect width="100%" height="100%" fill="#D6DFE6" />
  <path id="body" class="s0" stroke-dasharray="0 2482" d="m228.8 142c0 0-1 9.2 1.5 12.7 6.9 9.7 20.4 13.6 32.2 15.7 13.1 2.3 27.1 0.1 39.7-4.1 13.2-4.4 24.9-12.8 36-21.3 5.6-4.3 10.6-9.5 15-15 4.6-5.8 9.8-11.6 12-18.7 2.2-7 3.3-14.4 0.7-22.1C360.6 72.7 351.5 65 340.9 56.1 326.1 43.9 308.2 34.5 289.5 30.3c-19.5-4.4-40.4-2.6-59.9 1.5-20.1 4.2-39.6 12.3-56.9 23.2-24.2 15.3-46.2 35-63.7 57.7-18.9 24.5-34 52.7-42.7 82.4-7.7 26.3-10.4 54.7-7.5 82 4.4 41.8 18.8 62.2 37.5 88.1 11.1 15.3 27 26.8 42.7 37.5 13.2 9 27.5 16.8 42.7 21.7 13.5 4.4 27.8 5.4 41.9 6.7 27 2.5 81.3 2.2 81.3 2.2l74.9-0.7c0 0 33.9-0.2 49.4-1 9.3-0.5 13-14.3 15.7-23.2 2.8-9.1 2.3-19.3 0-28.5-2.7-11-8.6-21.2-15.7-30-6.3-7.8-14.8-13.8-23.2-19.3-12.1-7.8-25.1-14.7-39-18.9-12.5-3.8-25.9-5.4-39-5.2-17.9 0.2-35.9 3.4-53.2 8.2-4.7 1.3-13.4 5.5-13.4 5.5 0 0 13.4-17.7 21.2-25.6 9.3-9.4 19.6-18 30.4-25.7 13-9.1 26.8-17.3 41.2-23.9 13.8-6.3 27.9-12.8 42.9-15 18.2-2.7 37.5-2.3 55.2 2.6 14.2 3.9 27.1 12.3 39 21 10.4 7.6 18.8 17.6 27.7 27 7.9 8.3 13.3 24.3 10.5 36.7-2.1 9.1-10.1 17.4-18.7 21-9 3.8-21.6 4.6-29.2-1.5-8.2-6.7-9.4-20.2-8.2-30.7 1.4-12.3 8.8-23.9 17.2-33 8.4-9 19.4-16.7 31.5-19.5 11.7-2.7 25.2-1.6 36 3.7 8.9 4.4 15.6 13 20.2 21.7 4.6 8.6 6.8 19.4 6.7 28.5 0 9.5-16.5 23.2-16.5 23.2 0 0 19.8 2.8 29.2 6 9.7 3.3 19.2 7.6 27.5 13.5 9.6 6.9 17.6 15.9 24.9 25.2 4.7 5.9 11.9 19 11.9 19l9 18c0 0 0.7 15.9 6.7 18.7 3.9 1.8 11.1-0.3 12-4.5 0.4-1.7-2.1-3-3.7-3.7-2.3-1.1-5.1-1.6-7.5-0.7-3.3 1.2-7.5 7.5-7.5 7.5h-26.2l-43.9 0.9c0 0-14.8-0.4-22.2-0.4-13.2-0.1-26.6-0.3-39.7 0.2-16.9 0.6-34.3-0.6-53.8 0.1-15.7 0.5-51.6 0.5-51.6 0.5" >
    <animate id="an_body" attributeName="stroke-dasharray" dur="4s" begin="indefinite" values="0 2482;2482 0" fill="freeze" restart="whenNotActive" />
  </path>
  <path id="eye" class="s0" stroke-dasharray="0 43" d="m570.4 371.6c0 0 5.3-5.3 8.5-7.2 2.9-1.7 6.1-3.4 9.5-3.7 3.6-0.3 7.5 0.5 10.7 2.3 3.1 1.7 7.4 7.5 7.4 7.5" >
    <animate id="an_eye" attributeName="stroke-dasharray" dur="1s" begin="indefinite" values="0 43;43 0" fill="freeze" restart="whenNotActive" />
  </path>
  <path id="mustache_1" class="s0" stroke-dasharray="0 110" d="m542.9 462c2.5-8 7-15.1 10.7-22.5 2.5-4.9 5.2-9.7 7.7-14.7 1.2-2.5 2.2-5.1 3.6-7.5 0.6-1.1 1.1-2.1 2-3.2 0.2-0.3 0.5 0.6 0.4 0.9-1 4.9-2.3 8.2-3.8 12.2-1.3 3.4-3.1 6.6-4.8 9.8-1.2 2.3-2.4 4.6-3.6 6.9-1.1 2-2.2 4.1-3.3 6.1-2.2 4-4.6 9-6.8 11.8-1.9 2.4-2.3 0.9-2.1 0.3z" >
    <animate id="an_mustache_1" attributeName="stroke-dasharray" dur="1s" begin="indefinite" 
        values="0 110;110 0" fill="freeze" restart="whenNotActive" />
  </path>
  <path id="mustache_2" class="s0" stroke-dasharray="0 157" d="m589.1 412.5c-1 3.9-0.4 9.7-1.1 14.6-0.8 5.5-2.3 10.9-3.4 16.4-1.2 6-2.7 11.9-3.7 17.9-1.1 6.4-2.4 12.8-2.6 19.3-0.1 1.9-0.3 7.3 0.3 5.6 1.5-5 1.7-7.7 2.6-11.6 1.3-5.6 2.9-11.1 4.3-16.6 1.3-5.2 2.6-10.3 3.5-15.5 0.5-2.8 0.9-5.6 1.2-8.3 0.4-3.7 0.9-7.3 1.1-11 0.2-3.7-0.2-7.1-0.1-11.3 0.1-3.8-1.5-1.6-2 0.5z" >
    <animate id="an_mustache_2" attributeName="stroke-dasharray" dur="1s" begin="indefinite" 
        values="0 157;157 0" fill="freeze" restart="whenNotActive" />
  </path>
  <path id="mustache_3" stroke-dasharray="0 159" class="s0" d="m608.2 408.4c-0.2 4.1 0.6 6.9 1.3 10.3 0.5 2.4 1.4 4.7 2 7 1.3 5.6 1.8 11.4 3.2 16.9 1.5 6.2 3.7 12.2 5.6 18.3 2.4 7.7 4.1 15.7 7.4 22.9 0.2 0.4 1.3 0.3 1.3-0.1-0.3-5.6-1.2-6.9-1.9-10.3-1.2-6.1-2.3-12.3-3.7-18.4-0.9-4-2-7.9-3.2-11.8-0.9-2.9-2-5.6-2.9-8.5-1-3.1-2.1-6.2-3-9.4-1.6-5.4-2.3-9.6-4.5-16.2-0.2-0.6-1.6-1.4-1.6-0.8z">
    <animate id="an_mustache_3" attributeName="stroke-dasharray" dur="1s" begin="indefinite" 
        values="0 159;159 0" fill="freeze" restart="whenNotActive" />
  </path>
</svg>

27.12.2019

Мерцание огней ёлочки

В векторном редакторе, точно также, как в примере выше наносим по контуру ёлочки узловые точки и забираем path этого контура в другой файл.

Применяем к этому контуру маску с разными цветами, анимируем перебор их, что создаёт иллюзию мерцания гирлянд.

Анимация начинается после клика по заснеженной ёлочке

10 раз моргает, затем пауза 5 сек. и снова моргает

<svg id="svg1" xmlns="http://www.w3.org/2000/svg"     xmlns:xlink="http://www.w3.org/1999/xlink" 
    width="100%" height="100%" viewBox="0 0 1680 1050" preserveAspectRatio="xMinYMin meet">
  <defs>
   <mask id="msk1">
    <rect fill="white" width="100%" height="100%"/>
  <path fill="#9939CD"  d="m832.5 54.2c-25 19.3-14.5 57.9-13.8 93.8 0.2 11.8-8 22.2-12.5 33.1-2.3 5.7-7.5 17-7.5 17 0 0-8.4 18.5-12 28.1-5.5 15-12.7 29.7-14.5 45.6-1 9.1 3.7 18.2 2.5 27.3-1.7 12.3-11.3 22.5-13.1 34.8-1.1 7.5 1.6 15.1 1.5 22.7-0.1 8.4-2.2 25-2.2 25 0 0-0.6 8.1-2.8 11.4-3.6 5.5-12.9 6-15.6 12-2.2 4.9 1.4 10.7 1.1 16.1-0.5 10-7.2 19.7-5.3 29.5 1 5.1 6.3 8.2 8.3 13.1 1.5 3.6-2.4 15.9-6.7 23.9-2.7 5.2-9.3 4.9-10 9.5-1.4 8.4 12 22.5 12 22.5l-8.9 17.8-4.4 30 1.7 30 9.5 10c1 20.7-2.8 6-8.9 11.1-6.3 6.1 2.1 17.9-0.8 26.1-1.7 4.7-9.2 11.7-9.2 11.7 0 0-5.5 11-4.4 16.7 1.1 5.5 8.9 7.9 10 13.3 1.4 7.1-4 14-5.6 21.1-1 4.8-3.3 9.6-2.5 14.5 0.7 4.1 6 6.9 5.8 11.1-0.2 6.5-8.5 10.4-10 16.7-2.4 9.9 1.1 20.4 1.9 30.6 0.4 4.3 0.5 8.6 1.4 12.8 1.4 7 3 14.1 6.1 20.6 2.7 5.5 4.7 13.4 10.6 15 7 1.9 12.8-8.2 20-8.9 14.8-1.4 29.1 6 43.4 10 8.2 2.3 18.7 2 24.1 7.9 10.5 11.5 10.1 15.7 18 17.4 7.7 1.7 21.5 3.3 28.6-1 7.2-4.3 10-12.8 15.3-17 8.3-6.6 14-3.5 20.7-6.3 6.6-2.7 12.1-7.9 18.9-10 6.4-2 13.3-1.9 20-2.2 7-0.4 15.3 4 21.1 0 5.9-4 4.8-13.5 7.8-20 2.5-5.5 6.5-10.4 8.3-16.1 1.3-4.1 0.5-8.7 1.7-12.8 1.7-5.9 6.7-10.7 7.8-16.7 2-10.6-0.8-21.6-2.2-32.3-0.9-6.4-4.2-12.5-3.9-18.9 0.3-5.8 2.4-11.5 5-16.7 1.8-3.7 6.8-5.9 7.2-10 1.2-10.4-4-22.5-12.2-28.9-4.6-3.6-14.9 2.6-17.2-2.8-5.6-13 23.5-20.9 23.9-35 0.3-8.6-13.3-22.2-13.3-22.2l-5-60.1c0 0-1.6-8.9-1.1-13.3 0.6-5.8 6-11 5-16.7-0.9-4.8-8.8-6.8-8.9-11.7-0.1-6.1 10.2-8.9 10.6-15 0.5-7.8-7.4-13.7-11.1-20.6-4.1-7.6-9.4-14.7-12.2-22.8-1.4-3.9-3.2 0.5-2.2-12.2 0.1-9.5-14.8-18.5-10-26.7 2.5-4.2 11.7 1.8 14.5-2.2 14.2-21.2-16.9-49-17.8-74.5-0.2-4.5 4.3-9.3 2.2-13.3-1.9-3.7-8-2.8-11.1-5.6-3-2.7-5.5-6.2-6.7-10-1.5-5 0-10.4 0-15.6 0-4.4 1.2-9.1 0-13.3-1.4-4.6-5-8.3-7.8-12.2-1.1-1.5-3.1-2.6-3.3-4.4-0.6-4.8 3.9-8.8 5.6-13.3 1.2-3.3 3.9-6.5 3.3-10-0.9-5.5-4.3-12.8-9.8-13.3-1.9-0.2-2.3 4.2-4.2 4-8-1.1-10.4-12.9-12.6-20.7-3.6-26.5-14.5-23.1-15.4-35.2-1.3-25.9 11.6-67.9-9.4-89-8.7-8.8-27.1-11.6-36.9-4z">
 <animate
    id="Three_fire"
    attributeName="fill"
    dur="0.5s"
    begin="svg1.click;Three_pause.end"
    values=" #CD9AE9; white;white;#CD9AE9"
    fill="freeze"
    repeatCount="10" />
 <animate
    id="Three_pause"
    attributeName="fill"
    dur="5s"
    begin="Three_fire.end"
    values=" white;white"
    fill="freeze"
    repeatCount="1" />   
   </path>
 </mask> 
 </defs> 
  
  <image mask="url(#msk1)" xlink:href="https://i.stack.imgur.com/PBRad.jpg" height="100%" width="100%"/>
</svg>

Добавляем звезду

Всё сделано, как и в других примерах выше - с помощью векторного редактора рисуем контур и анимируем цвет и прозрачность с помощью SVG фильтров

<svg id="svg1" xmlns="http://www.w3.org/2000/svg"     xmlns:xlink="http://www.w3.org/1999/xlink" 
    width="100%" height="100%" viewBox="0 0 1680 1050" preserveAspectRatio="xMinYMin meet">
     
  <defs>
  <filter id="glow" filterUnits="userSpaceOnUse"
            x="-50%" y="-50%" width="300%" height="300%">
       
      <feGaussianBlur in="SourceGraphic" stdDeviation="25" result="blur5"/>
      <feGaussianBlur in="SourceGraphic" stdDeviation="30" result="blur10"/>
      <feGaussianBlur in="SourceGraphic" stdDeviation="40" result="blur20"/>
      <feGaussianBlur in="SourceGraphic" stdDeviation="50" result="blur30"/>
      <feGaussianBlur in="SourceGraphic" stdDeviation="70" result="blur50"/>
       <feMerge result="blur-merged">
        <feMergeNode in="blur10"/>
        <feMergeNode in="blur20"/>
        <feMergeNode in="blur30"/>
        <feMergeNode in="blur50"/>
      </feMerge>
      
      <feColorMatrix result="yellow-blur" in="blur-merged" type="matrix"
                     values="0 0 0 0 0
                             0 1 0 0 0
                             0 0 1 0 0
                             0 0 0 0.7 0" />
      <feMerge>
        <feMergeNode in="yellow-blur"/>       
        <feMergeNode in="blur5"/>          
        <feMergeNode in="SourceGraphic"/>  
      </feMerge>
    </filter>
  
   <mask id="msk1">
    <rect fill="white" width="100%" height="100%"/>
  <path fill="#9939CD"  d="m832.5 54.2c-25 19.3-14.5 57.9-13.8 93.8 0.2 11.8-8 22.2-12.5 33.1-2.3 5.7-7.5 17-7.5 17 0 0-8.4 18.5-12 28.1-5.5 15-12.7 29.7-14.5 45.6-1 9.1 3.7 18.2 2.5 27.3-1.7 12.3-11.3 22.5-13.1 34.8-1.1 7.5 1.6 15.1 1.5 22.7-0.1 8.4-2.2 25-2.2 25 0 0-0.6 8.1-2.8 11.4-3.6 5.5-12.9 6-15.6 12-2.2 4.9 1.4 10.7 1.1 16.1-0.5 10-7.2 19.7-5.3 29.5 1 5.1 6.3 8.2 8.3 13.1 1.5 3.6-2.4 15.9-6.7 23.9-2.7 5.2-9.3 4.9-10 9.5-1.4 8.4 12 22.5 12 22.5l-8.9 17.8-4.4 30 1.7 30 9.5 10c1 20.7-2.8 6-8.9 11.1-6.3 6.1 2.1 17.9-0.8 26.1-1.7 4.7-9.2 11.7-9.2 11.7 0 0-5.5 11-4.4 16.7 1.1 5.5 8.9 7.9 10 13.3 1.4 7.1-4 14-5.6 21.1-1 4.8-3.3 9.6-2.5 14.5 0.7 4.1 6 6.9 5.8 11.1-0.2 6.5-8.5 10.4-10 16.7-2.4 9.9 1.1 20.4 1.9 30.6 0.4 4.3 0.5 8.6 1.4 12.8 1.4 7 3 14.1 6.1 20.6 2.7 5.5 4.7 13.4 10.6 15 7 1.9 12.8-8.2 20-8.9 14.8-1.4 29.1 6 43.4 10 8.2 2.3 18.7 2 24.1 7.9 10.5 11.5 10.1 15.7 18 17.4 7.7 1.7 21.5 3.3 28.6-1 7.2-4.3 10-12.8 15.3-17 8.3-6.6 14-3.5 20.7-6.3 6.6-2.7 12.1-7.9 18.9-10 6.4-2 13.3-1.9 20-2.2 7-0.4 15.3 4 21.1 0 5.9-4 4.8-13.5 7.8-20 2.5-5.5 6.5-10.4 8.3-16.1 1.3-4.1 0.5-8.7 1.7-12.8 1.7-5.9 6.7-10.7 7.8-16.7 2-10.6-0.8-21.6-2.2-32.3-0.9-6.4-4.2-12.5-3.9-18.9 0.3-5.8 2.4-11.5 5-16.7 1.8-3.7 6.8-5.9 7.2-10 1.2-10.4-4-22.5-12.2-28.9-4.6-3.6-14.9 2.6-17.2-2.8-5.6-13 23.5-20.9 23.9-35 0.3-8.6-13.3-22.2-13.3-22.2l-5-60.1c0 0-1.6-8.9-1.1-13.3 0.6-5.8 6-11 5-16.7-0.9-4.8-8.8-6.8-8.9-11.7-0.1-6.1 10.2-8.9 10.6-15 0.5-7.8-7.4-13.7-11.1-20.6-4.1-7.6-9.4-14.7-12.2-22.8-1.4-3.9-3.2 0.5-2.2-12.2 0.1-9.5-14.8-18.5-10-26.7 2.5-4.2 11.7 1.8 14.5-2.2 14.2-21.2-16.9-49-17.8-74.5-0.2-4.5 4.3-9.3 2.2-13.3-1.9-3.7-8-2.8-11.1-5.6-3-2.7-5.5-6.2-6.7-10-1.5-5 0-10.4 0-15.6 0-4.4 1.2-9.1 0-13.3-1.4-4.6-5-8.3-7.8-12.2-1.1-1.5-3.1-2.6-3.3-4.4-0.6-4.8 3.9-8.8 5.6-13.3 1.2-3.3 3.9-6.5 3.3-10-0.9-5.5-4.3-12.8-9.8-13.3-1.9-0.2-2.3 4.2-4.2 4-8-1.1-10.4-12.9-12.6-20.7-3.6-26.5-14.5-23.1-15.4-35.2-1.3-25.9 11.6-67.9-9.4-89-8.7-8.8-27.1-11.6-36.9-4z">
 <animate
    id="Three_fire"
    attributeName="fill"
    dur="0.5s"
    begin="svg1.click;Three_pause.end"
    values=" #CD9AE9; white;white;#CD9AE9"
    fill="freeze"
    repeatCount="10" />
 <animate
    id="Three_pause"
    attributeName="fill"
    dur="5s"
    begin="Three_fire.end"
    values=" white;white"
    fill="freeze"
    repeatCount="1" />   
   </path>
 </mask> 
 </defs> 
  
  <image mask="url(#msk1)" xlink:href="https://i.stack.imgur.com/PBRad.jpg" height="100%" width="100%"/>
  
   <path id="star_Full" fill="#CDE7FB"  filter="url(#glow)" opacity="0" d="M580.2 76.2 837.2 71.3 774.7 5.7 845.1 62.7 850.1 8c0 0 6.8 54.2 6 54.7-4.3 2.8 70.9-57.5 70.9-57.5L862.8 71.2 1131.2 76.2 864.4 81.8 982.3 203C960.8 189.7 856.8 91.3 856.7 91.2L849.8 194.2 845.7 91.1 714.3 203.7 832.8 82.5Z">
    <animate
        id="an_star"
        attributeName="opacity"
        dur="2.5s"
        begin="svg1.click;pause_star.end"
        values="1;1;0"              
        fill="freeze"
        repeatCount="5" /> 
    <animate
        id="pause_star"
        attributeName="opacity"
        dur="1.5s"
        begin="an_star.end"
        values="0;0"                
        fill="freeze"
        repeatCount="1" />  
   </path>      
</svg>
 

Добавляем дополнительно анимацию замены цвета для основы фильтра.

В результате получаем иллюзию случайно выбранного цвета для звезды

Так как длительность циклов замены основного цвета звезды, циклы применения фильтров, циклы применения масок, паузы имеют разные значения.

<animate
        id="fill_change_star"
        attributeName="fill"
        dur="20s"
        begin="svg1.click"
        values="#CDE7FB;yellowgreen;crimson;#CDE7FB"                
        fill="freeze"
        repeatCount="1" />  

Анимация начнется после клика по ёлочке

<svg id="svg1" xmlns="http://www.w3.org/2000/svg"     xmlns:xlink="http://www.w3.org/1999/xlink" 
    width="100%" height="100%" viewBox="0 0 1680 1050" preserveAspectRatio="xMinYMin meet">
     
  <defs>
  <filter id="glow" filterUnits="userSpaceOnUse"
            x="-50%" y="-50%" width="300%" height="300%">
       
      <feGaussianBlur in="SourceGraphic" stdDeviation="25" result="blur5"/>
      <feGaussianBlur in="SourceGraphic" stdDeviation="30" result="blur10"/>
      <feGaussianBlur in="SourceGraphic" stdDeviation="40" result="blur20"/>
      <feGaussianBlur in="SourceGraphic" stdDeviation="50" result="blur30"/>
      <feGaussianBlur in="SourceGraphic" stdDeviation="70" result="blur50"/>
       <feMerge result="blur-merged">
        <feMergeNode in="blur10"/>
        <feMergeNode in="blur20"/>
        <feMergeNode in="blur30"/>
        <feMergeNode in="blur50"/>
      </feMerge>
      
      <feColorMatrix result="yellow-blur" in="blur-merged" type="matrix"
                     values="0 0 0 0 0
                             0 1 0 0 0
                             0 0 0 0 0
                             0 0 0 0.7 0" />
      <feMerge>
        <feMergeNode in="yellow-blur"/>       
        <feMergeNode in="blur5"/>          
        <feMergeNode in="SourceGraphic"/>  
      </feMerge>
    </filter>
  
   <mask id="msk1">
    <rect fill="white" width="100%" height="100%"/>
  <path fill="#9939CD"  d="m832.5 54.2c-25 19.3-14.5 57.9-13.8 93.8 0.2 11.8-8 22.2-12.5 33.1-2.3 5.7-7.5 17-7.5 17 0 0-8.4 18.5-12 28.1-5.5 15-12.7 29.7-14.5 45.6-1 9.1 3.7 18.2 2.5 27.3-1.7 12.3-11.3 22.5-13.1 34.8-1.1 7.5 1.6 15.1 1.5 22.7-0.1 8.4-2.2 25-2.2 25 0 0-0.6 8.1-2.8 11.4-3.6 5.5-12.9 6-15.6 12-2.2 4.9 1.4 10.7 1.1 16.1-0.5 10-7.2 19.7-5.3 29.5 1 5.1 6.3 8.2 8.3 13.1 1.5 3.6-2.4 15.9-6.7 23.9-2.7 5.2-9.3 4.9-10 9.5-1.4 8.4 12 22.5 12 22.5l-8.9 17.8-4.4 30 1.7 30 9.5 10c1 20.7-2.8 6-8.9 11.1-6.3 6.1 2.1 17.9-0.8 26.1-1.7 4.7-9.2 11.7-9.2 11.7 0 0-5.5 11-4.4 16.7 1.1 5.5 8.9 7.9 10 13.3 1.4 7.1-4 14-5.6 21.1-1 4.8-3.3 9.6-2.5 14.5 0.7 4.1 6 6.9 5.8 11.1-0.2 6.5-8.5 10.4-10 16.7-2.4 9.9 1.1 20.4 1.9 30.6 0.4 4.3 0.5 8.6 1.4 12.8 1.4 7 3 14.1 6.1 20.6 2.7 5.5 4.7 13.4 10.6 15 7 1.9 12.8-8.2 20-8.9 14.8-1.4 29.1 6 43.4 10 8.2 2.3 18.7 2 24.1 7.9 10.5 11.5 10.1 15.7 18 17.4 7.7 1.7 21.5 3.3 28.6-1 7.2-4.3 10-12.8 15.3-17 8.3-6.6 14-3.5 20.7-6.3 6.6-2.7 12.1-7.9 18.9-10 6.4-2 13.3-1.9 20-2.2 7-0.4 15.3 4 21.1 0 5.9-4 4.8-13.5 7.8-20 2.5-5.5 6.5-10.4 8.3-16.1 1.3-4.1 0.5-8.7 1.7-12.8 1.7-5.9 6.7-10.7 7.8-16.7 2-10.6-0.8-21.6-2.2-32.3-0.9-6.4-4.2-12.5-3.9-18.9 0.3-5.8 2.4-11.5 5-16.7 1.8-3.7 6.8-5.9 7.2-10 1.2-10.4-4-22.5-12.2-28.9-4.6-3.6-14.9 2.6-17.2-2.8-5.6-13 23.5-20.9 23.9-35 0.3-8.6-13.3-22.2-13.3-22.2l-5-60.1c0 0-1.6-8.9-1.1-13.3 0.6-5.8 6-11 5-16.7-0.9-4.8-8.8-6.8-8.9-11.7-0.1-6.1 10.2-8.9 10.6-15 0.5-7.8-7.4-13.7-11.1-20.6-4.1-7.6-9.4-14.7-12.2-22.8-1.4-3.9-3.2 0.5-2.2-12.2 0.1-9.5-14.8-18.5-10-26.7 2.5-4.2 11.7 1.8 14.5-2.2 14.2-21.2-16.9-49-17.8-74.5-0.2-4.5 4.3-9.3 2.2-13.3-1.9-3.7-8-2.8-11.1-5.6-3-2.7-5.5-6.2-6.7-10-1.5-5 0-10.4 0-15.6 0-4.4 1.2-9.1 0-13.3-1.4-4.6-5-8.3-7.8-12.2-1.1-1.5-3.1-2.6-3.3-4.4-0.6-4.8 3.9-8.8 5.6-13.3 1.2-3.3 3.9-6.5 3.3-10-0.9-5.5-4.3-12.8-9.8-13.3-1.9-0.2-2.3 4.2-4.2 4-8-1.1-10.4-12.9-12.6-20.7-3.6-26.5-14.5-23.1-15.4-35.2-1.3-25.9 11.6-67.9-9.4-89-8.7-8.8-27.1-11.6-36.9-4z">
  <!-- Анимация цветов маски -->
 <animate
    id="Three_fire"
    attributeName="fill"
    dur="0.5s"
    begin="svg1.click;Three_pause.end"
    values=" #CD9AE9; white;white;#CD9AE9"
    fill="freeze"
    repeatCount="10" />
 <!-- Пауза анимации цветов маски -->
 <animate
    id="Three_pause"
    attributeName="fill"
    dur="5s"
    begin="Three_fire.end"
    values=" white;white"
    fill="freeze"
    repeatCount="1" />   
   </path>
 </mask> 
 </defs> 
  
  <image mask="url(#msk1)" xlink:href="https://i.stack.imgur.com/PBRad.jpg" height="100%" width="100%"/>
  
   <path id="star_Full" fill="#CDE7FB"  filter="url(#glow)" opacity="0" d="M580.2 76.2 837.2 71.3 774.7 5.7 845.1 62.7 850.1 8c0 0 6.8 54.2 6 54.7-4.3 2.8 70.9-57.5 70.9-57.5L862.8 71.2 1131.2 76.2 864.4 81.8 982.3 203C960.8 189.7 856.8 91.3 856.7 91.2L849.8 194.2 845.7 91.1 714.3 203.7 832.8 82.5Z">
      <!-- Анимация opacity звезды -->
    <animate
        id="an_star"
        attributeName="opacity"
        dur="2.5s"
        begin="svg1.click;pause_star.end"
        values="1;1;0"              
        fill="freeze"
        repeatCount="5" /> 
      <!-- Пауза анимация opacity звезды -->
    <animate
        id="pause_star"
        attributeName="opacity"
        dur="1.5s"
        begin="an_star.end"
        values="0;0"                
        fill="freeze"
        repeatCount="1" />  
       <!-- Замена цвета у звезды    -->
   <animate
        id="fill_change_star"
        attributeName="fill"
        dur="11s"
        begin="svg1.click;pause_star.end"
        values="#CDE7FB;red;#B34EE9;#15C14E"                
        fill="freeze"
        repeatCount="1" />  
   </path>      
    
       <!-- #CDE7FB;yellowgreen;crimson;#CDE7FB" -->
</svg>
 

Answer 7

Ламповая ASCII графика на Си. Посвящается всем, кто пишет на Си.
Осторожно. Возможен приступ эпилепсии (особенно если у Вас слабый ПК)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#define ROWS 19
#define COLS 26
void make_frame(const char ft[][COLS], const char sn[][COLS], char frame[][COLS]);
void rotate_snow(char sn[][COLS]);
void draw_frame(const char frame[][COLS]);
void delay(double sec);
void clear_screen();
int main()
{
    const char fir_tree[ROWS][COLS] =
    {
        "                         ",
        "                         ",
        "                         ",
        "           /\\            ",
        "          <  >           ",
        "          /\\/\\           ",
        "         /  o \\          ",
        "        /o     \\         ",
        "       /_      _\\        ",
        "        /      \\         ",
        "       /    o   \\        ",
        "      /  o       \\       ",
        "     /_        o _\\      ",
        "      /          \\       ",
        "     /    o       \\      ",
        "    /          o   \\     ",
        "   /__o_____________\\    ",
        "          |  |           ",
        "*************************"
    };
    char snow[ROWS - 1][COLS] =
    {
        "   *    *       *    *   ",
        "  *       *     *  *     ",
        "       *    *     *     *",
        "  *       *    *         ",
        "     *      *        *   ",
        "       *         *       ",
        "*           *        *   ",
        "        *            *  *",
        "    *              *     ",
        "      *        *         ",
        "*       *               *",
        "              *          ",
        "    *   *          *    *",
        "             *           ",
        "     *              *    ",
        "  *       *           *  ",
        "         *         *     ",
        "     *              *   *",
    };
    char frame[ROWS][COLS];
    while (1)
    {
        make_frame(fir_tree, snow, frame);
        draw_frame(frame);
        delay(0.1);
        rotate_snow(snow);
        clear_screen();
    }
    return 0;
}
void make_frame(const char ft[][COLS], const char sn[][COLS], char frame[][COLS])
{
    strcpy(frame[ROWS - 1], ft[ROWS - 1]);
    for (int i = 0; i < ROWS - 1; i++)
    {
        strcpy(frame[i], ft[i]);
        for (int j = 0; j < COLS; j++)
        {
            if (sn[i][j] == '*')
            {
                frame[i][j] = '*';
            }
        }
    }
}
void rotate_snow(char sn[][COLS])
{
    char temp[COLS];
    strcpy(temp, sn[ROWS - 2]);
    for (int i = ROWS - 3; i >= 0; i--)
    {
        strcpy(sn[i + 1], sn[i]);
    }
    strcpy(sn[0], temp);
}
void draw_frame(const char frame[][COLS])
{
    for (int i = 0; i < ROWS; i++)
    {
        puts(frame[i]);
    }
}
void delay(double sec)
{
    clock_t start = clock();
    while ((double)(clock() - start) / CLOCKS_PER_SEC < sec)
        continue;
}
void clear_screen()
{
    system("cls");
}
Answer 8

елочка

window.onload = () => { 
  let C = document.querySelector('canvas'), 
    $ = C.getContext('2d'), 
    W = C.width = innerWidth, 
    H = C.height = innerHeight 
 
  function bg() { 
    $.fillStyle = '#000' 
    $.fillRect(0, 0, W, H) 
  } 
 
  function circle(x, y, r, color) { 
    $.fillStyle = color 
    $.beginPath() 
    $.arc(x, y, r, 0, Math.PI * 2) 
    $.fill() 
  } 
 
  function line(x1, y1, x2, y2, color) { 
    $.strokeStyle = color 
    $.beginPath() 
    $.moveTo(x1, y1) 
    $.lineTo(x2, y2) 
    $.stroke() 
  } 
 
  let count = 30, 
    x, y, z, 
    radius = H / 3, 
    r 
 
  let mouseY = .8 * H 
 
  let color, 
    alpha, 
    step = H / 50, 
    jmax = 10, 
    margin = .1 * H, 
    imax = H - margin, 
    angle 
 
  function loop() { 
    bg() 
 
    line(W / 2, margin, W / 2, H, 'rgba(0,255,0,.5)') 
 
    for (let j = 0; j < jmax; j++) { 
      for (let i = margin; i < imax; i += step) { 
        angle = (i / imax) * (count / (2 * Math.PI)) + (j / jmax) * 2 * Math.PI 
 
        x = W / 2 + ((i - 10) / imax) * radius * Math.cos(angle) 
        z = radius + ((i - 10) / imax) * radius * Math.sin(angle) 
        y = i + 100 * Math.sin((mouseY - H / 2) / (H / 2)) 
        r = .0075 * z + .002 * y 
        alpha = (z / (2 * radius)) + .2 
 
        color = `rgba(255,255,255,${alpha/5})` 
        line(W / 2, i, x, y, color) 
 
        if (j % 2) { 
          color = `rgba(255,155,0,${alpha})` 
        } else { 
          color = `rgba(0,155,255,${alpha})` 
        } 
        circle(x, y, r, color) 
      } 
    } 
 
    count += Math.PI / 90 
 
    requestAnimationFrame(loop) 
  } 
 
  window.addEventListener('mousemove', e => mouseY = e.clientY) 
 
  loop() 
 
  window.addEventListener('resize', () => { 
    location.reload() 
  }) 
}
<body style="margin: 0; background: #000; overflow: hidden"> 
  <canvas></canvas> 
</body>

Answer 9

снежок

let snowmax = 40, 
  snowcolor = new Array("#aaaacc", "#ddddff", "#ccccdd", "#f3f3f3", "#f0ffff"), 
  snowtype = new Array("Arial Black", "Arial Narrow", "Times", "Comic Sans MS"), 
  snowletter = "*", 
  sinkspeed = 0.5, 
  snowmaxsize = 30, 
  snowminsize = 8, 
  snow = new Array(), 
  marginbottom, 
  marginright, 
  timer, 
  i_snow = 0, 
  x_mv = new Array(), 
  crds = new Array(), 
  lftrght = new Array(); 
 
function randommaker(range) { 
  rand = Math.floor(range * Math.random()); 
  return rand; 
} 
 
function initsnow() { 
  marginbottom = window.innerHeight; 
  marginright = window.innerWidth; 
  let snowsizerange = snowmaxsize - snowminsize; 
  for (i = 0; i <= snowmax; i++) { 
    crds[i] = 0; 
    lftrght[i] = Math.random() * 15; 
    x_mv[i] = 0.03 + Math.random() / 10; 
    snow[i] = document.getElementById("s" + i); 
    snow[i].style.fontFamily = snowtype[randommaker(snowtype.length)]; 
    snow[i].size = randommaker(snowsizerange) + snowminsize; 
    snow[i].fontSize = snow[i].size; 
    snow[i].style.color = snowcolor[randommaker(snowcolor.length)]; 
    snow[i].sink = sinkspeed * snow[i].size / 5; 
    snow[i].posx = randommaker(marginright - snow[i].size); 
    snow[i].posy = randommaker( 
      2 * marginbottom - marginbottom - 2 * snow[i].size 
    ); 
    snow[i].style.left = snow[i].posx; 
    snow[i].style.top = snow[i].posy; 
  } 
  movesnow(); 
} 
 
function movesnow() { 
  for (i = 0; i <= snowmax; i++) { 
    crds[i] += x_mv[i]; 
    snow[i].posy += snow[i].sink; 
    snow[i].style.left = snow[i].posx + lftrght[i] * Math.sin(crds[i]) + "px"; 
    snow[i].style.top = snow[i].posy + "px"; 
    if ( 
      snow[i].posy >= marginbottom - 2 * snow[i].size || 
      parseInt(snow[i].style.left) > marginright - 3 * lftrght[i] 
    ) { 
      snow[i].posx = randommaker(marginright - snow[i].size); 
      snow[i].posy = 0; 
    } 
  } 
  let timer = setTimeout("movesnow()", 50); 
} 
 
for (i = 0; i <= snowmax; i++) { 
  document.write( 
    "<span id='s" + 
    i + 
    "'style='position: absolute; top: -" + 
    snowmaxsize + 
    "'>" + 
    snowletter + 
    "</span>" 
  ); 
} 
 
initsnow(); 
 
window.addEventListener('resize', ()=> initsnow())
<body style="margin: 0; background: #222; overflow: hidden;"></body>

поздравлялка stroke-dash

body { 
  margin: 0; 
  background: #222; 
  font: 14em/1 cursive; 
} 
 
.line { 
  font-size: 0.6em; 
} 
 
svg { 
  position: absolute; 
  width: 100%; 
  height: 100%; 
} 
 
.text { 
  fill: none; 
  stroke-dasharray: 7% 27%; 
  stroke-width: 3px; 
  animation: stroke 9s infinite ease-in-out; 
} 
 
.text:nth-child(1) { 
  stroke: hotpink; 
  stroke-dashoffset: 7%; 
} 
 
.text:nth-child(2) { 
  stroke: firebrick; 
  stroke-dashoffset: 14%; 
} 
 
.text:nth-child(3) { 
  stroke: sandybrown; 
  stroke-dashoffset: 21%; 
} 
 
.text:nth-child(4) { 
  stroke: antiquewhite; 
  stroke-dashoffset: 28%; 
} 
 
.text:nth-child(5) { 
  stroke: steelblue; 
  stroke-dashoffset: 35%; 
} 
 
@keyframes stroke { 
  50% { 
    stroke-dashoffset: 36%; 
    stroke-dasharray: 0 88%; 
  } 
}
<svg viewBox="0 0 800 600"> 
        <symbol id="text"> 
            <text text-anchor="middle" x="50%" y="40%" class="line"> 
                С Новым 
            </text> 
            <text text-anchor="middle" x="50%" y="70%"> 
                годом! 
            </text> 
        </symbol> 
        <g> 
            <use xlink:href="#text" class="text"></use> 
            <use xlink:href="#text" class="text"></use> 
            <use xlink:href="#text" class="text"></use> 
            <use xlink:href="#text" class="text"></use> 
            <use xlink:href="#text" class="text"></use> 
        </g> 
</svg>

поздравлялка webgl

let vertexCount = 10000 * 4, 
  depth = 0, 
  fontName = "Arial, Helvetica, Verdana", 
  fontSize = 24, 
  frame = 0, 
  smoothness = 6; 
 
let vertices = [], 
  dVertices = []; 
 
let refctx = document.createElement("canvas").getContext("2d"); 
let gl = document.createElement("canvas").getContext("webgl"); 
let postctx = document.body 
  .appendChild(document.createElement("canvas")) 
  .getContext("2d"); 
let canvas = gl.canvas; 
 
let compileShader = function(type, source) { 
  let shader = gl.createShader(type), 
    status; 
  gl.shaderSource(shader, source); 
  gl.compileShader(shader); 
  status = gl.getShaderParameter(shader, gl.COMPILE_STATUS); 
  if (status) return shader; 
  console.error("Shader compile error", gl.getShaderInfoLog(shader)); 
  gl.deleteShader(shader); 
}; 
 
let createProgram = function(vertexShader, fragmentShader) { 
  let program = gl.createProgram(), 
    status; 
  gl.attachShader(program, vertexShader); 
  gl.attachShader(program, fragmentShader); 
 
  gl.linkProgram(program); 
 
  status = gl.getProgramParameter(program, gl.LINK_STATUS); 
  if (status) return program; 
 
  console.error("program link error", gl.getProgramInfoLog()); 
  gl.deleteProgram(program); 
}; 
 
let vertexShader = compileShader( 
  gl.VERTEX_SHADER, 
  ` 
	attribute vec4 a_position; 
    uniform vec2 u_resolution; 
    uniform float u_frame; 
    varying vec4 v_position; 
    varying float v_frame; 
    void main () { 
  	v_position = a_position; 
    v_frame = u_frame; 
    v_position.xy /= u_resolution; 
    v_position.y *= -1.0; 
     
    v_position.xy *= 10.0; 
    v_position.z += cos(u_frame / 20.0 + v_position.x * 10.0) * sin(u_frame / 10.0 + v_position.y * 12.0) * 0.02; 
    v_position.xy /= (1.0 + v_position.z); 
     
  	gl_Position = vec4(v_position.xy, 0.0, 1.0); 
    gl_PointSize = 3.0; 
  } 
` 
); 
 
let fragmentShader = compileShader( 
  gl.FRAGMENT_SHADER, 
  ` 
	precision mediump float; 
    varying vec4 v_position; 
    varying float v_frame; 
 	float pi = 3.141592653589793; 
    float hue2rgb(float f1, float f2, float hue) { 
      if (hue < 0.0) 
          hue += 1.0; 
      else if (hue > 1.0) 
          hue -= 1.0; 
      float res; 
      if ((6.0 * hue) < 1.0) 
          res = f1 + (f2 - f1) * 6.0 * hue; 
      else if ((2.0 * hue) < 1.0) 
          res = f2; 
      else if ((3.0 * hue) < 2.0) 
          res = f1 + (f2 - f1) * ((2.0 / 3.0) - hue) * 6.0; 
      else 
          res = f1; 
      return res; 
  } 
 
  vec3 hsl2rgb(vec3 hsl) { 
      vec3 rgb; 
       
      hsl.x = mod(hsl.x, 360.0); 
      hsl.x /= 360.0; 
 
      if (hsl.y == 0.0) { 
          rgb = vec3(hsl.z); // Luminance 
      } else { 
          float f2; 
 
          if (hsl.z < 0.5) 
              f2 = hsl.z * (1.0 + hsl.y); 
          else 
              f2 = hsl.z + hsl.y - hsl.y * hsl.z; 
 
          float f1 = 2.0 * hsl.z - f2; 
 
          rgb.r = hue2rgb(f1, f2, hsl.x + (1.0/3.0)); 
          rgb.g = hue2rgb(f1, f2, hsl.x); 
          rgb.b = hue2rgb(f1, f2, hsl.x - (1.0/3.0)); 
      }    
      return rgb; 
  } 
   
  void main () { 
 		vec4 col = vec4(hsl2rgb(vec3(v_frame + v_position.z * 2000.0, 1.0, .5)) * v_position.w, 1.0); 
  	gl_FragColor = col; 
  } 
` 
); 
 
let program = createProgram(vertexShader, fragmentShader); 
 
let aPosition = gl.getAttribLocation(program, "a_position"); 
let uResolution = gl.getUniformLocation(program, "u_resolution"); 
let uColor = gl.getUniformLocation(program, "u_color"); 
let uFrame = gl.getUniformLocation(program, "u_frame"); 
 
let vertexBuffer = gl.createBuffer(); 
 
gl.useProgram(program); 
gl.clearColor(0, 0, 0, 1); 
gl.clear(gl.COLOR_BUFFER_BIT); 
 
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); 
gl.vertexAttribPointer(aPosition, 4, gl.FLOAT, false, 0, 0); 
gl.enableVertexAttribArray(aPosition); 
let render = () => { 
  frame++; 
  gl.uniform1f(uFrame, frame); 
  gl.clear(gl.COLOR_BUFFER_BIT); 
 
  if ( 
    postctx.canvas.width !== postctx.canvas.offsetWidth || 
    postctx.canvas.height !== postctx.canvas.offsetHeight 
  ) { 
    canvas.width = postctx.canvas.width = postctx.canvas.offsetWidth; 
    canvas.height = postctx.canvas.height = postctx.canvas.offsetHeight; 
    gl.viewport(0, 0, canvas.width, canvas.height); 
    gl.uniform2fv(uResolution, [canvas.width, canvas.height]); 
  } 
 
  for (let i = 0; i < vertices.length; i += 4) { 
    let x = i; 
    let y = i + 1; 
    let z = i + 2; 
    let v = i + 3; 
 
    dVertices[x] -= (dVertices[x] - vertices[x]) / smoothness; 
    dVertices[y] -= (dVertices[y] - vertices[y]) / smoothness; 
    dVertices[z] -= (dVertices[z] - vertices[z]) / smoothness; 
    dVertices[v] -= (dVertices[v] - vertices[v]) / smoothness * 2; 
  } 
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(dVertices), gl.STATIC_DRAW); 
  gl.drawArrays(gl.POINTS, 0, dVertices.length / 4); 
 
  postctx.globalAlpha = 0.2; 
  postctx.globalCompositeOperation = "source-over"; 
  postctx.drawImage(canvas, 0, 0); 
  postctx.globalCompositeOperation = "lighten"; 
  postctx.globalAlpha = 1; 
  postctx.filter = "blur(8px)"; 
  postctx.drawImage(canvas, 0, 0); 
  postctx.filter = "blur(0)"; 
 
  requestAnimationFrame(render); 
}; 
 
let setText = text => { 
  vertices = []; 
 
  refctx.font = fontSize.toString() + "px " + fontName; 
  refctx.canvas.width = refctx.measureText(text).width || 100; 
  refctx.canvas.height = fontSize; 
  refctx.font = fontSize.toString() + "px " + fontName; 
  refctx.textBaseline = "top"; 
  refctx.clearRect(0, 0, refctx.canvas.width, refctx.canvas.height); 
  refctx.fillStyle = "#fff"; 
  refctx.fillText(text, 0, 0); 
 
  let { 
    data 
  } = refctx.getImageData( 
    0, 
    0, 
    refctx.canvas.width, 
    refctx.canvas.height 
  ); 
 
  for (let i = 0; i < vertexCount; i += 4) { 
    j = i % data.length; 
    let dI = (j / 4) >> 0; 
    let x = dI % refctx.canvas.width - refctx.canvas.width / 2; 
    let y = 
      ((dI / refctx.canvas.width) >> 0) % refctx.canvas.height - 
      refctx.canvas.height / 2; 
    let z = -depth / 2 + Math.random() * depth; 
    let v = data[j] * (data[j + 3] / 255) / 255; 
 
    vertices.push(x); 
    vertices.push(y); 
    vertices.push(z); 
    vertices.push(v); 
  } 
}; 
 
let textList = [ 
  'С', 
  'новым', 
  'годом,', 
  'друзья!' 
]; 
 
let textIndex = 0, 
  textGeneration = () => { 
    setText(textList[textIndex]); 
    setTimeout(() => { 
      textIndex++; 
      if (textIndex === textList.length) { 
        textIndex = 0; 
      } 
      textGeneration(); 
    }, 1500); 
  }; 
 
textGeneration(); 
 
for (let i = 0; i < vertexCount; i++) { 
  dVertices.push(0); 
} 
 
render();
canvas { 
  position: absolute; 
  top: 0; 
  left: 0; 
  width: 100%; 
  height: 100%; 
}

Answer 10

Всех с наступающим!

window.onload = function() { 
  var canvas = document.getElementById("canvas"), 
    ctx = canvas.getContext("2d"), 
    particlesOnScreen = 245, 
    particlesArray = [], 
    w, 
    h; 
 
  if (window.innerWidth > 1600) { 
    particlesOnScreen = 350; /// for desktop 
  } 
 
  if (window.innerWidth < 680) { 
    particlesOnScreen = 140; /// for mobile 
  } 
 
  function random(min, max) { 
    return min + Math.random() * (max - min + 1); 
  } 
 
  function clientBrowseerViewbox() { 
    w = canvas.width = window.innerWidth; 
    h = canvas.height = window.innerHeight; 
  } 
 
  clientBrowseerViewbox(); 
 
  function createSnowFlakes(particlesOnScreen) { 
    for (var i = 0; i < particlesOnScreen; i++) { 
      particlesArray.push({ 
        x: Math.random() * w, 
        y: Math.random() * h, 
        opacity: Math.random(), 
        speedX: random(-1, 1), 
        speedy: random(3, 4), 
        radius: random(0.2, 3) 
      }); 
    } 
  } 
 
  function drawSnowFlakes() { 
    for (var i = 0; i < particlesArray.length; i++) { 
      var gradient = ctx.createRadialGradient( 
        particlesArray[i].x, 
        particlesArray[i].y, 
        0, 
        particlesArray[i].x, 
        particlesArray[i].y, 
        particlesArray[i].radius 
      ); 
      gradient.addColorStop( 
        0, 
        "rgba(255,255,255," + particlesArray[i].opacity + " )" 
      ); 
      gradient.addColorStop( 
        0.7, 
        "rgba(210,236,242," + particlesArray[i].opacity + " )" 
      ); 
      gradient.addColorStop( 
        1, 
        "rgba(237,247,249," + particlesArray[i].opacity + " )" 
      ); 
 
      ctx.beginPath(); 
      ctx.arc( 
        particlesArray[i].x, 
        particlesArray[i].y, 
        particlesArray[i].radius, 
        0, 
        Math.PI * 2, 
        false 
      ); 
 
      ctx.fillStyle = gradient; 
      ctx.fill(); 
    } 
  } 
 
  function moveSnowFlakes() { 
    for (var i = 0; i < particlesArray.length; i++) { 
      particlesArray[i].x += particlesArray[i].speedX; 
      particlesArray[i].y += particlesArray[i].speedy; 
 
      if (particlesArray[i].y > h) { 
        particlesArray[i].x = Math.random() * w * 1.5; 
        particlesArray[i].y = -50; 
      } 
    } 
  } 
 
  function updateSnowFall() { 
    ctx.clearRect(0, 0, w, h); 
    drawSnowFlakes(); 
    moveSnowFlakes(); 
  } 
 
  setInterval(updateSnowFall, 50); 
 
  function snowRun() { 
    createSnowFlakes(particlesOnScreen); 
  } 
 
  snowRun(); 
 
  var addEvent = function(object, type, callback) { 
    if (object == null || typeof object == "undefined") return; 
    if (object.addEventListener) { 
      object.addEventListener(type, callback, false); 
    } else if (object.attachEvent) { 
      object.attachEvent("on" + type, callback); 
    } else { 
      object["on" + type] = callback; 
    } 
  }; 
 
  addEvent(window, "resize", function(event) { 
    clientBrowseerViewbox(); 
    snowRun(); 
  }); 
};
canvas { 
  position: absolute; 
  top: 0; 
  left: 0; 
  right: 0; 
  bottom: 0; 
  width: 100%; 
  height: 100vh; 
  z-index: 2; 
} 
 
body { 
  margin: 0; 
  padding: 0; 
  height: 100vh; 
  background-color: #19242c; 
  font-family: "Indie Flower", cursive; 
  color: #fff; 
  overflow: hidden; 
} 
 
h1 { 
  display: block; 
  position: absolute; 
  left: 50%; 
  text-align: center; 
  transform: translate(-50%, 1vh); 
  margin: 0; 
  min-width: 300px; 
  letter-spacing: 10px; 
  font-size: 6vw; 
} 
 
img { 
  position: absolute; 
  bottom: 0; 
  left: 50%; 
  transform: translateX(-50%); 
  width: 100vw; 
  max-width: 450px; 
} 
 
@media only screen and (max-width: 600px) { 
  h1 { 
    font-size: 40px; 
    letter-spacing: 5px; 
  } 
} 
 
@media only screen and (max-width: 380px) { 
  h1 { 
    font-size: 36px; 
    letter-spacing: 3px; 
  } 
  img { 
    max-width: 250px; 
  } 
} 
 
@media only screen and (max-height: 460px) { 
  h1 { 
    font-size: 18px; 
    top: 5px; 
  } 
  img { 
    bottom: 0%; 
    width: 56vh; 
  } 
}
<meta name="viewport" content="width=device-width, initial-scale=1"> 
<link href="https://fonts.googleapis.com/css?family=Indie+Flower&display=swap" rel="stylesheet"> 
<h1>Happy New Year</h1> 
<img src="https://github.com/BlackStar1991/Pictures-for-sharing-/blob/master/NewYear/cathing-snowflakes.png?raw=true" alt="cathing-snowflakes"> 
<canvas id="canvas"></canvas> 
<audio autoplay loop> 
	<source src="https://github.com/BlackStar1991/AudioSharing/blob/master/New%20Year/Train%20-%20Shake%20it%20up%2C%20it's%20Christmas%20time.mp3?raw=true" type="audio/mpeg"/> 
	<source src="https://github.com/BlackStar1991/AudioSharing/blob/master/New%20Year/Train%20-%20Shake%20it%20up%2C%20it's%20Christmas%20time.ogg?raw=true"/> 
                                                                                                                        
</audio>

PS Не ешьте желтый снег

Answer 11

Маленькой CSS елочке холодно в 2D

let cos = Math.cos, sin = Math.sin,  
    k = 1111, a1 = 0.5, a2 = -0.5,  
    far = 300, points = []; 
 
let many = (n, f) => [...Array(n)].map((e,i) => f(i)); 
 
document.body.innerHTML += many(54, i => `<div class="plane" style="--h:${Math.floor(i/18)};background-color: rgb(0,${50+(i%18>9?18-i%18:i%18)*20},0);--r2:${i*360/18}deg;"></div>`).join('\n') 
 
document.body.innerHTML += many(333, i => { 
   let x = Math.random()*100-50; 
   let y = Math.random()*200-170; 
   let z = Math.random()*100-50; 
   points.push({x, y, z}); 
   return `<span style="color:white">*</span>`  
}).join('\n') 
 
let stars = document.querySelectorAll('span'); 
 
function clamp(v, min, max) { 
    return Math.min(Math.max(v, min), max); 
} 
 
function project(p, i) { 
  p.y += 1; 
  if (p.y > 30) p.y = -170; 
  let x = p.x*cos(a1) + p.z*sin(a1); 
  let z = p.z*cos(a1) - p.x*sin(a1); 
  let y = p.y*cos(a2) +   z*sin(a2); 
  let d =   z*cos(a2) - p.y*sin(a2) + far; 
  x = (k/d)*x + innerWidth/2; 
  y = (k/d)*y + innerHeight/2; 
  let cull = Math.abs(x) > innerWidth || Math.abs(y) > innerHeight   
  stars[i].style.transform = cull ? 'scale(0)': `translate(${x}px,${y}px)`; 
} 
 
requestAnimationFrame(render); 
 
function render() { 
  requestAnimationFrame(render); 
  points.forEach(project); 
} 
 
addEventListener('mousemove', e => { 
    a1 = -e.x/5/180*Math.PI 
    a2 = (-20-e.y/20)/180*Math.PI 
   document.body.style.setProperty('--y', e.x/5 + 'deg')  
   document.body.style.setProperty('--x', -20-e.y/20 + 'deg') 
})
body { 
    user-select: none; 
    background-color:black; 
    overflow: hidden; 
    perspective: 400px; 
    height: 100vh; 
    --r1: 10deg; 
    --x: -40deg; 
    --y: 100deg; 
} 
 
.plane { 
    clip-path: polygon(50% 0%,100% 100%, 0% 100%); 
    display: iniline-block; 
    --height: calc(100px - calc(var(--h) * 15.2px)); 
    --width: calc(20px - calc(var(--h) * 3px)); 
    width: var(--width); 
    height: var(--height); 
    top: calc(50% - calc(var(--height) * 0.5)); 
    left: calc(50% - 10px); 
    position: absolute; 
    backface-visibility: hidden; 
    transform: rotateX(var(--x)) 
               rotateY(calc(var(--r2) + calc(var(--y) + var(--r1)))) 
               translateZ(calc(51.5px - calc(var(--h) * 8px))) 
               translateY(calc(var(--h) * -40px)) 
               rotateX(31deg); 
    transform-origin: 50% 100%; 
} 
 
.snow { 
    position: absolute; 
    width:400px; 
    height:400px; 
    border-radius:22%; 
    background-color: #eeef; 
    --s: calc(50% - 200px); 
    top: var(--s); 
    left: var(--s); 
    transform: translateY(55px) 
               rotateX(calc(90deg + var(--x))) 
               rotateZ(calc(var(--y) * -1)) 
} 
 
span { 
    position: fixed; 
    top: -13px; 
    left: -7px; 
    font-size: 20px; 
}
<div class="snow"></div>

Answer 12

Сделал самую простую ёлочку ради интереса с помощью символов. Всех с наступающим!

let a = 19, 
    b = 6; 
    c = 10; 
    h = 1, 
    x = 0, 
    d = '<p style="color: green;" align="center">', 
    s = '⭐', 
    u = '✵', 
    p = '||||'; 
    f = ['        
    
Answer 13

фейерверк

window.onload = () => { 
    let C = document.querySelector('canvas'), 
        W = C.width = innerWidth, 
        H = C.height = innerHeight, 
        $ = C.getContext('2d') 
 
    window.addEventListener('resize', () => { 
        W = innerWidth 
        H = innerHeight 
        $.fillStyle = '#000' 
        $.fillRect(0, 0, W, H) 
    }) 
 
    $.fillStyle = '#000' 
    $.fillRect(0, 0, W, H) 
 
    let listFire = [], 
        listFirework = [], 
        fireNumber = 10, 
        center = { 
            x: W / 2, 
            y: H / 2 
        }, 
        range = 100, 
        i 
    for (i = 0; i < fireNumber; i++) { 
        let fire = { 
            x: Math.random() * range / 2 - range / 4 + center.x, 
            y: Math.random() * range * 2 + H, 
            size: Math.random() + 0.5, 
            fill: '#fd1', 
            vx: Math.random() - 0.5, 
            vy: -(Math.random() + 4), 
            ax: Math.random() * 0.02 - 0.01, 
            far: Math.random() * range + (center.y - range) 
        } 
        fire.base = { 
            x: fire.x, 
            y: fire.y, 
            vx: fire.vx 
        } 
        listFire.push(fire) 
    } 
 
    function randomColor() { 
        let r = Math.floor(Math.random() * 256), 
            g = Math.floor(Math.random() * 256), 
            b = Math.floor(Math.random() * 256) 
        color = `rgba(${r},${g},${b})` 
        return color 
    } 
 
    (function loop() { 
        requestAnimationFrame(loop) 
        update() 
        draw() 
    })(); 
 
    function update() { 
        for (i = 0; i < listFire.length; i++) { 
            let fire = listFire[i] 
            if (fire.y <= fire.far) { 
                let color = randomColor() 
                for (i = 0; i < fireNumber; i++) { 
                    let firework = { 
                        x: fire.x, 
                        y: fire.y, 
                        size: Math.random() + 1.5, 
                        fill: color, 
                        vx: Math.random() * 5 - 2.5, 
                        vy: Math.random() * -5 + 1.5, 
                        ay: 0.05, 
                        alpha: 1, 
                        life: Math.round(Math.random() * range / 2) + range / 2 
                    } 
                    firework.base = { 
                        life: firework.life, 
                        size: firework.size 
                    } 
                    listFirework.push(firework) 
                } 
                fire.x = fire.base.x 
                fire.y = fire.base.y 
                fire.vx = fire.base.vx 
                fire.ax = Math.random() * 0.02 - 0.01 
            } 
            fire.x += fire.vx 
            fire.y += fire.vy 
            fire.vx += fire.ax 
        } 
 
        for (i = listFirework.length - 1; i >= 0; i--) { 
            let firework = listFirework[i] 
            if (firework) { 
                firework.x += firework.vx 
                firework.y += firework.vy 
                firework.vy += firework.ay 
                firework.alpha = firework.life / firework.base.life 
                firework.size = firework.alpha * firework.base.size 
                firework.alpha = firework.alpha > 0.6 ? 1 : firework.alpha 
                firework.life-- 
                if (firework.life <= 0) { 
                    listFirework.splice(i, 1) 
                } 
            } 
        } 
    } 
 
    function draw() { 
        $.globalCompositeOperation = 'source-over' 
        $.globalAlpha = 0.18 
        $.fillStyle = '#000' 
        $.fillRect(0, 0, W, H) 
 
        $.globalCompositeOperation = 'screen' 
        $.globalAlpha = 1 
        for (i = 0; i < listFire.length; i++) { 
            let fire = listFire[i] 
            $.beginPath() 
            $.arc(fire.x, fire.y, fire.size, 0, Math.PI * 2) 
            $.fillStyle = fire.fill 
            $.fill() 
        } 
 
        for (i = 0; i < listFirework.length; i++) { 
            let firework = listFirework[i] 
            $.globalAlpha = firework.alpha 
            $.beginPath() 
            $.arc(firework.x, firework.y, firework.size, 0, Math.PI * 2) 
            $.fillStyle = firework.fill 
            $.fill() 
        } 
    } 
window.addEventListener('resize', () => location.reload()) 
}
<body style="margin: 0; overflow: hidden"> 
<canvas></canvas> 
</body>

Answer 14

Вряд ли еще к этим 2м наработкам еще что-то прибавится, публиковал их не так давно в чатике, публикую тут:

РАЗ:

let chars, particles, canvas, ctx, w, h, current; 
let duration = 5000; 
let str = ['Happy', 'New', 'Year' , '2020']; 
 
init(); 
resize(); 
requestAnimationFrame(render); 
addEventListener('resize', resize); 
 
function makeChar(c){ 
    let tmp = document.createElement('canvas'); 
    let size = tmp.width = tmp.height = w<400?200:300; 
    let tmpCtx = tmp.getContext('2d'); 
    tmpCtx.font = 'bold '+size+'px Arial'; 
    tmpCtx.fillStyle = 'white'; 
    tmpCtx.textBaseline = "middle"; 
    tmpCtx.textAlign = "center"; 
    tmpCtx.fillText(c, size/2, size/2); 
    let char2 = tmpCtx.getImageData(0,0,size,size); 
    let char2particles = []; 
    for(var i=0; char2particles.length< particles; i++){ 
        let x = size*Math.random(); 
        let y = size*Math.random(); 
        let offset = parseInt(y)*size*4 + parseInt(x)*4; 
        if(char2.data[offset]) 
            char2particles.push([x-size/2,y-size/2]) 
    } 
    return char2particles; 
} 
 
function init() { 
    canvas = document.createElement('canvas'); 
    document.body.append(canvas); 
    document.body.style.margin = 0; 
    document.body.style.overflow = 'hidden' 
    document.body.style.background = 'black' 
    ctx = canvas.getContext('2d'); 
} 
 
function resize() { 
    w = canvas.width = innerWidth; 
    h = canvas.height = innerHeight; 
    particles = innerWidth<400? 55 : 199; 
} 
 
function makeChars(t) { 
    let actual = parseInt(t / duration) % str.length; 
    if (current === actual) 
        return 
    current = actual; 
    chars = [...str[actual]].map(makeChar); 
} 
 
function render(t) { 
    makeChars(t); 
    requestAnimationFrame(render); 
    ctx.fillStyle = '#00000010' 
    ctx.fillRect(0, 0, w, h); 
    chars.forEach((pts,i) => firework(t, i, pts)); 
} 
 
function firework(t, i, pts) { 
    t -= i*200; 
    let id = i + chars.length*parseInt(t - t%duration); 
    t = t % duration / duration; 
    let dx = (i+1)*w/(1+chars.length); 
    dx += Math.min(0.33, t)*100*Math.sin(id); 
    let dy = h*0.5; 
    dy += Math.sin(id*4547.411)*h*0.1; 
    if (t < 0.33) { 
      rocket(dx, dy, id, t*3); 
    } else { 
      explosion(pts, dx, dy, id, Math.min(1, Math.max(0, t-0.33)*2)); 
    } 
} 
 
function rocket(x, y, id, t) { 
  ctx.fillStyle = 'white'; 
  let r = 2-2*t + Math.pow(t, 15*t)*16; 
  y = h - y*t; 
  circle(x, y, r) 
} 
 
function explosion(pts, x, y, id, t) { 
  let dy = (t*t*t)*20; 
  let r = Math.sin(id)*1 + 3   
  r = t<0.5 ? (t+0.5)*t*r:r-t*r 
  ctx.fillStyle = `hsl(${id*55}, 55%, 55%)`; 
  pts.forEach((xy,i) => { 
      if (i%20 === 0) 
        ctx.fillStyle = `hsl(${id*55}, 55%, ${55+t*Math.sin(t*55+i)*45}%)`; 
      circle(t*xy[0] + x, h - y + t*xy[1] + dy, r) 
  }); 
} 
 
function circle(x,y,r) { 
  ctx.beginPath(); 
  ctx.ellipse(x, y, r, r, 0, 0, 6.283); 
  ctx.fill(); 
}

ДВА:

Update by @Alexandr_TT

Интересные эффекты спрятаны под капотом. Наведите мышку на фейерверк и подвигайте курсор.

document.body.innerHTML = ` 
 
<canvas id=canvas  
  style="background:black;position:fixed;top:0;left:0"></canvas> 
 
<input oninput="changeColor(this,0)" type="color" value="#ff0000"  
  style="position:fixed;z-index:1"> 
 
<input oninput="changeColor(this,1)" type="color" value="#00ff00"  
  style="position:fixed;z-index:1;left:100px"> 
 
<input oninput="changeColor(this,2)" type="color" value="#0000ff"  
  style="position:fixed;z-index:1;left:200px"> 
 
`; 
 
let ctx = canvas.getContext('2d'); 
let cos = Math.cos,  
    sin = Math.sin,  
    rnd = Math.random, 
    k = 500,  
    a1 = 0,  
    a2 = 0.3,  
    far = 300,  
    w,  
    h, 
    p, 
    data, 
    colors = [[255, 0, 0],[0,255,0],[0,0,255]], 
    points = []; 
 
 
for (let i = 0; i < 1; i ++){ 
    for (var _ = 0; _ < 1e4; _ ++) { 
        let x = rnd()*300-150; 
        let y = rnd()*300-150; 
        let z = rnd()*300-150; 
        let d = Math.sqrt(x*x + y*y + z*z); 
        if (d > 100 || d < 80) 
            continue; 
        let dt = rnd()/8; 
        let c = [255-(d-90)*25, (d-90)*25, 255-(d-90)*25]; 
        let r = (d-90)/6; 
        points.push({x, y, z, c, dt, d, r}); 
    } 
} 
 
for (let i = 0; i < 1; i ++){ 
    for (var _ = 0; _ < 3e3; _ ++) { 
        let x = rnd()*300-150; 
        let y = rnd()*3-1; 
        let z = rnd()*300-150; 
        let d = Math.sqrt(x*x + y*y + z*z); 
        if (d > 150 || d < 140) 
            continue; 
        let dt = 0.0; 
        points.push({x, y, z,  dt, d, r:2}); 
    } 
} 
 
function particle(p, t, dy, dx, color) { 
  t = Math.max(0, t - p.dt); 
     
  let X = t*p.x + dx; 
  let Y = -dy + t*p.y; 
  let Z = t*p.z; 
     
  let x = X*cos(a1) + Z*sin(a1); 
  let z = Z*cos(a1) - X*sin(a1); 
  let y = Y*cos(a2) + z*sin(a2); 
  let d = z*cos(a2) - Y*sin(a2) + far; 
  x = (k/d)*x + w/2; 
  y = (k/d)*y + h/2; 
  let blink = 1;//sin(t*11); 
  let r = color[0]*blink; 
  let g = color[1]*blink; 
  let b = color[2]*blink;  
  circle(x, y, p.r, r, g, b);   
} 
 
function circle(x, y, R, r, g, b) { 
  for (let i = -R; i < R; i++) { 
     for (let j = -R; j < R; j++) { 
         let d = 0.1/Math.sqrt(i*i + j*j); 
         pixel(x+i, y+j, r*d, g*d, b*d); 
     }  
  } 
} 
 
function pixel (x, y, r, g, b) { 
  if (x<0 || y<0 || x>w || y>h)   
     return 
  let o = (parseInt(y)*w+parseInt(x))*4; 
  data.data[o] += r; 
  data.data[1+o] += g; 
  data.data[2+o] += b;  
} 
 
function firework(points, t, dx, color){ 
    let dur = 5000;   
    t = t % dur / dur;    
    let dy;  
    if (t < 0.3) { 
        dy = -300 + 400*t*10/3 
        t = 0.01 + 0.005*sin(t*55); 
    } else { 
        t = (t-0.3)/7*10; 
        dy = 100 - t*40; 
        t = Math.pow(t, 0.1) 
        points.forEach(p => particle(p, t, dy, dx, color)); 
    } 
    
} 
 
function render(t) { 
  requestAnimationFrame(render); 
  data = ctx.getImageData(0, 0, w, h); 
  firework(points, t, -200,colors[0]);  
  firework(points, t - 1000, 0,colors[1]); 
  firework(points, t - 2000, 200,colors[2]); 
  ctx.putImageData(data, 0, 0); 
  ctx.fillStyle = '#00000009'; 
  ctx.fillRect(0,0,w,h) 
} 
 
addEventListener('wheel', e => k *= 1 - Math.sign(e.deltaY)*0.1); 
addEventListener('mouseup', e => p = null); 
addEventListener('mousedown', e => p = {x: e.x, y: e.y, a1, a2}); 
addEventListener('mousemove', e => { 
    if (!p) return 
    a1 = p.a1 - (e.x - p.x)/100;  
    a2 = p.a2 - (e.y - p.y)/100; 
}); 
addEventListener('resize', e => { 
  w = canvas.width = innerWidth; 
  h = canvas.height = innerHeight; 
}); 
dispatchEvent(new Event('resize')); 
requestAnimationFrame(render); 
 
function changeColor(el,i) { 
    colors[i] = [[1,3], [3,5], [5,7]] 
        .map(args => el.value.substring(...args)) 
        .map(hex => parseInt(hex, 16)); 
}

READ ALSO
Странно работает cin.get() после обработки ctrl+c

Странно работает cin.get() после обработки ctrl+c

Суть программы в том, что пользователь вводит строку, которая посимвольно считывается и выводится на экранРеализована обработка ctrl+c, в результате...

87
Ассемблер зациклился

Ассемблер зациклился

Есть задание "Образовать строку из исходной, повторив 1-й и элемент 1 раз, 2-й элемент 2 раз, 3 и элемент – 3 раза и тд" на с++ с ассемблерными вставками

102
Принципы ООП. Интерфейс

Принципы ООП. Интерфейс

Пишу класс для работы с матрицамиУказатель и кол-во строк и столбцов сокрыто, это понятно

95