Хорошо бы поднять настроение себе и другим. Копировать и рассылать открыточки с красивыми картинками и гифками, скаченными из сети, уже как-то не интересно.
Хочется чего-то необычного, яркого, праздничного, которое есть только у тебя и которое можно подарить близкому человеку со словами,- "Я сделал это для тебя!"
или оставить у себя с чувством удовлетворения и гордости :-)
Идея сделать новогодний конкурс анимаций принадлежит @Hamster
Вот и рисунок, который она дала для образца.
Смотрите, как и в любой другой новогодней открытке, тут есть потенциал для всевозможных анимаций.
Например:
Можно легко сделать с помощью stroke-dasharray
для широкой строки. Добавить радиальный градиент, анимацию вращения строки и перемещения градиента.
Нарисовать в CSS или в SVG многие смогут и далее за анимировать размеры, вращение, падение снежинок.
Анимация фразы - С Новым 2019 годом!
движение фразы и/или покачивание, обводка, появление букв
Анимация новогодних персонажей,- белочки, зайчики :) Дед мороз и снегурочка
Можно делать весь вышеперечисленный список анимаций, можно реализовать один пункт или несколько.
Главное условие - картинки можно брать любые или рисовать свои, но анимация должна быть своя, никакого копи-паста!
Конкурс завершился.
Благодаря вашим работам дорогие участники, конкурс получился интересным, ярким, запоминающимся. Мы вместе узнали имена новых участников, которые сразу, с ходу ворвались в конкурс и сделали очень крутые работы.
Все работы сделаны на высоком уровне и каждая по своему интересна и хороша.
ВНИМАНИЕ! Ёлка не идеальна и только для современных браузеров и только в качестве примера!
Это бандл из моих предыдущих ответов.
Как видите, код стал модульным - можно на его базе собрать любого Франкенштейна. Также код вариативный везде, где только можно - любой коэффициент можно поменять, чтобы добиться желаемого результата и резиновый (на сколько смог). Повторюсь, что я не умею в векторную графику и канвас, поэтому накодил все на дивах и картинках. Разверните на всю страницу, если сильно сплющит.
UPD 0: Добавил покачивание снежинок, изменил некоторые коэффициенты и сменил изображение звездочек елки на более нейтральное.
UPD 1: Добавил текст и заанимировал.
UPD 2: Санта! Он будет появляться и махать рукой с разных сторон экрана. Думаю, далее будут только какие-то минорные правки, а так - это финалочка ;)
UPD 3: Оптимизация. Теперь все делает один цикл (вместо 4-х, как раньше). Открытка стала чуть более снисходительна на старт: картинки появляются только после полной загрузки и убрал ненужный тут $(document).ready()
Скрипт по-прежнему костыль :)
const randomBetween = (a, b) => {
return (a + (Math.random() * (b - a)));
}
const randomArr = (arr) => {
return arr[Math.round(Math.random() * (arr.length - 1))];
}
const params = {
snowflakes: {
amount: 15,
duration: {
min: 3,
max: 8
},
size: {
min: 10,
max: 32
},
src: [
"http://pngimg.com/uploads/snowflakes/snowflakes_PNG7578.png",
"https://vignette.wikia.nocookie.net/fantendo/images/2/27/Snowflake.png/revision/latest?cb=20121220012520",
"https://latxikadelacerveza.es/wp-content/plugins/christmas-panda/assets/images/snowflake_5.png"
],
container: "#snowflakes"
},
tree: {
amount: 300,
stretching: 1.4,
movement: 5,
src: "https://i.imgur.com/pPjPR8q.png",
duration: {
min: 5,
max: 50
},
size: {
min: 20,
max: 30
},
container: "#tree"
},
rays: {
amount: 40,
duration: 30,
width: 3,
height: 100,
perspective: 150,
color: "rgba(215,249,111,1)",
container: "#rays"
},
text: {
text: "С Новым 2019 годом!",
duration: 30,
width: 3,
height: 100,
perspective: 150,
color: "rgba(215,249,111,1)",
container: "#text"
}
}
let totalAmount = 0;
for (let key in params) {
let amount = params[key].amount;
totalAmount += typeof amount === "number" ? amount : 0;
}
for (let i = 0; i < totalAmount; i++) {
if (i < params.snowflakes.amount) {
let snowflake = $("<img src='" + randomArr(params.snowflakes.src) + "'>");
let randomSize = randomBetween(params.snowflakes.size.min, params.snowflakes.size.max);
snowflake.css({
"width": randomSize + "px",
"height": randomSize + "px",
"left": randomBetween(0, 100) + "%",
"animation-duration": randomBetween(params.snowflakes.duration.min, params.snowflakes.duration.max) + "s"
});
$(params.snowflakes.container).append(snowflake);
}
if (i < params.tree.amount) {
if (i === 0) {
$(params.tree.container).append("<img class='main' src='" + params.tree.src + "'>");
}
let star = $("<img src='" + params.tree.src + "'>");
let top = randomBetween(0, randomBetween(70, 100));
let randomSize = (randomBetween(params.tree.size.min, params.tree.size.max) * (top + 10) / 100);
star.css({
"width": randomSize + "px",
"height": randomSize + "px",
"left": "calc(50% - " + (Math.sin(top / params.tree.stretching) * top) + "px)",
"top": top + "%",
"animation-duration": randomBetween(params.tree.duration.min, params.tree.duration.max) + "s",
"transform-origin": (50 + randomBetween(-params.tree.movement, params.tree.movement)) + "% " + (50 + randomBetween(-params.tree.movement, params.tree.movement)) + "%"
});
$(params.tree.container).append(star);
}
if (i < params.rays.amount) {
if (i === 0) {
$(params.rays.container).css({
"animation-duration": params.rays.duration + "s",
width: params.rays.height * 2 + "px",
height: params.rays.height * 2 + "px"
});
window.alignRays = () => {
let mainStar = $(params.tree.container).find(".main");
$(params.rays.container).css("top", (mainStar.offset().top - params.rays.height) + (mainStar.height() / 2) + "px");
}
$(window).on("resize", window.alignRays);
}
let ray = $("<div></div>");
ray.css({
"width": params.rays.width + "px",
"height": params.rays.height + "px",
"transform": "perspective(" + params.rays.perspective + "px) rotateZ(" + (360 / params.rays.amount * i) + "deg) rotateX(-60deg)",
"background": "linear-gradient(to bottom, rgba(0,0,0,0) 0%," + params.rays.color + " 100%)"
});
$(params.rays.container).append(ray);
}
if (i < params.text.text.length) {
let char = params.text.text.substr(i, 1);
char = char === " " ? " " : char;
let charElem = $("<div>" + char + "</div>");
charElem.css("animation-delay", (i / 10) + "s");
$(params.text.container).append(charElem);
}
if (i === totalAmount - 1) {
$("#root").css("display", "block");
window.alignRays();
let selector = [];
for (let key in params) {
let container = params[key].container;
selector.push(typeof container === "string" ? container + " > img" : "");
}
selector = selector.join(",");
$(selector).css("display", "none");
$(selector).on("load", (e) => $(e.target).css("display", ""));
}
}
let santa = $("#santa");
santa.css("display", "none");
santa.on("load", (e) => $(e.target).css("display", ""));
setInterval(() => {
let side = ["right", "left"][Math.round(Math.random())];
let randTop = Math.round(Math.random() * ($(window).height() - 220));
santa.css("top", randTop + "px");
santa.addClass(side);
setTimeout(() => {
santa.removeClass();
}, 2000);
}, 4000);
body,
html {
margin: 0;
width: 100%;
height: 100%;
background: radial-gradient(ellipse at 50% 30%, #a1c920 10%, #1e2708 100%);
overflow: hidden;
}
#root {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
display: none;
}
#santa {
position: absolute;
display: none;
z-index: 12;
top: 20px;
width: 135px;
animation-duration: 2s;
transform-origin: bottom;
animation-timing-function: linear;
}
#santa.left {
animation-name: santa-left;
display: block;
left: -135px;
}
#santa.right {
animation-name: santa-right;
display: block;
right: -135px;
}
#text {
position: absolute;
bottom: 8%;
left: 0;
right: 0;
margin: 0 auto;
z-index: 11;
width: 390px;
white-space: nowrap;
}
#text>div {
position: relative;
display: inline-block;
float: left;
font-size: 40px;
font-family: Pacifico;
animation-name: text;
animation-iteration-count: infinite;
transform-origin: center center;
animation-timing-function: linear;
animation-duration: 4s;
color: white;
opacity: 0;
text-shadow: 0 0 10px yellow;
}
#rays {
position: absolute;
top: 0;
left: 0;
right: 0;
margin: 0 auto;
border-radius: 100%;
z-index: 8;
animation-name: rotate;
transform-origin: center center;
animation-iteration-count: infinite;
animation-timing-function: linear;
background: radial-gradient(circle, rgba(0, 0, 0, 0.2) 0%, rgba(0, 212, 255, 0) 70%);
}
#rays>div {
position: absolute;
top: 0;
left: 0;
right: 0;
margin: 0 auto;
transform-origin: center bottom;
}
#snowflakes {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 7;
}
#snowflakes>img {
position: absolute;
animation-name: drop;
transform-origin: top center;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
#tree {
position: absolute;
top: 20%;
left: 0;
right: 0;
bottom: 0;
margin: 0 auto;
width: 200px;
height: 270px;
z-index: 9;
}
#tree>img.main {
position: absolute;
top: -10px;
left: 0;
right: 0;
margin: 0 auto;
width: 35px;
height: 35px;
z-index: 1;
animation-duration: 20s;
animation-name: rotate;
transform-origin: center center;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
#tree>img {
position: absolute;
animation-name: shake;
transform-origin: center center;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
}
@keyframes drop {
0% {
top: 0%;
opacity: 0;
transform: rotate(0deg);
}
20%,
80% {
opacity: .7;
}
50% {
opacity: .5;
}
100% {
top: 100%;
opacity: 0;
transform: rotate(360deg);
}
}
@keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes text {
0% {
transform: rotate(-20deg) scale(0);
opacity: 0;
}
10% {
transform: rotate(10deg) scale(1.1);
opacity: 1;
}
20% {
transform: rotate(-5deg) scale(.9);
opacity: 1;
}
30% {
transform: rotate(0deg) scale(1);
opacity: 1;
}
80% {
transform: scale(1);
opacity: 1;
}
90% {
transform: scale(2);
opacity: 0;
}
100% {
transform: rotate(0deg) scale(1);
opacity: 0;
}
}
@keyframes shake {
0%,
100% {
transform: rotate(0deg) scale(1);
opacity: .4;
}
10% {
transform: rotate(50deg) scale(.5);
opacity: .6;
}
20% {
transform: rotate(180deg) scale(.7);
opacity: .7;
}
30% {
transform: rotate(150deg) scale(1);
opacity: .4;
}
40% {
transform: rotate(130deg) scale(.6);
opacity: .8;
}
50% {
transform: rotate(60deg) scale(0);
opacity: 1;
}
60% {
transform: rotate(120deg) scale(.4);
opacity: .8;
}
70% {
transform: rotate(300deg) scale(.1);
opacity: .7;
}
80% {
transform: rotate(240deg) scale(.5);
opacity: .6;
}
90% {
transform: rotate(200deg) scale(.9);
opacity: .3;
}
}
@keyframes santa-right {
from,
to {
transform: translate3d(0, 0, 0);
}
10%,
30%,
50%,
70%,
90% {
transform: rotate(-75deg);
}
20%,
40%,
60%,
80% {
transform: rotate(-65deg);
}
0%,
100% {
transform: rotate(0deg);
}
}
.santa-right {
animation-name: santa-right;
}
@keyframes santa-left {
10%,
30%,
50%,
70%,
90% {
transform: rotate(75deg);
}
20%,
40%,
60%,
80% {
-webkit-transform: rotate(65deg);
transform: rotate(65deg);
}
0%,
100% {
transform: rotate(0deg);
}
}
.santa-left {
-webkit-animation-name: santa-left;
animation-name: santa-left;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Pacifico" rel="stylesheet">
<div id="root">
<div id="tree"></div>
<div id="snowflakes"></div>
<div id="rays"></div>
<div id="text"></div>
<img id="santa" class="right" src="https://i.imgur.com/Fyyiz3d.png">
</div>
Всех с наступающим!!
Сцена создана без использования каких-либо ресурсов. Только математика.
Запаситесь видеокартой, тут процессор не делает почти совсем ничего, фрагментный шейдер тут больше чем в 400 строчек получился =)
<script>
var fragCode =`
precision highp float;
uniform vec2 resolution;
uniform vec3 eye;
uniform vec3 lightPos;
uniform float time;
// https://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
// distance functions
float dot2( in vec2 v ) {
return dot(v,v);
}
float sdCappedCone( in vec3 p, in float h, in float r1, in float r2 ){
vec2 q = vec2( length(p.xz), p.y );
vec2 k1 = vec2(r2,h);
vec2 k2 = vec2(r2-r1,2.0*h);
vec2 ca = vec2(q.x-min(q.x,(q.y < 0.0)?r1:r2), abs(q.y)-h);
vec2 cb = q - k1 + k2*clamp( dot(k1-q,k2)/dot2(k2), 0.0, 1.0 );
float s = (cb.x < 0.0 && ca.y < 0.0) ? -1.0 : 1.0;
return s*sqrt( min(dot2(ca),dot2(cb)) );
}
// vertical
float sdCylinder( vec3 p, vec2 h ){
vec2 d = abs(vec2(length(p.xz),p.y)) - h;
return min(max(d.x,d.y),0.0) + length(max(d,0.0));
}
float sdSphere( vec3 p, float s ){
return length(p)-s;
}
float sdPlane( vec3 p , float down){
return p.y - down;
}
float plane(vec3 p, vec3 n, float offs) {
return dot(p, n) - offs;
}
// distance functions operations
float opS( float d1, float d2 ){
return max(-d2,d1);
}
vec2 opU( vec2 d1, vec2 d2 ){
return (d1.x<d2.x) ? d1 : d2;
}
vec3 opRep( vec3 p, vec3 c ){
return mod(p,c)-0.5*c;
}
float opSmoothU( float d1, float d2, float k ) {
float h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 );
return mix( d2, d1, h ) - k*h*(1.0-h);
}
vec2 rotate(vec2 p, float ang) {
float c = cos(ang), s = sin(ang);
return vec2(p.x*c - p.y*s, p.x*s + p.y*c);
}
vec2 repeatAng(vec2 p, float n) {
float ang = 2.0*3.14/n;
float sector = floor(atan(p.x, p.y)/ang + 0.5);
p = rotate(p, sector*ang);
return p;
}
///
const float PI =3.141592;
const float PI2 = 6.2831853;
const float maxd = 256.0; //Max depth
float nearestD = maxd;
vec3 color = vec3(0.0, 0.0, 1.0);
float flakes(vec3 p) {
const float snowflakeMaxDist = 20.0;
if ( (abs(p.x) > snowflakeMaxDist) ||
(abs(p.y) > snowflakeMaxDist) ||
(abs(p.z) > snowflakeMaxDist) )
return 9999.9;
float snowPush = 0.25*time;
p.x += snowPush*-3.0;
p.y += snowPush*1.5;
p.z += snowPush*-0.25;
const float modDist = 2.0;
float stepX = floor(p.x/modDist);
float stepY = floor(p.y/modDist);
float stepZ = floor(p.z/modDist);
vec3 flakeP = vec3(
mod(p.x,modDist),
mod(p.y,modDist),
mod(p.z,modDist)
);
vec3 flakePos = vec3(modDist*0.5);
flakePos.x += sin(snowPush+stepY*1.0)*(2.0/5.0)*modDist;
flakePos.y += sin(snowPush+stepZ*1.3)*(2.0/5.0)*modDist;
flakePos.z += sin(snowPush+stepX*1.7)*(2.0/5.0)*modDist;
return sdSphere(flakeP- flakePos, 0.03);
}
// noise
float hash(vec3 p) {
p = fract( p*0.3183099+.1 );
p *= 17.0;
return fract( p.x*p.y*p.z*(p.x+p.y+p.z) );
}
float noise( in vec3 x ){
vec3 p = floor(x);
vec3 f = fract(x);
f = f*f*(3.0-2.0*f);
return mix(mix(mix( hash(p+vec3(0,0,0)),
hash(p+vec3(1,0,0)),f.x),
mix( hash(p+vec3(0,1,0)),
hash(p+vec3(1,1,0)),f.x),f.y),
mix(mix( hash(p+vec3(0,0,1)),
hash(p+vec3(1,0,1)),f.x),
mix( hash(p+vec3(0,1,1)),
hash(p+vec3(1,1,1)),f.x),f.y),f.z);
}
float noise( vec2 x ){
return noise(vec3(x, 0.));
}
const float VERY_FAR = 1e11;
float ground(vec3 p){
float d = -0.50 ;
p.y += noise(p)*.33 ;
d = sdPlane(p, d);
return d;
}
vec2 star(vec3 p) {
p.y -=1.5;
p.xy = repeatAng(p.xy, 5.0); // 3. Clone five cornders radially about Z axis
p.xz = abs(p.xz); // 2. Symmetrical about XoY and ZoY
vec3 n = vec3(0.5, 0.25, 0.8);
float d = plane(p, normalize(n), 0.065); // 1. A plane cutting the corner of X+Y+Z+
return vec2(d, .900 );
}
vec2 green(vec3 p) {
float d = VERY_FAR;
float k = .12;
d = sdCappedCone( p - vec3(.0, .99, .0), .4, 0.45, .0);
d = opSmoothU(d, sdCappedCone( p - vec3(.0, .55, .0), .5, 0.55, .0), k);
d = opSmoothU(d, sdCappedCone( p - vec3(.0, .11, .0), .6, 0.65, .0), k);
return vec2( d, 0.090 );
}
vec2 trunk(vec3 p) {
float d = VERY_FAR;
d = sdCylinder(p-vec3(.0, -.5,.0), vec2(0.1, 0.6));
return vec2( d, 0.000 );
}
vec2 toy(vec3 p, float col) {
float d = VERY_FAR;
d = sdSphere(p, 0.07);
return vec2( d, col );
}
vec2 toys(vec3 p) {
vec2 res = vec2(VERY_FAR, -1);
float r = .42;
float h = -0.57;
res = opU( res, toy(p-vec3(-r, h, -r), 0.990) );
res = opU( res, toy(p-vec3(-r, h, r), 0.099) );
res = opU( res, toy(p-vec3( r, h, -r), 0.999) );
res = opU( res, toy(p-vec3( r, h, r), 0.555) );
r = .3;
h = 0.5;
res = opU( res, toy(p-vec3(-r, h, -r), 0.990) );
res = opU( res, toy(p-vec3(-r, h, r), 0.099) );
res = opU( res, toy(p-vec3( r, h, -r), 0.999) );
res = opU( res, toy(p-vec3( r, h, r), 0.555) );
r = .5;
h = -0.05;
res = opU( res, toy(p-vec3(-r, h, 0.), 0.990) );
res = opU( res, toy(p-vec3( 0, h, -r), 0.099) );
res = opU( res, toy(p-vec3( r, h, 0.), 0.999) );
res = opU( res, toy(p-vec3( 0, h, r), 0.555) );
return res;
}
vec2 tree(vec3 p) {
vec2 res = vec2(VERY_FAR, -1);
res = opU( res, green(p) );
res = opU( res, trunk(p) );
res = opU( res, star(p) );
res = opU( res, toys(p) );
return res;
}
float snowmans(vec3 p) {
// mirror 3
p.xz = repeatAng(p.xz, 3.0);
p.xz = abs(p.xz);
float k = .12;
float d = sdSphere( p - vec3(1.5, 0.7, 3.0), .2);
d = opSmoothU(d, sdSphere( p - vec3(1.5, 0.2, 3.0), .3), k);
d = opSmoothU(d, sdSphere( p - vec3(1.5, -0.4, 3.0), .4), k);
return d;
}
float snowfall(vec3 p) {
vec3 q = vec3(mod(p.x, 3.0) - 1.5, p.yz);
return sdSphere( q - vec3(1.5, 0.7, 3.0), .02);
}
vec2 snow(vec3 p) {
float k = .12;
float d = ground(p);
d = opSmoothU(d, snowmans( p ), k);
d = opSmoothU( d, flakes(p), k );
return vec2( d, .999 );
}
vec2 snowmans_accesories(vec3 p) {
// mirror 3
p.xz = repeatAng(p.xz, 3.0);
p.xz = abs(p.xz);
float k = .12;
vec2 res = vec2(sdSphere( p - vec3(1.50, 0.70, 3.20), .02), 0.00 );
res = opU(res, vec2(sdSphere( p - vec3(1.44, 0.75, 3.18), .02), 0.00 ));
res = opU(res, vec2(sdSphere( p - vec3(1.56, 0.75, 3.18), .02), 0.00 ));
res = opU(res, vec2(sdSphere( p - vec3(1.50, 0.25, 3.30), .02), 0.00 ));
res = opU(res, vec2(sdSphere( p - vec3(1.50, -0.40, 3.40), .02), 0.00 ));
return res;
}
vec2 map(vec3 p) {
vec2 res = vec2(VERY_FAR, -1);
res = opU( res, snow(p) );
res = opU( res, snowmans_accesories(p) );
res = opU( res, tree(p) );
return res;
}
// ray direction
vec3 rayDirection(float fieldOfView, vec2 size) {
vec2 xy = gl_FragCoord.xy - size / 2.0;
float z = size.y / tan(radians(fieldOfView) / 2.0);
return normalize(vec3(xy, -z));
}
// compute view matrix
mat4 viewMatrix(vec3 eye, vec3 center, vec3 up) {
vec3 f = normalize(center - eye);
vec3 s = normalize(cross(f, up));
vec3 u = cross(s, f);
return mat4(
vec4(s, 0.0),
vec4(u, 0.0),
vec4(-f, 0.0),
vec4(0.0, 0.0, 0.0, 1)
);
}
// ro - ray origin
// rd - ray direction
vec2 castRay( in vec3 ro, in vec3 rd ) {
float tmin = 1.0;
float tmax = 32.0;
float t = tmin;
float m = -1.0;
for ( int i=0; i<128; i++ ) {
float precis = 0.0001*t;
vec2 res = map( ro+rd*t );
if ( res.x<precis || t>tmax )
break;
t += res.x/1.4;
m = res.y;
}
if ( t>tmax )
m=-1.0;
return vec2( t, m );
}
// estimate normal at point
// http://iquilezles.org/www/articles/normalsSDF/normalsSDF.htm
const float NORMAL_EPSILON = 0.0005;
vec3 estimateNormal(vec3 pos) {
vec2 e = vec2(1.0,-1.0)*0.5773*NORMAL_EPSILON;
return normalize( e.xyy*map( pos + e.xyy ).x +
e.yyx*map( pos + e.yyx ).x +
e.yxy*map( pos + e.yxy ).x +
e.xxx*map( pos + e.xxx ).x );
}
const vec3 K_a = vec3(.3, .2, .2);
const vec3 K_d = vec3(.2, .4, .7);
const vec3 K_s = vec3(.1, .1, .1);
const float shininess = 3.5;
const vec3 lightIntensity = vec3(0.7, 0.7, 0.7);
vec3 phongContribForLight(vec3 k_d, vec3 k_s, float alpha, vec3 p, vec3 eye,
vec3 lightPos, vec3 lightIntensity) {
vec3 N = estimateNormal(p);
vec3 L = normalize(lightPos - p);
vec3 V = normalize(eye - p);
vec3 R = normalize(reflect(-L, N));
float dotLN = dot(L, N);
float dotRV = dot(R, V);
if (dotLN < 0.0) {
// Light not visible from this point on the surface
return vec3(0.0, 0.0, 0.0);
}
if (dotRV < 0.0) {
// Light reflection in opposite direction as viewer, apply only diffuse
// component
return lightIntensity * (k_d * dotLN);
}
return lightIntensity * (k_d * dotLN + k_s * pow(dotRV, alpha));
}
vec3 phongIllumination(vec3 k_a, vec3 k_d, vec3 k_s, float alpha, vec3 p, vec3 eye, vec3 materialColor) {
vec3 color = materialColor * k_a;
color += phongContribForLight(k_d, k_s, alpha, p, eye, lightPos, lightIntensity);
return color;
}
vec3 decodeMaterialColor(float material) {
float r = material * 10.;
r = r - fract(r);
r = r/10.;
float g = material * 100. - r * 100.;
g = g - fract(g);
g = g/10.;
float b = material * 1000. - r * 1000. - g * 100.;
b = b - fract(b);
b = b/10.;
return vec3(r, g, b);
}
vec3 phong(vec3 p, vec3 eye, float material) {
vec3 materialColor = decodeMaterialColor(material);
return phongIllumination(K_a, K_d, K_s, shininess, p, eye, materialColor);
}
// http://iquilezles.org/www/articles/rmshadows/rmshadows.htm
float softShadow( in vec3 ro, in vec3 rd, in float mint, in float tmax ){
float res = 1.0;
float t = mint;
for( int i=0; i<12; i++ )
{
float h = map( ro + rd*t ).x;
res = min( res, 8.0*h/t );
t += clamp( h, 0.02, 0.10 );
if( res<0.005 || t>tmax ) break;
}
return clamp( res, 0.0, 1.0 );
}
// ambient occlusion
float ao( in vec3 pos, in vec3 nor ){
float occ = 0.0;
float sca = 1.0;
for( int i=0; i<5; i++ )
{
float hr = 0.01 + 0.12*float(i)/4.0;
vec3 aopos = nor * hr + pos;
float dd = map( aopos ).x;
occ += -(dd-hr)*sca;
sca *= 0.95;
}
return clamp( 1.0 - 3.0*occ, 0.0, 1.0 );
}
void main(void) {
vec3 direction = rayDirection(60.0, resolution);
mat4 viewToWorld = viewMatrix(eye, vec3(0.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0));
vec3 worldDir = (viewToWorld * vec4(direction, 0.0)).xyz;
vec2 dist = castRay(eye, worldDir);
if (dist.x > 24.) {
gl_FragColor = vec4(0.9, 0.9, 0.9, 1.0);
} else {
vec3 pt = eye + dist.x * worldDir;
vec3 nor = estimateNormal( pt );
float occ = ao( pt, nor );
float shadow = softShadow( pt, normalize(lightPos-pt), 0.1, 22.2);
vec3 color = phong(pt, eye, dist.y)*sqrt(occ);
color += color * shadow;
gl_FragColor = vec4(color, 1.0);
}
}
`;
</script>
<script>
function GLx() {
var canvas = document.createElement('canvas');
document.body.appendChild(canvas);
var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
return {
gl: gl,
buffer: buffer,
program: program,
resize: resize
};
function program(vs, fs) {
var pid = gl.createProgram(); // program id
shader(vs, gl.VERTEX_SHADER);
shader(fs, gl.FRAGMENT_SHADER);
gl.linkProgram(pid);
var p = {
uniform: uniform,
attribute: attribute,
use: use
};
return p;
function use() {
gl.useProgram(pid);
return p;
}
function attribute(name, count) {
var al = gl.getAttribLocation(pid, name);
return {
bind: bind
};
function bind(buffer) {
buffer.bind();
gl.vertexAttribPointer(al, count, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(al);
}
}
function uniform(type, name) {
var ul = gl.getUniformLocation(pid, name);
return {
set: set
};
function set(v1, v2, v3, v4) {
gl['uniform' + type](ul, v1, v2, v3, v4);
}
}
function shader(src, type) {
var sid = gl.createShader(type);
gl.shaderSource(sid, src);
gl.compileShader(sid);
var message = gl.getShaderInfoLog(sid);
if (message.length > 0){
console.log(src.split('\n').map(function (str, i) {
return ("" + (1 + i)).padStart(4, "0") + ": " + str
}).join('\n'));
throw message;
}
gl.attachShader(pid, sid);
}
}
function buffer(data) {
var array = new Float32Array(data);
var buffer = gl.createBuffer();
var type = gl.ARRAY_BUFFER;
gl.bindBuffer(type, buffer);
gl.bufferData(type, array, gl.STATIC_DRAW);
gl.bindBuffer(type, data = null);
return {
bind: bind
};
function bind() {
gl.bindBuffer(type, buffer);
}
}
function resize() {
var c = canvas;
if (c.clientWidth !== c.width || c.clientHeight !== c.height) {
c.width = c.clientWidth;
c.height = c.clientHeight;
return true;
}
}
}
// full-screen-triangle with webgl
function FullScreenTriangle(fragCode) {
var glx = GLx();
var vertices = glx.buffer([-1, 3, -1, -1, 3, -1]);
var vertCode =
`attribute vec2 coords;
void main(void) {
gl_Position = vec4(coords.xy, 0.0, 1.0);
}`;
glx.triangleProgram = glx.program(vertCode, 'precision highp float;' + fragCode).use();
glx.triangleProgram.attribute("coords", 2).bind(vertices);
glx.draw = function () {
var gl = glx.gl;
glx.resize();
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.clearColor(0, 0, 0, 1);
gl.drawArrays(gl.TRIANGLES, 0, 3);
};
return glx;
}
var Mouse3D = (function(){
var theta = 0;
var phi = 0;
var mouse = {x: 0, y: 0};
var radius = 7;
var dragStartMousePosition, dragStartPhi, dragStartTheta;
var callback;
var mouse3d = {
init: init,
eye: [0, 0, radius],
callback: function (cb) {
callback = cb;
}
};
return mouse3d;
function init() {
window.addEventListener('mousemove', mouseMove, false);
window.addEventListener('mouseup', mouseUp, false);
window.addEventListener('mousedown', mouseDown, false);
window.addEventListener('mousewheel', mouseWheel, false);
}
function mouseMove(event) {
if (event.target.tagName !== 'CANVAS') return;
mouse = event;
if (dragStartMousePosition) {
rotate();
}
}
function updateCameraPosition() {
mouse3d.eye[0] = radius * Math.cos(phi) * Math.sin(theta);
mouse3d.eye[1] = radius * Math.sin(phi);
mouse3d.eye[2] = radius * Math.cos(phi) * Math.cos(theta);
callback && callback();
}
function rotate() {
var amountX = dragStartMousePosition ? dragStartMousePosition.x - mouse.x : 0;
var amountZ = mouse.y - dragStartMousePosition.y;
theta = dragStartTheta + amountX/120;
phi = dragStartPhi + amountZ/120;
var limit = Math.PI / 2;
phi = phi > limit ? limit : phi;
phi = phi < -limit ? -limit : phi;
updateCameraPosition();
}
function mouseDown(event) {
if (event.target.tagName !== 'CANVAS') return;
dragStartPhi = phi;
dragStartTheta = theta;
dragStartMousePosition = event;
}
function mouseUp() {
if (event.target.tagName !== 'CANVAS') return;
rotate();
dragStartMousePosition = null;
dragStartPhi = 0;
dragStartTheta = 0;
}
function mouseWheel(e){
radius *= e.wheelDelta > 0 ? 0.9 : 1.1;
updateCameraPosition();
}
})();
Mouse3D.init();
let fst = FullScreenTriangle(fragCode);
let resolution = fst.triangleProgram.uniform('2f', 'resolution');
let lightPos = fst.triangleProgram.uniform('3f', 'lightPos');
let time = fst.triangleProgram.uniform('1f', 'time');
let eye = fst.triangleProgram.uniform('3f', 'eye');
addEventListener('mousemove', drawFrame);
animate();
var started = new Date().getTime();
function animate() {
requestAnimationFrame(animate);
drawFrame();
}
function drawFrame() {
let t = (new Date().getTime() - started)/1000;
resolution.set(fst.gl.drawingBufferWidth, fst.gl.drawingBufferHeight);
time.set(t);
lightPos.set(Math.cos(t/10)*10,10,Math.sin(t/10)*10);
eye.set(Mouse3D.eye[0], Mouse3D.eye[1], Mouse3D.eye[2]);
fst.draw();
}
</script>
<style>
body, canvas {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
margin: 0;
}
</style>
Это все придумано давным давно, однако раньше, трассировка лучей в реальном времени была фантастикой и таким образом создавали статические картинки. сегодня каждый обладатель компьютера с видеокартой может написать фрагментный шейдер, который делает трассировку простеньких (и не очень) сцен в реальном времени.
Для этого потребуются:
Во фрагменте кода приведена уже склеенная версия, исходник на github gists и blocks.
Итак, попробую по-простому описать что тут происходит, т.к. код вы можете и сами почитать.
Для начала WebGL инициализируется таким образом, чтобы нарисовать один треугольник, который покрывает весь экран как на изображении ниже, или как-то иначе, главное вызвать фрагментный шейдер для каждого пикселя.
Для этого я как-то написал себе маленькую утилиту GLx, которая мне помогает сделать это в несколько строк.
Фрагментный шейдер делает всю работу.
Перед формированием каждого кадра, из javascript в шейдер передаются некоторые переменные, которые характеризуют сцену, в нашей ёлочке это положение наблюдателя в декартовых координатах, размер картинки, и еще для анимации понадобится время. конечно перед каждым кадром обновлять все uniform переменные не нужно, но в этом примере я сделал так для простоты кода.
Далее в каждом фрагменте(пикселе) происходит трассировка луча
В нашем случае это raymarching, что про сути есть оптимизация шага трассировки.
В отличие от классического представления объектов сцены в виде треугольников, тут используются математические формулы дистанции до поверхностей. Шагая вдоль луча, применяется огромная формула (функция map(vec3)
), которая вычисляет эту дистанцию до всех объектов в сцене. Дистанция которую вернула эта функция - безопасное расстояние, шагнув на которое, мы точно не во что не упремся. Собственно это будет следующий шаг, и так до тех пор, пока луч не упрется в поверхность.
vec2 map(vec3 p) {
vec2 res = vec2(VERY_FAR, -1);
res = opU( res, snow(p) );
res = opU( res, snowmans_accesories(p) );
res = opU( res, tree(p) );
return res;
}
изначально результат инициализируется расстоянием очень далеким от наблюдателя, т.е. будущим фоном. -1 выступает в роли идентификатора материала.
функция opU
- названа от слов operation и union и предназначена для объединения объектов сцены.
каждый компонент, объединяемый этой операцией это в свою очередь тоже функция, только описывающая один объект сцены плюс возвращающая вторым компонентом идентификатор(цвет) материала в найденной точке. в свою очередь состят из более простых примитив, сфер, цилиндров, кубов, фракталов, поверхностей безье, чего душе угодно, между которыми возможно всевозможные трансформации, булевые операции итд.
все вместе это и описывает нашу сцену с елочкой.
после того, как точка пересечения луча с поверхностью найдена, начинается самое сложное и самое интересное, это определение цвета найденной точки
в нашей сцене цвет состоит из нескольких компонентов:
этот список можно было бы продолжать всякими экранными эффектами, компонентами других моделей освещения итд
Непосредственно при моделировании никаких сложных примитивов не использовано, все объекты собраны из
сфер
float sdSphere( vec3 p, float s ){
return length(p)-s;
}
плоскостей
// horizontal
float sdPlane( vec3 p , float down){
return p.y - down;
}
float plane(vec3 p, vec3 n, float offs) {
return dot(p, n) - offs;
}
усеченных конусов
float sdCappedCone( in vec3 p, in float h, in float r1, in float r2 ){
vec2 q = vec2( length(p.xz), p.y );
vec2 k1 = vec2(r2,h);
vec2 k2 = vec2(r2-r1,2.0*h);
vec2 ca = vec2(q.x-min(q.x,(q.y < 0.0)?r1:r2), abs(q.y)-h);
vec2 cb = q - k1 + k2*clamp( dot(k1-q,k2)/dot2(k2), 0.0, 1.0 );
float s = (cb.x < 0.0 && ca.y < 0.0) ? -1.0 : 1.0;
return s*sqrt( min(dot2(ca),dot2(cb)) );
}
цилиндра
float sdCylinder( vec3 p, vec2 h ){
vec2 d = abs(vec2(length(p.xz),p.y)) - h;
return min(max(d.x,d.y),0.0) + length(max(d,0.0));
}
и шума(noise), для создания "сугробов":
float hash(vec3 p) {
p = fract( p*0.3183099+.1 );
p *= 17.0;
return fract( p.x*p.y*p.z*(p.x+p.y+p.z) );
}
float noise( in vec3 x ){
vec3 p = floor(x);
vec3 f = fract(x);
f = f*f*(3.0-2.0*f);
return mix(mix(mix( hash(p+vec3(0,0,0)),
hash(p+vec3(1,0,0)),f.x),
mix( hash(p+vec3(0,1,0)),
hash(p+vec3(1,1,0)),f.x),f.y),
mix(mix( hash(p+vec3(0,0,1)),
hash(p+vec3(1,0,1)),f.x),
mix( hash(p+vec3(0,1,1)),
hash(p+vec3(1,1,1)),f.x),f.y),f.z);
}
Так же тут используется отражение и поворот пространства, для создания 6 снеговиков и звезды, операция smoothMin для создания плавных переходов между поверхностями
Upd2: добавил деталей, теперь летит снег и взаимодействует с другим снегом в сцене при помощи smooth minimum
, двигается источник света, самую актуальную версию смотрите тут
PPS: все происходящее тут можно сильно оптимизировать, начиная от шума, который тут считается каждый раз, его можно либо запечь в текстуру, либо сразу предоставить текстуру шума, затем функция map()
... для разных частей освещения или эффектов можно использовать различные упрощенные версии map()
кандидаты на это - построение теней, ambient occlusion, из последнего убрать бы летящий снег, сам raymarching тоже может быть оптимизирован на счет первоначальной трассировки более простых сцен(кубов или сфер в которых вписаны объекты сцены), для уменьшения количества шагов трассировки
PPPS: Где можно про это почитать:
ну и конечно же гуглёж по терминам
signed distance field(function), SDF
raymarching, raytracing
UPD 31.03.2019: Починил ( правда ценой производительности (: ) артефакты прошлой версии, когда при взгляде сверху появлялись черно-цветные полосы.
А вот и Ёлочка!
Я плох в векторной графике и канвасе, но что-то смыслю в математике, поэтому как смог :) В общем, можно заметить, что есть очень много общего со скриптом снежинок, который я кидал ранее. Соль заключается в том, что позиционированием звездочек полностью занимается js при помощи функции y=sin(x)*x
, график которой похож на елку. Перевернув эту функцию на 90 градусов можно получить точки расположения звездочек по оси Y. Размер звездочек вариативный, но зависит от смещения сверху: чем ниже, тем больше звезда, как на картинке. Немного визуальных эффектов и вот :) Хорошо себя чувствует при ресайзе, разверните на весь экран, для примера. Не совсем похоже, конечно, но, думаю, имеет место быть.
let params = {
amount: 800,
duration: {
min: 8,
max: 20
},
size: {
min: 20,
max: 45
}
}
const randomBetween = (a, b) => {
return (a + (Math.random() * (b - a)));
}
const randomArr = (arr) => {
return arr[Math.round(Math.random() * (arr.length - 1))];
}
$(document).ready(() => {
for (let i = 0; i < params.amount; i++) {
let star = $("<img class='star' src='https://vignette.wikia.nocookie.net/justdance/images/2/2e/Star.png/revision/latest?cb=20160307193808'>");
let top = randomBetween(0, randomBetween(50, 100));
let randomSize = (randomBetween(params.size.min, params.size.max) * top / 100);
star.css({
"width": randomSize + "px",
"height": randomSize + "px",
"left": "calc(50% - " + (Math.sin(top) * top) + "px)",
"top": top * 3 + "px",
"animation-duration": randomBetween(params.duration.min, params.duration.max) + "s",
"transform-origin": (50 + randomBetween(-15, +15)) + "% " + (50 + randomBetween(-15, 15)) + "%"
});
$("#root").append(star);
}
});
body,
html {
margin: 0;
width: 100%;
height: 300px;
background: green;
}
#root {
position: absolute;
width: 100%;
height: 100%;
filter: drop-shadow(0 0 2px white);
overflow: hidden;
}
.main-star {
position: absolute;
top: 3px;
left: calc(50% - 15px);
z-index: 9;
width: 30px;
height: 30px;
}
.star {
position: absolute;
animation-name: shake;
transform-origin: center center;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
}
@keyframes shake {
0%,
100% {
transform: rotate(0deg) scale(1);
opacity: 0;
}
10% {
transform: rotate(50deg) scale(.5);
opacity: 0.7;
}
20% {
transform: rotate(184deg) scale(.7);
opacity: 0.8;
}
30% {
transform: rotate(365deg) scale(1);
opacity: 0.7;
}
40% {
transform: rotate(130deg) scale(.6);
opacity: 0.9;
}
50% {
transform: rotate(10deg) scale(0);
opacity: 1;
}
60% {
transform: rotate(46deg) scale(.4);
opacity: 0.8;
}
70% {
transform: rotate(360deg) scale(.1);
opacity: 0.6;
}
80% {
transform: rotate(240deg) scale(.5);
opacity: 0.5;
}
90% {
transform: rotate(200deg) scale(.9);
opacity: 0.2;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="root">
<img class="main-star" src="https://vignette.wikia.nocookie.net/justdance/images/2/2e/Star.png/revision/latest?cb=20160307193808">
</div>
Начну для затравки.
Конкурс откроется сегодня, - 24.12.2018 г. с хорошим вознаграждением.
Как раз будем подводить итоги накануне Нового года.
Возьмусь, для примера, сделать первый пункт анимации из списка в вопросе. Так как я буду использовать в этой заготовке базовые команды svg и простые, общеизвестные приемы, то можно смело их использовать в конкурсных ответах, это не будет считаться копи-пастом.
Лучи от звезды.
Я делаю в SVG, естественно возможно это реализовать и на CSS
, Javascript
, jQuery
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" viewBox="0 0 400 400">
<defs>
<radialGradient id="radGrad" cx="50%" cy="50%" r="25%"
fx="50%" fy="80%">
<stop offset="10%" style="stop-color:yellow;
stop-opacity:1">
<animate
attributeName="offset"
values="10%;90%;10%"
dur="1.5s"
repeatCount="indefinite"/>
</stop>
<stop offset="90%" style="stop-color:gold;
stop-opacity:1.0"/>
</radialGradient>
<radialGradient id="starGrad" cx="50%" cy="50%" r="65%"
fx="50%" fy="50%">
<stop offset="10%" style="stop-color:yellow;
stop-opacity:1;">
<animate
attributeName="offset"
values="10%;90%;10%"
dur="2.5s"
repeatCount="indefinite"/>
</stop>
<stop offset="90%" style="stop-color:crimson;
stop-opacity:1;"/>
</radialGradient>
</defs>
<rect width="100%" height="100%" fill="#DBFF66"/>
<path transform="translate(100 105)" d="M100,10 L100,10 40,180 190,60 10,60 160,180 z" stroke="gold" stroke-width="4" fill-opacity="0.75" fill="url(#starGrad)" />
<circle cx="200" cy="200" r="150" fill="yellow" fill-opacity="0.25" stroke="url(#radGrad)" stroke-dasharray="13.08 13.08" stroke-width="250" >
<animate
attributeName="stroke-width"
fill="yellow"
fill-opacity="0.15"
values="0;300;0"
dur="8s"
repeatCount="indefinite" />
<!-- <animateTransform
attributeName="transform"
type="rotate"
values="0 200 200;180 200 200"
dur="8s"
repeatCount="indefinite"/> -->
</circle>
</svg>
r="100"
длина окружности равна 2 * 3,14 * 100 = 628px
Нужно получить 12 лучей + 12 промежутков = 24 равные части. Одна
часть равна 26,16px
Подставляем длину черты и интервала в атрибут
<circle stroke-dasharray="26.16 26.16"
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" viewBox="0 0 400 400" >
<circle cx="200" cy="200" r="100"
fill="none"
stroke="yellowgreen"
stroke-dasharray="26.16 26.16"
stroke-width="4" />
</svg>
stroke-width="200"
Так как строка размещается симметрично по обе стороны от осевой линии окружности
и при r="100px"
её ширина должна быть 200px
для заполнения внутреннего пространства окружности.
Для демонстрации окружность заполнена цветом fill="purple"
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" viewBox="0 0 400 400" >
<circle cx="200" cy="200" r="100"
fill="purple"
stroke="yellowgreen"
stroke-dasharray="26.16 26.16"
stroke-width="200" />
</svg>
Прототип снежинки
Убираем заливку fill="none"
и присваиваем stroke="#87CEFA"
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" viewBox="0 0 400 400">
<circle cx="200" cy="200" r="100"
fill="none"
stroke="#87CEFA"
stroke-dasharray="26.16 26.16"
stroke-width="200" />
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" viewBox="0 0 400 400" >
<path transform="translate(100 105)" d="M100,10 L100,10 40,180 190,60 10,60 160,180 z" stroke="gold" stroke-width="4" fill-opacity="0.75" fill="yellow" />
<circle cx="200" cy="200" r="100"
fill="none"
stroke="yellowgreen"
stroke-dasharray="26.16 26.16"
stroke-width="200" />
</svg>
Добавляем градиент лучей звезды и анимацию, к сожалению анимация в
этом варианте работает только в FF
Этот кусок кода закомментирован
<defs>
<radialGradient id="radGrad" cx="50%" cy="50%" r="150%"
fx="50%" fy="50%">
<stop offset="10%" style="stop-color:#D3B300; stop-opacity:1">
<!-- <animate
attributeName="offset"
values="1%;90%;1%"
dur="2.5s"
repeatCount="indefinite"/> -->
</stop>
<stop offset="90%" style="stop-color:yellow; stop-opacity:1.0"/>
</radialGradient>
</defs>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" viewBox="0 0 400 400" >
<defs>
<radialGradient id="radGrad" cx="50%" cy="50%" r="150%"
fx="50%" fy="50%">
<stop offset="10%" style="stop-color:#D3B300;
stop-opacity:1">
<!-- <animate
attributeName="offset"
values="1%;90%;1%"
dur="2.5s"
repeatCount="indefinite"/> -->
</stop>
<stop offset="90%" style="stop-color:yellow;
stop-opacity:1.0"/>
</radialGradient>
</defs>
<path transform="translate(100 105)" d="M100,10 L100,10 40,180 190,60 10,60 160,180 z" stroke="gold" stroke-width="4" fill-opacity="0.5" fill="yellow" />
<circle cx="200" cy="200" r="100"
fill="none"
stroke="url(#radGrad)"
stroke-dasharray="26.16 26.16"
stroke-width="200" />
</svg>
Анимация вращения лучей звезды
Для вращения объекта по часовой стрелке на один полный оборот необходимо добавить внутри его тегов команду анимации:
<animateTransform
attributeName="transform"
type="rotate"
values="0 200 200;360 200 200"
dur="2s"
repeatCount="indefinite" />
Немного сложна семантика тегов объекта при использовании вложенной анимации.
Внести ясность поможет топик: Эти странные теги SVG
Ниже код анимации вращения лучей звезды
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" viewBox="0 0 400 400" >
<defs>
<radialGradient id="radGrad" cx="50%" cy="50%" r="150%"
fx="50%" fy="50%">
<stop offset="10%" style="stop-color:gold;
stop-opacity:1">
<!-- <animate
attributeName="offset"
values="1%;90%;1%"
dur="2.5s"
repeatCount="indefinite"/> -->
</stop>
<stop offset="90%" style="stop-color:yellow;
stop-opacity:1.0"/>
</radialGradient>
</defs>
<path transform="translate(100 105)" d="M100,10 L100,10 40,180 190,60 10,60 160,180 z" stroke="gold" stroke-width="4" fill-opacity="0.5" fill="dodgerblue" />
<circle cx="200" cy="200" r="100"
fill="none"
stroke="url(#radGrad)"
stroke-dasharray="26.16 26.16"
stroke-width="200" >
<animateTransform
attributeName="transform"
type="rotate"
values="0 200 200;360 200 200"
dur="2s"
repeatCount="indefinite" />
</circle>
</svg>
Усложняем алгоритм вращения
values="0 200 200;720 200 200;720 200 200;0 200 200;0 200 200"
Поворот по часовой стрелке на 720 ° → пауза → поворот против часовой стрелки на 720 ° → пауза
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" viewBox="0 0 400 400" style="border:1px solid red;" >
<defs>
<radialGradient id="radGrad" cx="50%" cy="50%" r="150%"
fx="50%" fy="50%">
<stop offset="10%" style="stop-color:gold;
stop-opacity:1">
<!-- <animate
attributeName="offset"
values="1%;90%;1%"
dur="2.5s"
repeatCount="indefinite"/> -->
</stop>
<stop offset="90%" style="stop-color:yellow;
stop-opacity:1.0"/>
</radialGradient>
</defs>
<path transform="translate(100 105)" d="M100,10 L100,10 40,180 190,60 10,60 160,180 z" stroke="gold" stroke-width="4" fill-opacity="0.5" fill="dodgerblue" />
<circle cx="200" cy="200" r="100"
fill="none"
stroke="url(#radGrad)"
stroke-dasharray="26.16 26.16"
stroke-width="200" >
<animateTransform
attributeName="transform"
type="rotate"
values="0 200 200;720 200 200;720 200 200;0 200 200;0 200 200"
dur="8s"
repeatCount="indefinite" />
</circle>
</svg>
Подбирая углы, их порядок следования, а также изменяя время вращения
dur="3.43s"
, можно получить интересные эффекты
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" viewBox="0 0 400 400" >
<defs>
<radialGradient id="radGrad" cx="50%" cy="50%" r="150%"
fx="50%" fy="50%">
<stop offset="10%" style="stop-color:gold;
stop-opacity:1">
<!-- <animate
attributeName="offset"
values="1%;90%;1%"
dur="2.5s"
repeatCount="indefinite"/> -->
</stop>
<stop offset="90%" style="stop-color:yellow;
stop-opacity:1.0"/>
</radialGradient>
</defs>
<path transform="translate(100 105)" d="M100,10 L100,10 40,180 190,60 10,60 160,180 z" stroke="gold" stroke-width="4" fill-opacity="1" fill="dodgerblue" />
<circle cx="200" cy="200" r="100"
fill="none"
stroke="url(#radGrad)"
stroke-dasharray="26.16 26.16"
stroke-width="200" >
<animateTransform
attributeName="transform"
type="rotate"
values="0 200 200;1440 200 200;720 200 200;0 200 200"
dur="3.43s"
repeatCount="indefinite" />
</svg>
Думаю, можно поменьше js при желании, а так вроде норм, красиво)
Снежинки
let params = {
amount: 30,
duration: {
min: 2,
max: 6
}, //s
size: {
min: 10,
max: 20
}
}
const randomBetween = (a, b) => {
return (a + (Math.random() * (b - a)));
}
const randomArr = (arr) => {
return arr[Math.round(Math.random() * (arr.length - 1))];
}
const snowflakes = [
"http://pngimg.com/uploads/snowflakes/snowflakes_PNG7578.png",
"https://vignette.wikia.nocookie.net/fantendo/images/2/27/Snowflake.png/revision/latest?cb=20121220012520",
"https://latxikadelacerveza.es/wp-content/plugins/christmas-panda/assets/images/snowflake_5.png"
];
$(document).ready(() => {
for (let i = 0; i < params.amount; i++) {
let snowflake = $("<img class='snowflake' src='" + randomArr(snowflakes) + "'>");
let randomSize = randomBetween(params.size.min, params.size.max);
snowflake.css({
"width": randomSize + "px",
"height": randomSize + "px",
"left": randomBetween(0, 100) + "%",
"animation-duration": randomBetween(params.duration.min, params.duration.max) + "s"
});
$("#root").append(snowflake);
}
});
body,
html {
margin: 0;
width: 100%;
height: 100%;
}
#root {
position: absolute;
width: 100%;
height: 100%;
background: green;
overflow: hidden;
}
.snowflake {
position: absolute;
animation-name: drop;
transform-origin: center center;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
@keyframes drop {
0% {
top: 0%;
opacity: 0;
transform: rotate(0deg);
}
10%,
90% {
opacity: 1;
}
100% {
top: 100%;
opacity: 0;
transform: rotate(360deg);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="root">
</div>
Этот вариант не участвует в конкурсе, создан для примера. Участники могут брать эту технику анимации прорисовки и раскрашивания букв в качестве заготовки и использовать, творчески переработав, в своих конкурсных ответах.
Как сделать анимацию обводки букв - подробно, с картинками рассказывается как это сделать
update Новый вариант
<style>
width:100%;
heighr:100;
</style>
<div class="container">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100%" height="100%" viewBox="0 0 1318 1054" preserveAspectRatio="xMinYMin meet" border="1">
<defs>
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="5" dy="5" stdDeviation="2"/>
</filter>
</defs>
<image height="100%" width="100%" xlink:href="https://i.stack.imgur.com/EgAH7.jpg"/>
<g fill="transparent" stroke-width="3" transform="translate(0 100)" filter="url(#shadow)">
<path id="L1" transform="translate(-280 -110) scale(1.6)" stroke="gold" stroke-dasharray="327" stroke-dashoffset="327" d="m248.8 131.1 2.9-6h2.6l1.1 24.8h-2.8q-2.7-10.5-6.9-15.4-5.2-6.2-12.3-6.2-7.7 0-12.6 6.9-4.9 6.9-4.9 23.4 0 13.9 5.6 21.2 4.8 6.2 13.3 6.2 7.5 0 12.6-4.8 5.1-4.8 6.6-14.5h3q-1.3 11-7.5 16.9-6.2 5.9-15.7 5.9-7.7 0-14.2-3.9-6.4-3.9-10.3-11.1-3.8-7.3-3.8-16 0-9.2 4-17.3 4-8.1 10.2-12.1 6.2-4.1 13.4-4.1 4 0 7.8 1.4 3.8 1.4 8.2 4.7zM288.6 126.3">
<animate id="an_L1" attributeName="stroke-dashoffset" dur="0.8s" values="327;0" fill="freeze" />
<animate id="fill_L1" attributeName="fill" begin="an_L16.end" dur="0.4s" values="transparent;yellow" fill="freeze" />
</path>
<path id="L2" transform="translate(-290 -110) scale(1.6)" stroke="crimson" stroke-dasharray="458" stroke-dashoffset="458" d="m288.6 126.3h26.3v3.1h-4.8q-2.5 0-3.3 0.9-0.7 0.9-0.7 4.3v19h28.2v-19q0-3.6-0.7-4.4-0.7-0.8-3.4-0.8h-4.5v-3.1h26.2v3.1h-4.8q-1.8 0-2.5 0.5-0.7 0.5-1.2 1.6-0.2 0.7-0.2 3.7v44.3q0 3.2 0.5 3.9 1.1 1.4 4 1.4h4.3v3.1h-26.2v-3.1h4.5q2.7 0 3.6-1.5 0.5-0.8 0.5-4.2v-21.4h-28.2v21.8q0 3.3 0.5 3.9 1 1.4 3.6 1.4h4.8v3.1h-26.3v-3.1h5q1.3 0 2.1-0.5 0.8-0.5 1.2-1.5 0.2-0.7 0.2-3.5v-44.5q0-3.5-0.8-4.3-0.7-0.9-3.3-0.9h-4.4z">
<animate id="an_L2" attributeName="stroke-dashoffset" begin="an_L1.end" dur="0.8s" values="458;0" fill="freeze" />
<animate id="fill_L2" attributeName="fill" begin="fill_L1.end" dur="0.3s" values="transparent;red" fill="freeze" />
</path>
<g id="new" transform="translate(-75)">
<path id="L3" stroke="yellowgreen" stroke-dasharray="346" stroke-dashoffset="346" d="m388.4 125q7.8 0 14.6 4.1 6.8 4.1 10.7 11.5 3.9 7.3 3.9 16.5 0 9.2-3.9 16.6-3.9 7.4-10.7 11.6-6.7 4.1-14.3 4.1-7.4 0-13.9-4-6.5-4.1-10.5-11.6-3.9-7.6-3.9-16.8 0-9.1 3.8-16.4 3.8-7.3 10.5-11.5 6.6-4.2 13.8-4.2zm0.7 3.2q-8.1 0-13.2 6.8-5 6.8-5 22 0 16.5 5.2 22.9 5.2 6.3 12.8 6.3 5.3 0 9.4-2.9 4-2.9 6.4-9.1 2.4-6.2 2.4-16.4 0-11.1-2.2-17.3-2.2-6.2-6.4-9.2-4.2-3-9.3-3z">
<animate id="an_L3" attributeName="stroke-dashoffset" begin="an_L2.end" dur="0.5s" values="346;0" fill="freeze" />
<animate id="fill_L3" attributeName="fill" begin="fill_L2.end" dur="0.4s" values="transparent;greenyellow" fill="freeze" />
</path>
<path id="L4" stroke="#00C4FF" stroke-dasharray="430" stroke-dashoffset="430" d="m426.1 126.3h32.1q9.5 0 14.5 4.2 5 4.2 5 10.5 0 5.3-3.5 8.9-3.5 3.7-10.5 5.8 8.7 1.8 13 5.8 4.4 3.9 4.4 9.9 0 4.6-2.5 8.1-2.5 3.5-8.2 6-5.7 2.5-13.1 2.5h-31.2v-3.1h5.1q2.3 0 3.3-0.7 1.1-0.7 1.1-1.7v-49.4q0-1.7-1-2.6-1-0.9-3-0.9h-5.4zm18.4 28.3h11.7q5.4 0 8.5-3.2 3.2-3.2 3.2-10.4 0-4.5-1.5-7-1.5-2.5-4.4-3.6-2.9-1.2-10-1.2-5 0-6.2 0.8-1.2 0.7-1.2 2.5zm0 3.1v23.8q0 1.7 1 2.5 1 0.8 3.5 0.8h7.5q7.4 0 11-3.2 3.5-3.3 3.5-10.2 0-6.3-3.7-10-3.7-3.7-10.1-3.7z">
<animate id="an_L4" attributeName="stroke-dashoffset" begin="an_L3.end" dur="0.5s" values="430;0" fill="freeze" />
<animate id="fill_L4" attributeName="fill" begin="fill_L3.end" dur="0.4s" values="transparent;cyan" fill="freeze" />
</path>
<path id="L5" stroke="#ED00FF" stroke-dasharray="557" stroke-dashoffset="557" d="m487.8 187.9v-3.1h3.4q2.7 0 3.7-0.5 1-0.6 1.2-1.4 0.3-0.8 0.3-3.3v-46.1q0-2.4-0.7-3.2-0.7-0.8-2.8-0.8h-5v-3.1h28.4v3.1h-7q-2.4 0-3.2 1.1-0.7 1.1-0.7 3.5v19.1h12.5q10.4 0 16.3 4.6 5.9 4.5 5.9 13 0 7.6-5.3 12.4-5.3 4.8-15.9 4.8zm17.4-31.6v23.9q0 2.5 0.9 3.6 0.9 1 3.7 1h5.3q9.5 0 12.4-3.6 2.9-3.6 2.9-10.5 0-7.5-3.6-10.9-3.5-3.5-11.5-3.5zm35.6-30h28.4v3.1h-4.9q-3.2 0-4.1 0.8-0.8 0.8-0.8 3.4v46.7q0 2.8 0.8 3.5 1 1 3.6 1h5.5v3.1h-28.4v-3.1h5.4q2.8 0 3.7-0.8 0.8-0.8 0.8-3.6v-46.7q0-2.7-0.7-3.3-1.2-1-4.3-1h-4.8z">
<animate id="an_L5" attributeName="stroke-dashoffset" begin="an_L4.end" dur="0.5s" values="557;0" fill="freeze" />
<animate id="fill_L5" attributeName="fill" begin="fill_L4.end" dur="0.4s" values="transparent;magenta" fill="freeze" />
</path>
<path id="L6" stroke="yellow" stroke-dasharray="810" stroke-dashoffset="810" d="m573.3 126.3h20.5l18.4 48.7 17-48.7h21v3.1h-5.1q-2.7 0-3.7 0.8-0.9 0.8-0.9 2.8v48.8q0 1.5 1.1 2.3 1.1 0.8 3.9 0.8h4.7v3.1h-28.2v-3.1h5.3q2.3 0 3.3-0.8 1.1-0.9 1.1-2.2v-52.3l-20.4 58.5h-2.8l-21.9-58.3v44.8q0 4 1 6 1 2 2.8 3 1.9 1 6.2 1.3v3.1h-23.2v-3.1q5.7-0.4 7.8-2.5 2-2.1 2-7.4v-42.5q0-1.6-1-2.3-1-0.7-3.6-0.7h-5.2z">
<animate id="an_L6" attributeName="stroke-dashoffset" begin="an_L5.end" dur="0.5s" values="810;0" fill="freeze" />
<animate id="fill_L6" attributeName="fill" begin="fill_L5.end" dur="0.4s" values="transparent;gold" fill="freeze" />
</path>
<path id="L7" transform="translate(-420 -110) scale(1.6)" stroke="crimson" stroke-dasharray="810" stroke-dashoffset="810" d="m689.5 178.8q-1.9 2.5 18.9 2.5 3.1 0 4.5-1.6 1.3-1.6 3-9h2.8l-1.3 17.3h-37.3v-2.2l12.1-13.8q10.1-11 12.2-13.8 2.9-4 4.3-7.8 1.3-3.8 1.3-6.9 0-5.1-2.8-8-2.8-3-7.9-3-5.7 0-9.2 2.7-3.6 2.7-3.6 5.8 0 1 0.5 1.6 0.5 0.5 2.2 1 4.2 1 4.2 4.9 0 2.1-1.4 3.5-1.4 1.4-3.6 1.4-2.5 0-4.5-2.3-1.9-2.4-1.9-6.2 0-4.2 2.2-7.7 2.2-3.5 6.6-5.7 4.4-2.3 9.5-2.3 5 0 9.3 2.2 4.3 2.2 6.5 5.7 2.2 3.5 2.2 7.7 0 2.9-1.1 5.8-1.1 3-3.2 5.5-3.6 4.5-7.4 7.6l-11 9.3q-4.2 3.5-6.1 6z">
<animate id="an_L7" attributeName="stroke-dashoffset" begin="an_L6.end" dur="0.5s" values="810;0" fill="freeze" />
<animate id="fill_L7" attributeName="fill" begin="fill_L6.end" dur="0.4s" values="transparent;red" fill="freeze" />
</path>
<path id="L8" transform="translate(-420 -110) scale(1.6)" stroke="crimson" stroke-dasharray="292" stroke-dashoffset="292" d="m747.4 129.1q8.1 0 13.5 6.3 6.7 7.8 6.7 23.6 0 14.7-5.8 22.4-5.8 7.7-14.1 7.7-8 0-13.3-6.5-6.7-8.1-6.7-23.5 0-14.6 6.3-23.2 5-6.9 13.3-6.9zm0.3 3q-5.5 0-8.6 5.3-3.1 5.3-3.1 21.8 0 16.2 3.2 21.6 3.2 5.4 8.6 5.4 5.4 0 8.3-5 3.5-6 3.5-21.7 0-16.3-3.2-21.9-3.2-5.5-8.6-5.5z">
<animate id="an_L8" attributeName="stroke-dashoffset" begin="an_L7.end" dur="0.5s" values="292;0" fill="freeze" />
<animate id="fill_L8" attributeName="fill" begin="fill_L7.end" dur="0.4s" values="transparent;red" fill="freeze" />
</path>
<path id="L9" transform="translate(-420 -110) scale(1.6)" stroke="crimson" stroke-dasharray="192" stroke-dashoffset="192" d="m800.1 130.1v52q0 1.2 0.8 1.8 1.2 0.9 3 0.9h8.1v3.1h-30v-3.1h6.9q2.2 0 3.2-1 1-1 1-2.7v-39.3q0-1.2-1-2-1-0.8-2.5-0.8h-9.2v-2.9q6.5-0.8 10.5-2.2 4-1.4 7.1-3.7z">
<animate id="an_L9" attributeName="stroke-dashoffset" begin="an_L8.end" dur="0.5s" values="192;0" fill="freeze" />
<animate id="fill_L9" attributeName="fill" begin="fill_L8.end" dur="0.4s" values="transparent;red" fill="freeze" />
</path>
<path id="L10" transform="translate(-420 -110) scale(1.6)" stroke="crimson" stroke-dasharray="325" stroke-dashoffset="325" d="m854.4 158q-2.7 4.1-6.3 6.2-3.6 2-8.1 2-6.2 0-11.4-4.4-5.1-4.4-5.1-12.9 0-8.3 5.6-14.1 5.7-5.8 13.5-5.8 8.6 0 14.4 7.2 5.8 7.2 5.8 20.1 0 10.8-3.2 18.2-3.2 7.4-8.4 11-5.2 3.6-11.8 3.6-6.4 0-10-2.8-3.6-2.8-3.6-6.7 0-2.6 1.5-4.2 1.5-1.6 3.8-1.6 2 0 3.5 1.4 1.4 1.4 1.4 3.3 0 1.4-1.3 3-0.8 1-0.8 1.8 0 1.2 1.4 2 1.4 0.8 4.4 0.8 4.3 0 7.6-2.4 3.3-2.4 5.3-7.9 2-5.5 2-14.2zm-11.7-26q-4.7 0-7.7 3.9-3 3.9-3 11.7 0 7.2 3 10.7 3 3.5 7.8 3.5 4.8 0 8-3.8 3.3-3.8 3.3-10.6 0-7.1-3.4-11.2-3.4-4.2-8.1-4.2z">
<animate id="an_L10" attributeName="stroke-dashoffset" begin="an_L9.end" dur="0.5s" values="325;0" fill="freeze" />
<animate id="fill_L10" attributeName="fill" begin="fill_L9.end" dur="0.4s" values="transparent;red" fill="freeze" />
</path>
<path id="L11" transform="translate(90 0) " stroke="yellowgreen" stroke-dasharray="279" stroke-dashoffset="279" d="m893.8 126.3h47.6l0.8 21.2h-2.9q-2-11.8-6.1-15-4.2-3.1-10.5-3.1h-8.7q-2.7 0-2.7 2.8v48.8q0 2.2 1 3 1 0.8 3.4 0.8h6.4v3.1h-28.2v-3.1h5q3.5 0 3.5-3.3v-49q0-3.1-3.8-3.1h-4.7z">
<animate id="an_L11" attributeName="stroke-dashoffset" begin="an_L10.end" dur="0.5s" values="279;0" fill="freeze" />
<animate id="fill_L11" attributeName="fill" begin="fill_L10.end" dur="0.4s" values="transparent;greenyellow" fill="freeze" />
</path>
<path id="L12" transform="translate(90 0)" stroke="#00C4FF" stroke-dasharray="346" stroke-dashoffset="346" d="m975.4 125q7.8 0 14.6 4.1 6.8 4.1 10.7 11.5 3.9 7.3 3.9 16.5 0 9.2-3.9 16.6-3.9 7.4-10.7 11.6-6.7 4.1-14.3 4.1-7.4 0-13.9-4-6.5-4.1-10.5-11.6-3.9-7.6-3.9-16.8 0-9.1 3.8-16.4 3.8-7.3 10.5-11.5 6.6-4.2 13.8-4.2zm0.7 3.2q-8.1 0-13.2 6.8-5 6.8-5 22 0 16.5 5.2 22.9 5.2 6.3 12.8 6.3 5.3 0 9.4-2.9 4-2.9 6.4-9.1 2.4-6.2 2.4-16.4 0-11.1-2.2-17.3-2.2-6.2-6.4-9.2-4.2-3-9.3-3z">
<animate id="an_L12" attributeName="stroke-dashoffset" begin="an_L11.end" dur="0.5s" values="346;0" fill="freeze" />
<animate id="fill_L12" attributeName="fill" begin="fill_L11.end" dur="0.4s" values="transparent;cyan" fill="freeze" />
</path>
<path id="L13" transform="translate(90 0) " stroke="#ED00FF" stroke-dasharray="485" stroke-dashoffset="485" d="m1072.8 184.8v18.5h-3.1q-0.4-4.7-1.7-8.2-1.4-3.4-6-5.3-4.5-1.9-9.2-1.9h-24.5q-6.9 0-11.4 3.1-4.5 3.2-4.7 12h-3.1l0.6-18.6q5.3-0.2 8.4-1.9 3.1-1.7 6.4-7.8 3.3-6.1 4.5-14.4 1.2-8.3 1.2-19.3 0-6.7-2-9.3-2-2.6-6-2.6h-0.9v-2.8h51.4v3.1h-4.6q-2.4 0-3.2 1-0.8 1-0.8 4.8v44.3q0 5.3 4.9 5.3zm-17.3-0.3v-55.1h-10.6q-5.1 0-7.1 1.5-2 1.4-2.5 4.2-0.5 2.7-0.9 11.5-0.7 18.2-5 27-4.2 8.8-9.9 11z">
<animate id="an_L13" attributeName="stroke-dashoffset" begin="an_L12.end" dur="0.5s" values="485;0" fill="freeze" />
<animate id="fill_L13" attributeName="fill" begin="fill_L12.end" dur="0.4s" values="transparent;magenta" fill="freeze" />
</path>
<path id="L14" transform="translate(90 0) " stroke="yellow" stroke-dasharray="348" stroke-dashoffset="348" d="m1109.4 125q7.8 0 14.6 4.1 6.8 4.1 10.7 11.5 3.9 7.3 3.9 16.5 0 9.2-3.9 16.6-3.9 7.4-10.7 11.6-6.7 4.1-14.3 4.1-7.4 0-13.9-4-6.5-4.1-10.5-11.6-3.9-7.6-3.9-16.8 0-9.1 3.8-16.4 3.8-7.3 10.5-11.5 6.6-4.2 13.8-4.2zm0.7 3.2q-8.1 0-13.2 6.8-5 6.8-5 22 0 16.5 5.2 22.9 5.2 6.3 12.8 6.3 5.3 0 9.4-2.9 4-2.9 6.4-9.1 2.4-6.2 2.4-16.4 0-11.1-2.2-17.3-2.2-6.2-6.4-9.2-4.2-3-9.3-3z">
<animate id="an_L14" attributeName="stroke-dashoffset" begin="an_L13.end" dur="0.5s" values="348;0" fill="freeze" />
<animate id="fill_L14" attributeName="fill" begin="fill_L13.end" dur="0.4s" values="transparent;gold" fill="freeze" />
</path>
<path id="L15" transform="translate(90 0) " stroke="yellowgreen" stroke-dasharray="610" stroke-dashoffset="610" d="m1144.5 126.3h20.5l18.4 48.7 17-48.7h21v3.1h-5.1q-2.7 0-3.7 0.8-0.9 0.8-0.9 2.8v48.8q0 1.5 1.1 2.3 1.1 0.8 3.9 0.8h4.7v3.1h-28.2v-3.1h5.3q2.3 0 3.3-0.8 1.1-0.9 1.1-2.2v-52.3l-20.4 58.5h-2.8l-21.9-58.3v44.8q0 4 1 6 1 2 2.8 3 1.9 1 6.2 1.3v3.1h-23.2v-3.1q5.7-0.4 7.8-2.5 2-2.1 2-7.4v-42.5q0-1.6-1-2.3-1-0.7-3.6-0.7h-5.2z">
<animate id="an_L15" attributeName="stroke-dashoffset" begin="an_L14.end" dur="0.5s" values="610;0" fill="freeze" />
<animate id="fill_L15" attributeName="fill" begin="fill_L14.end" dur="0.4s" values="transparent;greenyellow" fill="freeze" />
</path>
<path id="L16" transform="translate(-510 -93) scale(1.5)" stroke="red" stroke-dasharray="131" stroke-dashoffset="131" d="m1237.5 169.9h-2.2q0-7.5-0.4-11.2-0.6-6.1-2.1-14.5-1.6-9.3-1.6-12.2 0-3.6 1.5-5.4 1.5-1.8 3.8-1.8 2.5 0 3.9 1.8 1.4 1.7 1.4 5.4 0 3.1-1.7 12.3-1.5 8.1-2 13.4-0.5 5.3-0.6 12.2zm-1 9.1q2.1 0 3.6 1.5 1.5 1.5 1.5 3.6 0 2-1.5 3.5-1.5 1.5-3.6 1.5-2.1 0-3.6-1.5-1.5-1.5-1.5-3.6 0-2.2 1.5-3.6 1.5-1.5 3.6-1.5z">
<animate id="an_L16" attributeName="stroke-dashoffset" begin="an_L15.end" dur="0.5s" values="131;0" fill="freeze" />
<animate id="fill_L16" attributeName="fill" begin="fill_L5.end" dur="0.4s" values="transparent;crimson" fill="freeze" />
</path>
</g>
</g>
</svg>
</div>
Подробно теория и примеры, как это сделать здесь
svg {
background-image: url(https://i.stack.imgur.com/ZNCaY.jpg);
background-size:cover;
width:50%
height:50%
}
</style>
<svg viewBox="0 0 650 500">
<defs>
<path id="Lsvg" d="M100 200Q200,200 300,200 T500,200" style="stroke:teal;fill-opacity:0.3;stroke-width:3;fill:none;filter:url(#shadow);">
<animate begin="0.5s"
dur="10s"
repeatCount="indefinite"
restart="whenNotActive"
attributeName="d"
values="M100 200Q200,200 300,200 T500,200;
M100 200Q200,100 300,200 T500,200;
M100 200Q200,200 300,200 T500,200;
M100 200Q200,300 300,200 T500,200;
M100 200Q200,200 300,200 T500,200"/>
</path>
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="4" dy="4" stdDeviation="2"/>
</filter>
</defs>
<text text-anchor="middle" font-size="36" fill="crimson" filter="url(#shadow)">
<textPath id="result" method="align" spacing="auto" startOffset="50%" xlink:href="#Lsvg"><tspan dy="-20">С Новым 2019 годом!</tspan></textPath>
<animate
begin="0s"
dur="10s"
repeatCount="indefinite"
attributeName="fill"
values="purple;yellowgreen;yellow;red;cyan;purple"/>
</text>
<use xlink:href="#Lsvg" transform="translate(0 -10)"/>
<rect id="animLink" x="100" y="150" width="400" height="60" fill="#E0E0E0" fill-opacity="0.01" stroke="none" />
</svg>
svg {
background-image: url(https://i.stack.imgur.com/3ENnq.jpg);
background-size:cover;
width:50%
height:50%
}
<svg viewBox="0 0 650 500">
<defs>
<path transform="translate(-30 100)" id="Lsvg" d="M100 200Q200,200 300,200 T500,200" style="fill:none; stroke:cyan;stroke-opacity:0.4;stroke-width:5;filter:url(#shadow);">
<!-- Анимация кривой линии (кривой Безье) -->
<animate begin="0.5s"
dur="10s"
repeatCount="indefinite"
restart="whenNotActive"
attributeName="d"
values="M100 200Q200,200 300,200 T500,200;
M100 200Q200,100 300,200 T500,200;
M100 200Q200,200 300,200 T500,200;
M100 200Q200,300 300,200 T500,200;
M100 200Q200,200 300,200 T500,200"/>
<!-- Анимация изменения цвета строки-->
<animate
begin="0s"
dur="14s"
repeatCount="indefinite"
attributeName="stroke"
values="purple;yellowgreen;yellow;#D05589;#D05589;cyan;purple"/>
</path>
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="4" dy="4" stdDeviation="2"/>
</filter>
</defs>
<text text-anchor="middle" font-size="42" fill="purple" filter="url(#shadow)" >
<textPath id="result" method="align" spacing="auto" startOffset="-48%" xlink:href="#Lsvg"><tspan dx="0" dy="-20">С Новым 2019 годом!</tspan>
<!-- Движение фразы вдоль кривой линии -->
<animate
dur="15s"
repeatCount="indefinite"
attributeName="startOffset"
values="150%;50%;50%;50%;50%;50%;50%;50%;-50%"/>
</textPath>
<!-- Анимация изменения цвета -->
<animate
begin="0s"
dur="14s"
repeatCount="indefinite"
attributeName="fill"
values="purple;yellowgreen;yellow;#D05589;#D05589;cyan;purple"/>
</text>
<use xlink:href="#Lsvg" transform="translate(0 -10)"/>
<rect id="animLink" x="100" y="150" width="400" height="60" fill="#E0E0E0" fill-opacity="0.01" stroke="none" />
</svg>
Это внеконкурсный ответ
Только HTML и CSS.
* {
margin: 0;
box-sizing: border-box;
padding: 0;
}
body {
background-color: rgb(25, 25, 105);
}
.wrap_hy {
margin: 0 auto;
width: 615px;
height: 615px;
overflow: hidden;
}
.yolka {
--size: 160px;
position: relative;
width: calc(var(--size) * 2.647);
height: calc(var(--size) * 1);
font-size: 0;
}
.zvezda {
width: 0;
height: 0;
margin: 0% 50%;
color: #fc2e5a;
position: relative;
display: block;
border-right: 100px solid transparent;
border-bottom: 70px solid #fc2e5a;
border-left: 100px solid transparent;
transform: translate(-51%, 15%) scale(-0.4, 0.4) rotate(35deg);
}
.zvezda:before {
content: "";
height: 0;
width: 0;
position: absolute;
display: block;
top: -45px;
left: -65px;
border-bottom: 80px solid #fc2e5a;
border-left: 30px solid transparent;
border-right: 30px solid transparent;
transform: rotate(-35deg);
}
.zvezda:after {
content: "";
width: 0;
height: 0;
position: absolute;
display: block;
top: 3px;
left: -105px;
color: #fc2e5a;
border-right: 100px solid transparent;
border-bottom: 70px solid;
border-left: 100px solid transparent;
transform: rotate(-70deg);
}
ul {
--luchi-flash: 0.3;
position: absolute;
z-index: -10;
left: 50%;
top: 28%;
padding: 0;
width: 0;
height: 0;
list-style: none;
animation: luchi_rotate 10s infinite linear;
}
li,
li:before,
li:after {
position: absolute;
width: 0;
height: 0;
font-size: 40px;
border: 0 solid transparent;
border-width: 1.2em 20em;
border-color: transparent rgba(255, 193, 7, var(--luchi-flash));
animation: luchi_flash 4s infinite 0s ease;
}
li {
left: -20em;
top: 50%;
margin-top: -1.2em;
transform: rotate(0.1deg);
}
li:before,
li:after {
content: "";
left: -20em;
top: -1.2em;
display: block;
}
li:before {
transform: rotate(60deg);
}
li:after {
transform: rotate(-60deg);
}
li:nth-child(2) {
transform: rotate(15deg);
}
li:nth-child(2),
li:nth-child(2):before,
li:nth-child(2):after {
border-color: transparent rgba(244, 94, 4, var(--luchi-flash));
animation: luchi_flash 4s infinite 1s ease;
}
li:nth-child(3) {
transform: rotate(30deg);
}
li:nth-child(3),
li:nth-child(3):before,
li:nth-child(3):after {
border-color: transparent rgba(147, 251, 25, var(--luchi-flash));
animation: luchi_flash 4s infinite 2s ease;
}
li:nth-child(4) {
transform: rotate(45deg);
}
li:nth-child(4),
li:nth-child(4):before,
li:nth-child(4):after {
border-color: transparent rgba(156, 39, 176, var(--luchi-flash));
animation: luchi_flash 4s infinite 2s ease;
}
@keyframes luchi_rotate {
100% {
transform: rotate(360deg);
}
}
@keyframes luchi_flash {
0%,
100% {
--luchi-flash: 0.2;
}
50% {
--luchi-flash: 0.5;
}
}
.yarus {
position: absolute;
left: 50%;
transform: translate(-50%, 0%);
height: 40%;
width: 30%;
}
.yarus:nth-child(2) {
z-index: -1;
left: 50%;
transform: translate(-50%, 40%);
height: 70%;
width: 50%;
}
.yarus:nth-child(3) {
z-index: -2;
left: 50%;
transform: translate(-50%, 80%);
height: 100%;
width: 80%;
}
.yarus:nth-child(4) {
z-index: -3;
left: 50%;
transform: translate(-50%, 160%);
height: 100%;
width: 100%;
}
.yarus div {
display: inline-block;
height: 100%;
width: 50%;
border-radius: 0 0 0% 100% / 0 0 0% 66%;
background-image: radial-gradient( circle closest-corner at 34% -68%, transparent 117%, #fbfbfb 122%, #808080 140%, #015001 141%);
box-shadow: inset 0 calc(var(--size) * -0.3) calc(var(--size) * 0.2) calc(var(--size) * -0.15) rgba(0, 0, 0, 0.5);
}
.yarus div:nth-child(2) {
transform: scaleX(-1);
}
.stvol {
position: absolute;
z-index: -5;
left: 50%;
transform: translate(-50%, 330%) perspective(200px) rotateX(45deg);
height: 70%;
width: 15%;
border-radius: 15%;
background: #795548;
box-shadow: inset 0 calc(var(--size) * -0.1) calc(var(--size) * 0.3) calc(var(--size) * -0.1) white, inset 0 calc(var(--size) * 0.34) calc(var(--size) * 0.4) black;
}
.girlyanda div {
position: absolute;
left: 50%;
transform: translate(-43%, 56%) rotate(19deg);
height: 40%;
width: 40%;
border-radius: 0 0 50% 50% / 0 0 95% 95%;
border: 12px dotted;
border-top: none;
box-shadow: 0px 10px 30px -25px;
animation: girlyanda 2.1s ease-in infinite;
animation-delay: 0s;
}
.girlyanda div:before {
content: "";
position: absolute;
z-index: -1;
height: 100%;
width: 100%;
border-radius: 0 0 50% 50% / 0 0 95% 95%;
border: 2px solid #444;
border-top: none;
}
.girlyanda div:nth-child(2) {
transform: translate(-42%, 119%) rotate(19deg);
height: 56%;
width: 69%;
animation-delay: 1s;
}
.girlyanda div:nth-child(3) {
transform: translate(-48%, 176%) rotate(23deg);
height: 80%;
width: 84%;
animation-delay: 2s;
}
.girlyanda div:nth-child(4) {
transform: translate(-42%, 125%) rotate(-51deg);
height: 35%;
width: 44%;
animation-delay: 3s;
}
.girlyanda div:nth-child(5) {
transform: translate(-38%, 291%) rotate(-51deg);
height: 35%;
width: 68%;
animation-delay: 4s;
}
.girlyanda div:nth-child(6) {
transform: translate(-54%, 283%) rotate(18deg);
height: 45%;
width: 67%;
animation-delay: 5s;
}
.girlyanda div:nth-child(7) {
transform: translate(-71%, 304%) rotate(-7deg);
height: 59%;
width: 55%;
animation-delay: 6s;
}
@keyframes girlyanda {
0%,
100% {
color: rgb(255, 0, 0);
}
25% {
color: rgba(255, 210, 0, 1);
}
50% {
color: rgb(0, 199, 0);
}
75% {
color: rgb(46, 137, 255);
}
}
.ded_moroz {
position: relative;
}
.shapka {
position: absolute;
left: 50%;
transform: translateX(-50%);
height: 75px;
width: 100px;
border-radius: 100px / 70px;
background-color: rgb(230, 0, 0);
box-shadow: inset -3px 0px 13px -3px black;
}
.shapka:after {
content: "";
position: absolute;
top: 15px;
left: 50%;
transform: translateX(-50%);
height: 75px;
width: 120px;
border-radius: 105px / 53px;
background-color: rgb(230, 230, 230);
box-shadow: inset -3px 0px 13px -3px black;
}
.boroda_lico {
position: absolute;
top: 36px;
left: 50%;
transform: translateX(-50%);
height: 130px;
width: 110px;
border-radius: 55px 55px 60px 60px / 55px 55px 85px 85px;
background-color: rgb(240, 240, 240);
box-shadow: inset -3px 0px 13px -3px black;
}
.boroda_lico:after {
content: "";
position: absolute;
top: -5px;
left: 50%;
transform: translateX(-50%);
height: 80px;
width: 90px;
border-radius: 50px / 50px;
background-color: rgba(255, 214, 195, 1);
box-shadow: inset 0px 0px 13px -3px black;
}
.glaz_l {
position: absolute;
z-index: 1;
top: 20px;
left: 30%;
height: 15px;
width: 13px;
border-radius: 55px 55px 60px 60px / 55px 55px 85px 85px;
background-color: rgb(21, 21, 21);
box-shadow: 0px 0px 5px 0px white;
animation: morganie 5s infinite linear, oglyad_glaza 15s infinite linear;
}
.glaz_r {
position: absolute;
z-index: 1;
top: 20px;
right: 30%;
height: 15px;
width: 13px;
border-radius: 55px 55px 60px 60px / 55px 55px 85px 85px;
background-color: rgb(21, 21, 21);
box-shadow: 0px 0px 5px 0px white;
animation: morganie 5s infinite linear, oglyad_glaza 15s infinite linear;
}
@keyframes morganie {
0%,
10%,
15%,
100% {
height: 15px;
top: 20px;
}
11% {
height: 3px;
top: 25px;
}
}
@keyframes oglyad_glaza {
0%,
10%,
24%,
100% {
transform: translateX(0%);
}
12%,
14% {
transform: translateX(-30%);
}
19%,
21% {
transform: translateX(20%);
}
}
.nos_brovi {
position: absolute;
z-index: 1;
top: 35px;
left: 50%;
transform: translateX(-50%);
height: 26px;
width: 53px;
border-radius: 100px / 50px;
background-color: rgb(255, 168, 168);
box-shadow: inset -3px 0px 13px -3px black, 0px 2px 10px -3px black;
}
.nos_brovi:before {
content: "";
position: absolute;
top: -28px;
left: 15%;
transform: translateX(-50%) rotate(-25deg);
height: 10px;
width: 32px;
border-radius: 0px 80px / 50px 50px;
background-color: rgb(230, 230, 230);
box-shadow: inset 1px -1px 6px -3px black, 0px 2px 10px -3px black;
animation: oglyad_brovi_l 15s infinite linear;
}
.nos_brovi:after {
content: "";
position: absolute;
top: -28px;
right: -45%;
transform: translateX(-50%) rotate(25deg);
height: 10px;
width: 32px;
border-radius: 80px 0px / 50px 50px;
background-color: rgb(230, 230, 230);
box-shadow: inset -1px -1px 6px -3px black, 0px 2px 10px -3px black;
animation: oglyad_brovi_r 15s infinite linear;
}
@keyframes oglyad_brovi_l {
0%,
10%,
19%,
100% {
transform: translateX(-50%) rotate(-25deg);
}
13%,
16% {
transform: translateX(-50%) rotate(0deg);
}
}
@keyframes oglyad_brovi_r {
0%,
17%,
25%,
100% {
transform: translateX(-50%) rotate(25deg);
}
20%,
22% {
transform: translateX(-50%) rotate(0deg);
}
}
.rot_usw {
position: absolute;
z-index: 1;
top: 80px;
left: 50%;
transform: translateX(-50%);
height: 26px;
width: 53px;
}
.rot_usw:before {
content: "";
position: absolute;
top: -28px;
left: -5%;
transform: translateX(-50%) rotate(-40deg);
height: 32px;
width: 50px;
border-radius: 0px 80px / 50px 50px;
background-color: rgb(230, 230, 230);
box-shadow: inset 1px -1px 6px -3px black, 0px 2px 10px -3px black;
}
.rot_usw:after {
content: "";
position: absolute;
top: -28px;
right: -105%;
transform: translateX(-50%) rotate(40deg);
height: 32px;
width: 50px;
border-radius: 80px 0px / 50px 50px;
background-color: rgb(230, 230, 230);
box-shadow: inset -1px -1px 6px -3px black, 0px 2px 10px -3px black;
}
.tulup {
position: absolute;
top: 100px;
left: 50%;
transform: translateX(-50%);
height: 355px;
width: 240px;
border-radius: 40% 40% 10% 10%;
background-color: rgb(230, 0, 0);
box-shadow: inset -13px 0px 73px -3px black;
}
.tulup:before {
content: "";
position: absolute;
bottom: -10px;
left: 50%;
transform: translateX(-50%);
height: 35px;
width: 250px;
border-radius: 20% 20% 40% 40%;
background-color: rgb(230, 230, 230);
box-shadow: inset -23px 0px 53px -15px black;
}
.tulup:after {
content: "";
position: absolute;
z-index: -2;
bottom: -10px;
left: 50%;
transform: translateX(-50%);
height: 350px;
width: 25px;
border-radius: 20% 20% 40% 40%;
background-color: rgb(230, 230, 230);
box-shadow: 1px -10px 16px -5px black;
}
.plecho_l {
position: absolute;
top: 40px;
left: 0px;
height: 140px;
width: 70px;
border-radius: 100% 60% 55px 55px;
background-color: rgb(230, 0, 0);
box-shadow: inset 0px -10px 53px -15px black, 1px 10px 16px -5px black;
}
.plecho_r {
position: absolute;
top: 40px;
right: 0px;
height: 140px;
width: 70px;
border-radius: 60% 100% 55px 55px;
background-color: rgb(230, 0, 0);
box-shadow: inset -15px -10px 53px -15px black, 1px 10px 16px -5px black;
}
.lokot_l {
position: absolute;
bottom: 0px;
left: 0px;
height: 70px;
width: 100px;
border-radius: 100% 60% 55px 55px;
background-color: rgb(230, 0, 0);
box-shadow: inset 0px -10px 53px -15px black, 1px 10px 16px -5px black;
}
.lokot_l:after {
content: "";
position: absolute;
top: 50%;
right: 0px;
transform: translateY(-50%);
height: 80px;
width: 30px;
border-radius: 35%;
background-color: rgb(230, 230, 230);
box-shadow: inset 0px -10px 53px -15px black, 1px 10px 16px -5px black;
}
.lokot_r {
position: absolute;
bottom: 0px;
right: 0px;
height: 70px;
width: 100px;
border-radius: 60% 100% 55px 55px;
background-color: rgb(230, 0, 0);
box-shadow: inset -15px -10px 53px -15px black, 1px 10px 16px -5px black;
}
.lokot_r:after {
content: "";
position: absolute;
top: 50%;
left: 0px;
transform: translateY(-50%);
height: 80px;
width: 30px;
border-radius: 35%;
background-color: rgb(230, 230, 230);
box-shadow: inset 0px -10px 53px -15px black, 1px 10px 16px -5px black;
}
.kist_l {
position: absolute;
z-index: -1;
top: 5px;
right: -30px;
height: 60px;
width: 60px;
border-radius: 100% 60% 55px 55px;
background-color: rgba(255, 214, 195, 1);
box-shadow: inset 0px -10px 53px -15px black, 1px 10px 16px -5px black;
}
.kist_r {
position: absolute;
z-index: -1;
top: 0px;
left: -30px;
height: 60px;
width: 60px;
border-radius: 60% 100% 55px 55px;
background-color: rgba(255, 214, 195, 1);
box-shadow: inset -15px -10px 53px -15px black, 1px 10px 16px -5px black;
}
<div class="wrap_hy">
<div class="yolka">
<div class="zvezda">
<div class="zvezda">
</div>
</div>
<div class="yarus">
<div></div>
<div></div>
</div>
<div class="yarus">
<div></div>
<div></div>
</div>
<div class="yarus">
<div></div>
<div></div>
</div>
<div class="yarus">
<div></div>
<div></div>
</div>
<div class="stvol">
<div></div>
<div></div>
</div>
<div class="girlyanda">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<ul class="luchi">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
<div class="ded_moroz">
<div class="telo">
<div class="tulup">
<div class="plecho_l">
<div class="lokot_l">
<div class="kist_l">
</div>
</div>
</div>
<div class="plecho_r">
<div class="lokot_r">
<div class="kist_r">
</div>
</div>
</div>
</div>
</div>
<div class="golova">
<div class="shapka"></div>
<div class="boroda_lico">
<div class="glaz_l"></div>
<div class="glaz_r"></div>
<div class="rot_usw"></div>
<div class="nos_brovi"></div>
</div>
</div>
</div>
</div>
d3.js
Начну делать елку с звезды. Я сделал лучи заднего плана полностью на линейных градиентах без svg. Звезду позаимстовал у SE и добавил эффект свечения. Получилось вот что-то такое:
html, body {
width: 100%;
height: 100%;
margin: 0;
background-color: lightgreen;
}
#star_back {
position: relative;
width: 100%;
height: 100%;
}
#star_back:after, #star_back:before {
content: '';
position: absolute;
background: linear-gradient(90deg, transparent 50%, black 50%, black), linear-gradient(82deg, transparent 50%, lightgreen 50%, lightgreen), linear-gradient(67deg, transparent 50%, green 50%, green), linear-gradient(52deg, transparent 50%, lightgreen 50%, lightgreen), linear-gradient(37deg, transparent 50%, green 50%, green), linear-gradient(22deg, transparent 50%, lightgreen 50%, lightgreen), linear-gradient(7deg, transparent 50%, green 50%, green), linear-gradient(-8deg, transparent 50%, lightgreen 50%, lightgreen), linear-gradient(-23deg, transparent 50%, green 50%, green), linear-gradient(-38deg, transparent 50%, lightgreen 50%, lightgreen), linear-gradient(-53deg, transparent 50%, green 50%, green), linear-gradient(-68deg, transparent 50%, lightgreen 50%, lightgreen), linear-gradient(-83deg, transparent 50%, green 50%, green), linear-gradient(-90deg, transparent 50%, lightgreen 50%, lightgreen), radial-gradient(transparent 90%, white 10%);
background-position: 0% 0%;
background-size: 200% 100%;
height: 200px;
width: 120px;
border-top-left-radius: 50%;
border-bottom-left-radius: 50%;
}
#star_back:before {
left: 120px;
transform: rotate(180deg);
}
#star_gradient{
background: radial-gradient(transparent, lightgreen);
width: 240px;
height: 220px;
z-index: 1;
position: absolute;
}
#star{
width: 80px;
height: 80px;
margin-left: 80px;
margin-top: 60px;
opacity: 1;
-webkit-filter: drop-shadow( -5px -5px 5px gold );
filter: drop-shadow( 0px 0px 10px gold );
}
<div id="star_back"><div id = "star_gradient"><svg aria-hidden="true" width="18" height="18" viewBox="0 0 18 18" id = "star"><path d="M9 12.65l-5.29 3.63 1.82-6.15L.44 6.22l6.42-.17L9 0l2.14 6.05 6.42.17-5.1 3.9 1.83 6.16z" fill="gold"></path></svg></div></div>
Остальное делать время нет...если будет время до рисую до конца весь мультик как я и задумал
.tree {
fill: url(#pattern);
}
.top-star {
fill: red;
stroke-width: 2;
stroke: yellow
}
.star-tree {
opacity: .8;
paint-order: markers stroke fill;
}
.tree-line {
fill: none;
stroke: #e09a11;
stroke-width: 2px;
stroke-linecap: butt;
stroke-linejoin: miter;
stroke-opacity: 1;
stroke-miterlimit: 4;
stroke-dasharray: 0.26499999, 0.52999997;
stroke-dashoffset: 0
}
.fill-gray {
fill: #ccc;
stroke: none;
opacity: 0.5;
}
.green {
fill: #00ff00;
}
.blue {
fill: #0000ff;
}
.pink {
fill: #ff5555;
}
.red {
fill: #ff0000;
}
</style><style>.tree-wrapper {
width: 300px;
margin: auto;
}
.red,
.r1,
.r2,
.r3,
.r4,
.r5 {
animation: scale 5s linear infinite;
}
.r1 {
animation-delay: -1s;
}
.r2 {
animation-delay: -2s;
}
.r3 {
animation-delay: -3s;
}
.r4 {
animation-delay: -4s;
}
.r5 {
animation-delay: -5s;
}
@keyframes scale {
from {
opacity: 1;
}
20% {
fill: yellow;
}
40% {
fill: orange;
}
60% {
fill: blue;
}
to {
fill: green;
}
}
.op1,
.op2 {
animation: opacity 10s linear infinite;
}
.op1 {
animation-delay: 0.5s;
}
.op2 {
animation-delay: 1s;
}
.op3 {
animation-delay: 1.5s;
}
@keyframes opacity {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.multy {
animation: draw 5s linear infinite;
}
@keyframes draw {
from {
transform: matrix(0.61232376, 0, 0, 0.59080494, 51.47426, 136.56321)
}
to {
transform: matrix(0.61232376, 0, 0, 0.59080494, 501.47426, 136.56321)
}
}
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf8">
</head>
<body>
<div class="tree-wrapper">
<svg version="1.1" viewBox="0 0 236 290" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<pattern id="pattern"
class="pat"
width="250.75568"
height="215.5179"
patternTransform="matrix(.18 0 0 .15 341 .54)"
patternUnits="userSpaceOnUse">
<g transform="matrix(3.8 0 0 3.8 -969 -116)">
<path class="fill-gray op3" d="m280 52 2.3-7.8-5.2-6.3 8.2-.25 4.4-6.9 2.8 7.7 7.9 2.1-6.5 5 .46 8.2-6.8-4.6z"/>
<path class="fill-gray op1" d="m302 82 2.3-7.8-5.2-6.3 8.2-.25 4.4-6.9 2.8 7.7 7.9 2.1-6.5 5 .46 8.2-6.8-4.6z"/>
<ellipse class="fill-gray op2" cx="314" cy="37" rx="5.3" ry="3.7"/>
<ellipse class="fill-gray op1" cx="304" cy="54" rx="5.3" ry="3.7"/>
<ellipse class="fill-gray op2" cx="289" cy="66" rx="5.3" ry="3.7"/>
<path class="fill-gray op1" d="m259 72 2.3-7.8-5.2-6.3 8.2-.25 4.4-6.9 2.8 7.7 7.9 2.1-6.5 5 .46 8.2-6.8-4.6z" />
<ellipse class="fill-gray op3" cx="293" cy="84" rx="5.3" ry="3.7"/>
</g>
</pattern>
</defs>
<g transform="translate(13 -11)">
<g transform="translate(-2.3 -3.8)">
<g>
<path class="tree"
transform="translate(2.3 3.8)"
d="m-13 301c49-89 102-167 117-290 24 133 65 225 119 288-36-5.8-47-17-81-9.2-28 6.5-81 7-101 .67-19-5.7-37 5.5-54 10z"/>
<path class="top-star"
transform="matrix(.58 -.028 .029 .56 179 -45)"
d="m-147 149 6.6-16-14-10 17 1.4 5.4-16 4 17 17 .057-15 9 5.3 16-13-11z"/>
<g transform="translate(326 6)">
<g transform="translate(-241 -34)">
<path class="tree-line" d="m26 89c-3.4 11-8.2 15-14 16" />
<path class="tree-line" d="m26 120c-7.4 13-17 22-28 27" />
<path class="tree-line" d="m40 147c-17 21-35 36-56 41" />
<path class="tree-line" d="m51 177c-29 35-63 53-98 70" />
<path class="tree-line" d="m82 251c-34 31-71 53-109 75"/>
<path class="tree-line" d="m91 272c-19 21-39 41-67 48" />
<path class="tree-line" d="m101 298c-5 3.5-15 12-23 19z" />
<path class="tree-line" d="m113 311c-12 7.6-14 8.3-14 8.3l3-.76" />
</g>
<g transform="matrix(-1 0 0 1 -205 -34)">
<path class="tree-line" d="m26 89c-3.4 11-8.2 15-14 16"/>
<path class="tree-line" d="m26 120c-7.4 13-17 22-28 27"/>
<path class="tree-line" d="m40 147c-17 21-35 36-56 41" />
<path class="tree-line" d="m51 177c-29 35-63 53-98 70" />
<path class="tree-line" d="m82 251c-34 31-71 53-109 75"/>
<path class="tree-line" d="m91 272c-19 21-39 41-67 48" />
<path class="tree-line" d="m101 298c-5 3.5-15 12-23 19z"/>
<path class="tree-line" d="m113 311c-12 7.6-14 8.3-14 8.3l3-.76"/>
</g>
<path class="star-tree green r1"
d="m-239 106 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z"/>
<path class="star-tree pink r2"
d="m-212 124 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z"/>
<path class="star-tree pink r3"
d="m-262 161 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z"/>
<path class="star-tree green r4"
d="m-200 165 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z"/>
<path class="star-tree pink r5"
d="m-183 198 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z"/>
<path class="star-tree red r1"
d="m-157 246 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z"
/>
<path class="star-tree red r2"
d="m-285 215 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z"
/>
<path class="star-tree blue r2"
d="m-298 252 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z"/>
<path class="star-tree pink r3"
d="m-253 235 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z"/>
<path class="star-tree pink r4"
d="m-199 229 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z"
/>
<path class="star-tree red r3"
d="m-266 271 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z"
/>
<path class="star-tree red r4"
d="m-216 259 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z"
/>
<path class="star-tree pink r2"
d="m-137 286 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z" />
<path class="star-tree blue r5"
d="m-194 294 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z"/>
<path class="star-tree pink r3"
d="m-242 287 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z" />
<path class="star-tree red r3"
d="m-305 295 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z"
/>
<path class="star-tree blue r1"
d="m-219 213 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z" />
<path class="star-tree pink r5"
d="m-226 177 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z" />
<path class="star-tree green r1"
d="m-254 196 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z"/>
<path class="star-tree blue r2"
d="m-237 142 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z" />
<path class="star-tree blue r1"
d="m-226 83 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z" />
<path class="star-tree green r3"
d="m-178 272 3.3-8.8-6.8 6.4 5.7-7.4-8.4 4.1 7.7-5.4-9.2 1.4 8.9-2.9-9.3-1.3 9.4-.12-8.5-4 9 2.6-6.9-6.3 7.8 5.2-4.7-8.1 5.9 7.2-2.1-9.1 3.5 8.7.65-9.3.82 9.3 3.4-8.7-2 9.2 5.8-7.3-4.6 8.2 7.7-5.3-6.8 6.5 8.9-2.8-8.4 4.2 9.4-.049-9.2 1.5 9 2.7-9.3-1.3 7.8 5.2-8.5-4 5.9 7.3-6.9-6.3 3.5 8.7-4.8-8 .75 9.3-2.2-9.1-2 9.1.58-9.3z"/>
</g>
</g>
</g>
</g>
<g class="multy" transform="matrix(.71 0 0 .68 196 112)">
<path d="m-281 177 1.4 1.4c.79.78 1.4 1.6 1.4 1.7s-.4.85-.89 1.5c-.8 1-1.1 1.2-3 1.3-1.2.084-2.3.32-2.5.52-.48.48-1 4.3-1 7.2-.011 5.7 1.8 11 5.4 15 2 2.2 2.3 3.1 1.5 3.9-.87.87-1.9.41-4.1-1.8-4-4-6.1-9.7-6.1-17v-3.4l-2 .21c-4.3.45-6 .87-9.8 2.3-3.7 1.5-3.9 1.6-4 2.6-.14 1.5.47 2.6 1.4 2.6.42 0 1.8-.34 3.1-.76 2.9-.94 4-.73 4.7.89.4.96.78 1.2 2 1.6 1.9.48 3.8 1.7 4.4 2.9.6 1.1.35 3.4-.97 8.8-.98 4-1.8 9.6-2.3 16-.26 3.3-.32 3.3 2.7 2.2 3.3-1.1 5-2.2 7.2-4.4 2.8-2.8 4.2-5.7 6.9-13 2.5-7.4 4-11 6.3-13 4.9-6.1 13-7.2 18-2.5 3.7 3.4 4.3 11 1.1 14-3.6 4.3-8.8 3.2-8.8-1.8 0-2.1 1-3 3-2.7l1.5.21-.36-1c-.53-1.5-1.2-1.9-2.8-1.7-2.8.38-4.3 2.1-4.3 4.8.018 2.3 1.2 4.9 4 8.8 1.2 1.6 2.4 3.6 2.7 4.4 2.4 7-1.4 17-7.9 21-1.4.79-1.7 1.2-1.5 1.5.18.28.33 1.1.33 1.8.007 1.7-1.2 2.8-3.3 3.1-1.3.15-1.7.027-2.6-.72-.97-.84-1-.96-.6-2 .35-.92.35-1.2 0-1.4-.71-.45-2.5-.33-3.3.22-.66.49-.63.61 1 4 3.7 7.4 6.8 11 10 12 2.8.89 7.7.92 10 .057 3.2-.97 5.9-3.8 5.9-6.1 0-3.6-4.8-6.3-6.7-3.8-.83 1.1-.82 1.1 1.4 2.3.61.34 1.1.89 1.1 1.3 0 .76-1.4 2.2-2.1 2.2-.72-.002-2.9-1.3-3.6-2.2-1.4-1.7-.25-5.5 2.1-7 2.8-1.7 8.1.86 9.8 4.7.68 1.6.69 3.1.048 5.6-.28 1.1-.46 2-.42 2 .35.35 6.3-4.1 8.7-6.6 7.4-7.5 9.6-16 6-24-.98-2-3.2-4.4-4-4.4-.17 0-.2.94-.065 2.1.51 4.4-.94 7.6-4.2 9.3-2 1-6.8 1.1-8.8.098-1.8-.88-3.5-2.7-4.5-4.7-1.2-2.4-1.1-7.2.035-9.8 1.1-2.4 3.3-4.4 5.7-5.2 3-.99 7.6-.65 11 .77 6.3 3 10 9.3 10 18 .38 8-2.1 15-7.5 20-4.5 4.5-9.3 7.5-16 9.6-7.7 2.6-4.4 2.4-58 2.3-28-.052-50-.24-53-.44-2.4-.19-5.4-.67-6.7-1.1-2-.62-2.7-1.1-4.5-2.9-1.3-1.4-2.6-3.2-3.5-4.9-1.2-2.4-1.4-3.1-1.4-5.3-.012-2.2.12-2.8 1-4.3 1.4-2.2 3.2-3.2 6-3.2 1.6.004 2.4.21 3.5.83 2.2 1.3 3.4 4.5 2.7 7-.79 2.9-3.7 4-6.9 2.6-.93-.41-1.8-.75-1.8-.75-.53 0 2.2 4 3.9 5.8 1.8 1.9 2.4 2.2 4 2.6 1 .22 2.7.4 3.6.4h1.8l-1.3-1.8c-3-4.1-3-8.5.051-11 1.9-1.8 5.5-2.6 6.9-1.6 1.2.88 2.4 3.2 2.4 4.4 0 1.7-1.9 3.6-3.6 3.6-1.2 0-1.7-.34-2.1-1.5-.16-.46.086-.82.92-1.3.63-.38 1.3-.75 1.5-.81.22-.074.19-.47-.081-1.1-.87-1.9-4.3-.97-5.6 1.5-.77 1.5-.64 2.5.5 4.1 1.4 1.9 3.3 3 5.2 3.1 1.4.03 1.7-.13 3.5-1.9 2.4-2.4 4.5-5.4 6.8-10l1.8-3.6-.88-.58c-.55-.36-1.2-.49-1.8-.35-.81.2-.87.34-.67 1.6.18 1.2.096 1.4-.6 1.9-1.3.92-3 .74-4.2-.46-1.2-1.2-1.4-2.8-.29-3.8.74-.67.69-.68-4.9-1.1-3.1-.22-6.6-.66-7.9-.98-7.1-1.8-11-5.8-13-14-.7-2.2-.82-3.4-.81-7.6.009-4.5.088-5.1.97-7.4 1.4-3.5 3.8-7 6.7-9.5 1.8-1.6 2.8-2.8 3.6-4.5 1-2.1 1.1-2.6 1.1-5.6 0-3.9-.73-6.3-2.6-8.5-1.4-1.7-3.1-2.3-5.6-2-4.7.49-7.4 4.3-6.1 8.7.22.79.29.71.73-.83.9-3.2 3-4.8 6.3-4.8 3.5.001 5.5 2 5.5 5.6-.001 5.4-3.7 9.9-8.2 9.9-1.5-.004-4.5-.94-6.1-1.9-3.9-2.3-6.2-6.9-6.2-13-.012-7.6 4.4-14 11-16 .97-.24 1.9-.55 2.1-.69.49-.41-1-3.4-1.9-3.7-.6-.19-.67-.34-.35-.73.33-.39.12-.6-1.1-1.1-1.2-.49-1.4-.67-1-1.1.55-.55 3.9-1.4 6.7-1.7 2-.22 2-.24 1.8-1.2l-.2-.99 3.1-.15c2.2-.1 3.4-.33 4-.75 1.2-.82 3.3-.75 5.2.17l1.6.77-1.8.86c-2 .93-2.2 1.3-1.1 1.6.48.12.71.48.71 1.1 0 .74.34 1.1 1.9 1.8 3 1.5 6.4 3.9 8.1 5.7 3.6 3.9 4.8 9.2 3.8 17l-.38 3.1 1.5 1.8c.83 1 2.9 3.4 4.5 5.3l3 3.5.8-.75c1.3-1.2 3-4.9 3.6-7.9.51-2.5.53-3.6.15-9.6-.24-3.7-.32-7.3-.19-8l.24-1.3h-1.5c-1.3 0-1.7-.21-2.9-1.4-.75-.75-1.4-1.6-1.4-1.9 0-.79 1.1-.72 2.2.13 1.2.93 1.9.89 2.6-.14.52-.79.49-.99-.34-3-.5-1.2-.9-2.4-.9-2.7 0-.38-.36-.54-1.2-.54-.99 0-1.3-.19-1.7-1-.48-.92-.46-1.1.19-1.7.5-.5.68-1.1.6-1.9l-.11-1.2-.96 1.5c-1.1 1.7-4.6 5.2-6 6-.67.4-.98.93-1.1 1.9-.25 1.9-.78 2.4-2.4 2.4-1.2 0-1.6-.24-2.8-1.4-1.2-1.2-1.4-1.6-1.4-2.8 0-1.1.22-1.7.87-2.3 1-1 1.9-1.1 3.4-.31.59.31 1.1.5 1.2.44.062-.063 1.7-3.4 3.6-7.3 1.9-4 4-7.8 4.6-8.5s1.9-1.7 2.9-2.3c1.8-1 2-1 6.7-1 5.8.011 6.7.35 7.9 3.1.44 1 .9 2.1 1 2.4.17.5.4.54 1.5.24 1.5-.43 2.2.051 3.3 2.3.96 2 .9 2.7-.34 4.2-.58.73-.98 1.4-.89 1.6.09.15.65.47 1.2.71.71.3 1 .62.89.96-.73 1.9-.65 2.1.92 2.8 1.9.86 2 .94 4 5.3 1.4 3.1 1.7 4.1 1.9 6.7.14 1.7.37 3.3.51 3.5.41.67 2.5.48 3.5-.32 1.1-.88 1.2-1.8.19-3.2l-.74-1 1.3.61c1.2.55 1.3.73 1.2 1.9-.1 1.2-.063 1.2 1.1 1.3.68.023 1.7.25 2.3.51 1.1.45 1.2.41 2.4-.61 1.9-1.7 3.4-2 6.1-1.5l2.3.42 2-1.6 1.8 3.4zm-22 48c7e-4-1.4.23-5.1.52-8.2.28-3.1.45-5.7.36-5.8-.087-.087-2.5.26-5.4.78-7.9 1.4-11 1.7-13 1.5l-2.4-.2 1.7 1.5c4 3.5 7.6 6.4 10 8.3 3 2 7.3 4.6 7.8 4.6.15.002.27-1.1.27-2.6zm1.5-44c2.8-1.2 3.1-1.5 2.4-3.3-.23-.58-.36-.49-.98.71-.84 1.6-2.5 2.7-4.2 2.7-1.2.034-1.5.24-1 .72.4.4.91.28 3.7-.88z" style="fill:#ff0000;stroke-width:.35"/>
<path d="m-247 164c20-12 45-21 52-22 1.5-.13 2.9-.36 3.2-.52.31-.16.75-.93.98-1.7.24-.79.89-2.5 1.5-3.7l1-2.3-1.3-.55c-2.1-.89-3.2-2.2-3.2-3.8 0-1.5.24-1.6 1.5-.65l.89.7-.17-2.2c-.18-2.3.62-5.3 1.1-4.1.11.29.4 1 .62 1.6l.42 1.1.39-1.9c.46-2.3 1.1-3.5 1.8-3.5.42 0 .48.27.29 1.3l-.25 1.3 1.5-1.2c.8-.64 1.5-1.3 1.7-1.5.11-.18.61-.33 1.1-.33.9 0 .9.005.29.97-.34.53-1.1 1.5-1.8 2.1-.74.74-1.3 1.9-1.7 3.2-.68 2.4-.72 3.4-.2 4.9l.38 1.1 2-.7c4.2-1.4 7.6-2.1 11-2.1 6.9-.005 11 .96 17 3.7 6.2 3 14 5.1 19 5.1 2.6-.006 6.3-.83 8.8-1.9 1.1-.51 3.2-1.1 4.7-1.4 4.6-.82 6-2.6 9.1-11l1.4-3.8-2.4-1.8c-4.7-3.5-6.4-5.9-7.3-10-.13-.63-.35-1.1-.51-1.1-.15 0-2.2.4-4.6.88-4.7.96-6.2 1.1-7.1.51-.44-.3-.19-.66 1.4-2.1 3.5-3.2 6.2-3.8 11-2.7 1.1.28 2 .47 2 .42.32-.32-1.3-2.6-2.2-3.1-.62-.36-4-1.4-7.6-2.2-3.6-.88-7.1-2-7.9-2.4-1.4-.81-4.9-4.3-6-6-.3-.47-2.2-2-4.3-3.4-5.6-3.9-6.5-5-6.9-8.2-.43-3.5 1.2-10 2.2-9.2.15.15.36 2.1.46 4.4.14 2.9.38 4.5.79 5.2.48.89 3 2.9 5.4 4.4.23.14.36-1.5.37-4.8.014-4.1.16-5.5.8-7.8.97-3.4 3-7.6 4.6-9.5 1-1.2 2.9-2.4 3.8-2.4.13 0 .15.87.038 1.9-.14 1.4-.53 2.4-1.3 3.5-1.4 2-2.6 4.8-3.3 7.5-.67 2.6-.7 7.4-.066 9.8.56 2.1 2.1 5.1 2.8 5.8.7.58.7.56-.12-2.1-.37-1.2-.78-2.7-.9-3.3-.32-1.6 1-4.9 2.7-6.7 1.7-1.8 3.4-2.7 10-5.1 2.7-.99 5.8-2.1 6.8-2.5 2.6-.95 3.6-.9 3.6.17 0 1.8-3.6 3.9-9.7 5.7-4.1 1.2-4.7 1.5-6 2.8-2.1 2.1-2.5 4-1.7 8.6.34 1.9.73 3.4.86 3.3.13-.15.59-1.4 1-2.7.43-1.4 1-2.8 1.3-3.3.74-1.1 2.7-2 7.6-3.5 4.1-1.2 4.4-1.4 5.9-3 .89-.97 2.1-1.9 2.7-2.1l1.1-.33v1.5c0 1.5-1.7 4.8-2.5 4.8-.64 0-.38.65.34.88 1.1.34 1.8 1.2 1.8 2.1 0 .76-.11.84-.97.63-.53-.13-1.8-.53-2.7-.89-4.1-1.5-9.6-.21-11 2.7-.44.82-1.7 5.6-1.5 5.7.066.066.97-.86 2-2s2.3-2.4 2.9-2.7c.95-.49 1.1-.48 1.8.22l.75.75-1.6 1.4c-1.8 1.5-3.1 3.9-3.1 5.4 0 1.3 1.3 2.1 5.7 3.4 3.6 1.1 4 1.5 5.4 4l.71 1.3 2.3-.21c1.3-.12 3.2-.45 4.2-.74 2.6-.7 3.7-.67 6.2.17 3 1 4.1.92 7.5-.88 1.7-.87 3.3-1.6 3.7-1.6.94 0 1.4 1.1 1.4 3.6 0 1.2.24 3 .53 4 .29.95.53 2 .53 2.3.004.65-1.3 1.2-3.9 1.5-1.3.18-2.2.63-4.1 2.2-1.3 1.1-2.5 2.1-2.6 2.3-.66 1 2.1 6.5 5 10 4 4.7 4.6 6.2 5.1 11l.22 2.3-1.8-2.8-.011 3.5c-.011 3.4-.53 6.6-1.1 6.6-.15 0-.43-.44-.61-.97-.3-.88-.37-.74-.75 1.4-.23 1.3-.68 3.1-.99 3.8-.54 1.3-.59 1.4-.97.67-.37-.69-.49-.57-1.5 1.5-1.3 2.5-3.2 4.9-4.7 5.7-1.1.59-1.2.49-.46-.93.59-1.1.36-1.3-.69-.51-.59.44-.63.68-.3 1.7.21.67 1.2 2.5 2.2 4.1 2.1 3.2 2.2 3.2 8.3 4.5 4 .83 5.2 1.5 6.2 3.7.48 1 .99 2.3 1.1 2.7.39 1.3 2.4 5.2 3.7 7.1 1.5 2.2 1.4 3.2-.48 4.8-.86.76-2.2 1.6-3 1.8-2.6.87-3.1 1.6-4.3 5.9-1.1 4.3-1.5 5-4.3 6.9-.87.59-3.8 3.2-6.5 5.9-2.7 2.6-5.8 5.4-6.9 6.1-1.7 1.1-6.8 3.8-7.2 3.8-.079 0-.064-2.1.035-4.7.13-3.4.32-4.8.7-5.3.61-.7 5-1.8 6.2-1.5 1.5.36 2.8-.39 7.8-4.7 4.7-4 5.1-4.5 5.5-5.9.23-.89.36-1.7.31-1.7-.24-.18-10 5.5-14 7.6-4.1 2.7-5.9 3.5-8.1 3.5-.87 0-1.6-.056-1.6-.12 0-.068.16-.58.36-1.1.2-.56.66-2.8 1-5 .38-2.3.9-4.2 1.2-4.5.46-.46 1.2-.48 5.4-.1 5.7.49 5.7.48 11-2.5 4.8-2.7 5.4-3.2 5.1-4.3-.12-.49-1.5-2.3-3.1-4-1.6-1.7-3.9-4.2-5-5.5l-2.1-2.4-11-.56c-6.3-.31-12-.72-13-.91-1.9-.51-2.4-1.2-2.4-3.2v-1.8l-1.3.22c-4.6.75-11 1-15 .62-7.4-.68-12-2.2-19-6.5-5.1-3-5.2-3-8.8.27-3.1 2.9-4.1 3.5-6.8 4.5-2.1.76-2.7.8-10 .72-11-.12-12 .17-18 5.5-3.9 3.8-6 5.5-11 9.1-2.1 1.4-4.1 3-4.7 3.6-1.1 1.3-.92 2.2 1.2 4.8 3.1 3.9 3.5 4.5 3.7 5.9.13.79.11 1.6-.06 1.7-.38.38-6.1 1.4-7.8 1.4l-1.3-.006-2-4.6c-2.5-5.6-2.9-7.2-2.4-9.8.7-3.8 1.1-4.8 1.7-4.5.32.12 1.2.31 2.1.43 1.3.17 1.7.041 3-.85.85-.58 2.5-1.6 3.8-2.2 1.2-.61 2.8-1.7 3.6-2.5 2.6-2.7 5.1-8.7 6.8-16l.79-3.6 2.3-.012c5.8-.031 11-1.9 14-4.7 1.3-1.5 3.5-5.5 3.2-5.8-.31-.31-8.4.99-12 2-7.1 1.8-77 36-84 40 0 0 17-13 42-24z" style="fill:#c87137;stroke-width:.35"/>
</g>
</svg>
</div>
</body>
</html>
А давайте оживим обычные, рутинные времена проведения конкурсов.
Накануне Новый год! Самый любимый и весёлый праздник в году. Когда все надеются и ждут чего-то хорошего.
Наш конкурс предпраздничный и поэтому можно отойти от сложившихся традиций проведения конкурсов. Когда идёт жёсткая конкуретная борьба, а порою соперники отходят от правил фейр-плей
До последнего момента не ясно, кого выберут победителем. Каждый участник конкурса надеется, что выберут его ответ и с нетерпением ждёт окончания конкурса. Наконец чей-то ответ принимается, как победивший в конкурсе. Проигравшим остается разочарование, а порою и острый негатив, если они считали и продолжают считать свой ответ лучше, чем выбранный ответ.
Как сделать, чтобы наш предновогодний конкурс не был похож на обычный, рабочий сценарий?
Предлагаю разрешить каждому участнику от одной до трёх конкурсных попыток в отдельных постах.
Что это даст?
Опубликовав первый ответ, можно увидеть реакцию и вовремя скорректировать себя в последующих ответах.
В трех ответах можно более широко, разнонаправленно развернуться.
И что греха таить, наличие трех, положительно отмеченных постов
, смягчит горечь поражения.
Выиграет ведь только один конкурсант :-)
Как будут подводиться итоги и выбираться победитель?
По сумме нескольких номинаций:
Чтобы не топить конкурсный топик в комментариях, можно обсуждать, размещать свои мнения в чатах. В главном чате это будет размыто, предлагаю здесь https://chat.stackexchange.com/rooms/70612/svg-chat
Что ещё могу добавить, не решайте заранее для себя, что вы проиграете уже опубликованному ответу, не лишайте себя шанса, если уж и не выиграть, то хотя бы согреться :) Вперёд коллеги!
Продолжу делать елку — рандомная генерация снежинок. Даже получилось сделать её адаптивной.
Смотреть в полноэкранном режиме
url = ["https://ya-webdesign.com/images/5-point-snowflake-png-3.png", "https://www.nextibs.com/wp-content/uploads/2013/04/2744.png", "https://www.shareicon.net/download/2015/09/08/97611_snowflake_512x512.png", "http://www.clker.com/cliparts/5/H/p/E/a/z/blue-snowflake-md.png", "https://cdn.pixabay.com/photo/2015/11/30/13/05/flake-1070310_960_720.png"];
function generate(){
var ran_bot = 0;
var ran_top = $(window).width()-50;
var random = Math.floor(Math.random() * ran_top) + ran_bot;
var rand = url[Math.floor(Math.random() * url.length)];
var img = document.createElement("img");
img.setAttribute("height", "100px");
img.setAttribute("src", rand);
img.setAttribute("style", "opacity: 0.7; animation: fall 3s ease-in; position: absolute; top: -100px; left: " + random + "px");
$("body").append(img);
setTimeout(generate, Math.floor(Math.random() * 1000) + 100);
}
generate();
@keyframes fall{
from{
transform: translateY(0);
}
to{
transform: translateY(100vh);
}
}
body{
background-color: darkblue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Это внеконкурсный ответ
.tree {
width:100%;
height:100%;
outline:1px solid green;
position:relative;
}
.txt1 {
position:absolute;
top:25%;
left:5%;
}
<div class="tree">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1260 709" >
<image id="img1" xlink:href="https://i.stack.imgur.com/JWPjk.jpg" width="100%" height="100%" opacity="1" />
<!-- Анимация появления картинки мальчика, читающего стихи под ёлочкой на табуретке -->
<g transform="scale(0.6) translate(-320 470)">
<image id="img2" xlink:href="https://i.stack.imgur.com/MChyh.png" width="100%" height="100%" opacity="0" >
<animate id="an_img" attributeName="opacity" values="0;1" begin="btn.click;an_img_none.end+1.5s" dur="2s" repeatCount="1" fill="freeze"/>
<animate id="an_img_none" attributeName="opacity" values="1;0" begin="an_fill_none.end+1s" dur="2s" repeatCount="1" fill="freeze"/>
</image>
<!-- Замкнутый Контур контейнера для стихов -->
</g>
<path transform="scale(0.85) translate(0 170)" fill="none" stroke="white" fill-opacity="0.8" stroke-width="2" stroke-dasharray="1025" stroke-dashoffset="1025" d="m386.6 66.7c31.1 0.1 36.2 126-18 109-41.2-12.9-75 80.3-95.1 122-20.4 42.3 56.2-122.7 4.5-122.6-68.8 0.1-65.9-1.2-154.7-1.2-42.2 0-60.4-105.3 1.2-107.6 68.5-2.6 87.2 0.5 147.8 0.3 10.2 0 33.3 0.2 41.6 0.2 15.8 0 56.7-0.2 72.8-0.1z" >
<!-- анимация прорисовки контура для стихов -->
<animate id="an_str"
attributeName="stroke-dashoffset"
values="1025;0"
begin="an_img.end+0.5s"
dur="2s"
repeatCount="1"
fill="freeze"/>
<!-- анимация заполнения фона контура -->
<animate id="an_fill"
attributeName="fill"
values="transparent;white"
begin="an_str.end"
dur="2s"
repeatCount="1"
fill="freeze"/>
<!-- анимация исчезновения контура-->
<animate id="an_str_none"
attributeName="stroke-dashoffset"
values="0;1025"
begin="an_fill_none.end"
dur="2s"
repeatCount="1"
fill="freeze"/>
<!-- анимация исчезновения фона контура -->
<animate id="an_fill_none"
attributeName="fill"
values="white;transparent"
begin="an_text.end"
dur="2s"
repeatCount="1"
fill="freeze"/>
</path>
<g id="btn">
<rect x="0" y="10" rx="15" stroke="green" id="rec1" width="100px" height="40px" fill="greenyellow" />
<text x="18" y="40" font-size="32" fill="crimson"> Start </text>
</g>
<!-- Блок стихов -->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
width="30%" height="40%" viewBox="0 40 -200 100">
<!-- <rect width="100%" height="100%" fill="none" fill-opacity="1" stroke="red" style="border:1px solidred;" /> -->
<text transform="translate(100 175 )" style="font-size:24px;fill:#0D440D;font-family:Garamond"
x="0"
y="0">
<tspan x="0" y="0">Нарядная, пушистая</tspan>
<tspan x="0" y="100">К нам ёлочка пришла</tspan>
<tspan x="0" y="150">И аромат душистый</tspan>
<tspan x="0" y="200">Домой к нам принесла!</tspan>
<tspan x="0" y="250">Вокруг неё, зелёной,</tspan>
<tspan x="0" y="300">Мы водим хоровод,</tspan>
<tspan x="0" y="350">Сегодня встретим новый,</tspan>
<tspan x="0" y="400">Счастливый самый год!</tspan>
<!-- Анимация движения строчек стихов -->
<animateMotion id="an_text"
path="M 0 0 L 0 -400"
begin="an_fill.end+0.5s"
dur="10s"
repeatCount="1"
fill="freeze" />
</text>
</svg>
</svg>
</div>
Live Demo
Выражаю благодарность @Варлам-Ерофеич, который предоставил мне баллон для диалогов, улучшенной формы.
.tree {
width:100%;
height:100%;
outline:1px solid green;
position:relative;
}
.txt1 {
position:absolute;
top:25%;
left:5%;
}
<div class="tree">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1260 709" >
<defs>
<mask id="msk1">
<rect width="100%" height="100%" fill="black" />
<path fill="white" transform="scale(0.85) translate(0 170)" fill="none" stroke="white" fill-opacity="0.8" stroke-width="2" stroke-dasharray="1540" stroke-dashoffset="1540" d="M 375 425 Q 450 300 375 300 L 200 300 A 50 50 0 1 1 200 125 L 600 125 A 50 50 0 1 1 600 300 Q 475 300 375 425 Z" >
</mask>
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="4" dy="8" stdDeviation="4"/>
</filter>
</defs>
<image id="img1" xlink:href="https://i.stack.imgur.com/JWPjk.jpg" width="100%" height="100%" opacity="1" />
<image id="SnowMaiden" transform="translate(750 310)" xlink:href="https://i.stack.imgur.com/MAz5g.png"
width="60%" height="60%" opacity="0" >
<!-- Анимация появления снегурочки -->
<animate id="Maiden"
attributeName="opacity"
values="0;1"
begin="btn.click"
dur="2s"
repeatCount="1"
fill="freeze"
restart="whenNotActive"/>
<!-- Анимация движения снегурочки -->
<animateTransform id="RunMaiden"
attributeName="transform"
type="translate"
values="750 310; 300 310"
begin="Maiden.end-1.2s"
dur="2s"
fill="freeze"
restart="whenNotActive" />
<!-- Анимация движения снегурочки после стихов мальчика -->
<animateTransform id="RunMaiden2"
attributeName="transform"
type="translate"
values="300 310; 100 310"
begin="an_fill_none.end"
dur="2s"
fill="freeze"
restart="whenNotActive" />
</image>
<g id="MaidenWords">
<!-- Контур для слов снегурочки -->
<path transform="scale(0.6) translate(450 400)" filter="url(#shadow)" fill="none" stroke="white" fill-opacity="0.8" stroke-width="2" stroke-dasharray="1549" stroke-dashoffset="1549" d="M 375 425 Q 450 300 375 300 L 200 300 A 50 50 0 1 1 200 125 L 600 125 A 50 50 0 1 1 600 300 Q 475 300 375 425 Z" >
<!-- анимация прорисовки контура слов снегурочки -->
<animate id="Maiden_str"
attributeName="stroke-dashoffset"
values="1549;0"
begin="RunMaiden.end+0.5s"
dur="2s"
repeatCount="1"
fill="freeze"
restart="whenNotActive"/>
<!-- анимация заполнения фона контура -->
<animate id="Maiden_fill"
attributeName="fill"
values="transparent;white"
begin="Maiden_str.end"
dur="2s"
repeatCount="1"
fill="freeze"
restart="whenNotActive"/>
</path>
<text id="txt1" transform="translate(400 400 )" style="font-size:24px;fill:#0D440D;font-family:Garamond; opacity:0;"
x="0"
y="0">
<tspan x="-10" y="-50">Дети.Кто хочет подарков?</tspan>
<tspan x="-10" y="0">Читайте стихи про ёлочку! </tspan>
</text>
<!-- Анимация появления текста снегурочки -->
<animate id="text_opacity"
xlink:href="#txt1"
attributeName="opacity"
values="0;1"
dur="1s"
begin="Maiden_fill.end"
fill="freeze"
restart="whenNotActive" />
<!-- Исчезновение текста снегурочки -->
<animate id="disWordMaiden"
xlink:href="#MaidenWords"
attributeName="opacity"
values="1;0"
dur="1s"
begin="text_opacity.end+2s"
fill="freeze"
restart="whenNotActive" />
</g>
<!-- Анимация появления картинки мальчика, читающего стихи под ёлочкой на табуретке -->
<g transform="scale(0.6) translate(-320 470)">
<image id="img2" xlink:href="https://i.stack.imgur.com/MChyh.png" width="100%" height="100%" opacity="0" filter="url(#shadow)" >
<animate id="an_img"
attributeName="opacity"
values="0;1"
begin="disWordMaiden.end+1s"
dur="2s"
repeatCount="1"
fill="freeze"
restart="whenNotActive"/>
</image>
</g>
<!-- Контур для стихов мальчика -->
<path transform="scale(0.6) translate(0 200)" filter="url(#shadow)" fill="none" stroke="white" fill-opacity="0.8" stroke-width="2" stroke-dasharray="1549" stroke-dashoffset="1549" d="M 375 425 Q 450 300 375 300 L 200 300 A 50 50 0 1 1 200 125 L 600 125 A 50 50 0 1 1 600 300 Q 475 300 375 425 Z" >
<!-- анимация прорисовки контура для стихов -->
<animate id="an_str"
attributeName="stroke-dashoffset"
values="1549;0"
begin="an_img.end+0.5s"
dur="2s"
repeatCount="1"
fill="freeze"
restart="whenNotActive"/>
<!-- анимация заполнения фона контура -->
<animate id="an_fill"
attributeName="fill"
values="transparent;white"
begin="an_str.end"
dur="2s"
repeatCount="1"
fill="freeze"
restart="whenNotActive"/>
<!-- анимация исчезновения контура-->
<animate id="an_str_none"
attributeName="stroke-dashoffset"
values="0;1549"
begin="an_fill_none.end"
dur="2s"
repeatCount="1"
fill="freeze"
restart="whenNotActive"/>
<!-- анимация исчезновения фона контура -->
<animate id="an_fill_none"
attributeName="fill"
values="white;transparent"
begin="an_text.end"
dur="2s"
repeatCount="1"
fill="freeze"
restart="whenNotActive"/>
</path>
<g id="btn" filter="url(#shadow)">
<rect x="0" y="10" rx="15" stroke="green" id="rec1" width="100px" height="40px" fill="greenyellow" />
<text x="18" y="40" font-size="32" fill="crimson"> Start </text>
</g>
<!-- Блок стихов -->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
width="30%" height="40%" viewBox="0 40 -200 100">
<text transform="translate(100 175 )" style="font-size:24px;fill:#0D440D;font-family:Garamond;
filter:"url(#shadow);"
x="0"
y="0">
<tspan x="0" y="0">Нарядная, пушистая</tspan>
<tspan x="0" y="100">К нам ёлочка пришла</tspan>
<tspan x="0" y="150">И аромат душистый</tspan>
<tspan x="0" y="200">Домой к нам принесла!</tspan>
<tspan x="0" y="250">Вокруг неё, зелёной,</tspan>
<tspan x="0" y="300">Мы водим хоровод,</tspan>
<tspan x="0" y="350">Сегодня встретим новый,</tspan>
<tspan x="0" y="400">Счастливый самый год!</tspan>
<!-- Анимация движения строчек стихов -->
<animateMotion id="an_text"
path="M 0 0 L 0 -400"
begin="an_fill.end+0.5s"
dur="8s"
repeatCount="1"
fill="freeze"
restart="whenNotActive" />
</text>
</svg>
<!-- Корзина с подарками -->
<image id="img4" transform="translate(370 480)" xlink:href="https://i.stack.imgur.com/F4BVa.png" width="30%" height="30%" opacity="0" filter="url(#shadow)" >
<animate id="Basket_Op"
attributeName="opacity"
values="0;1"
dur="0.1s"
begin="RunMaiden2.end"
fill="freeze"
restart="whenNotActive" />
<!-- Анимация Корзины с подарками к мальчику -->
<animateTransform id="Basket_Up" attributeName="transform" type="translate" values="370 480; 70 480" dur="2s" begin="Basket_Op.end" fill="freeze" />
<!-- Анимация исчезновения снегурочки -->
<animate id="No_Maiden"
attributeName="opacity"
xlink:href="#SnowMaiden"
values="1;0"
begin="Basket_Up.end-1s"
dur="2s"
repeatCount="1"
fill="freeze"
restart="whenNotActive"/>
</image>
</svg>
</div>
Дискотеки Авария -"Новогодняя"
Начало анимации взято из другого моего ответа,- где мальчик читает стихи на табуретке под ёлочкой. Остальная, большая часть анимации публикуется впервые.
На мой взгляд интересно получилась анимация парочки,- зайца с гитарой и снеговика.
Применена техника совместной анимации, которая позволила с малым количеством кода реализовать алгоритм сложных совместных движений двух персонажей.
С 2:11 - начинается прилёт на самолёте пьяненького, но весёлого Деда Мороза, который по пути с Камчатки потерял снегурочку или она сама потерялась :)
Я попытался приблизить музыкальное сопровождение, темп и смысловую нагрузку трека к анимации.
.tree {
width:100%;
height:100%;
position:relative;
}
.txt1 {
position:absolute;
top:25%;
left:5%;
}
<div class="tree">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1260 709" >
<defs>
<mask id="msk1" x="0" y="0" width="200" height="100" >
<rect fill="white" x="0" y="0" width="100%" height="100%" />
<circle cx="600" cy="350" r="1" fill="black" stroke-width="70" stroke="yellow" >
<animate id="no_Princess" attributeName="r" values="1;350;350;1000" dur="7s" restart="whenNotActive" fill="freeze" />
</circle>
</mask>
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="4" dy="8" stdDeviation="4"/>
</filter>
</defs>
<image id="img1" xlink:href="https://i.stack.imgur.com/JWPjk.jpg" width="100%" height="100%" opacity="1" />
<image id="Princess" xlink:href="https://i.stack.imgur.com/u50yb.jpg" transform="translate(-120 0) scale(1.2 1)" width="100%" height="100%" mask="url(#msk1)" >
</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">С Новым 2019 годом!</tspan>
<!-- Движение фразы вдоль кривой линии begin ="80s" -->
<animate id="NY_move"
begin ="80s"
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="98.5s" />
<set id="lime" attributeName="fill" to="lime" begin="106s" />
<set id="purple" attributeName="fill" to="purple" begin="114.5s" />
<animateTransform id="Scale_purple" attributeName="transform" type="scale" dur="1.5s" from="1" to="2" begin="114.5s" fill="freeze" />
</text>
<!-- Анимация самолёта Деда мороза -->
<path id="path1" d="m590 38.6c0 0 436.3-46.4 600.7-5.8 40.8 10.1 21.2 56.9 2.2 63-103.1 33.1-271.3 103.3-324.8 9.1-9.3-16.4 12.7-41.3 30.4-47.8 108.3-39.6 335.3-12 330.3 103.2-8 182.6-547.1-65.1-535.7 117.3 11 176 483.5-123.1 527 47.8 23.8 93.7-241.2 160.8-241.2 160.8v0" style="fill:none;stroke:none"/>
<image id="fly" xlink:href="https://i.stack.imgur.com/qnNmf.png" width="2%" height="2%" opacity="1" >
<animateMotion id="MotionHal" begin="140s" dur="24s" fill="freeze" rotate="auto-reverse" >
<mpath xlink:href="#path1" />
</animateMotion>
<animateTransform id="an_fly" attributeName="transform" type="scale" begin="140s" dur="25s" values="1;2;2;2;4;4;4;7;7;8;8;9;9;10;11;12" fill="freeze" />
<animate id="no_fly" attributeName="opacity" begin="an_fly.end" dur="3.5s" values="1;0" repeatCount="1" fill="freeze" />
</image>
<!-- Дед мороз -->
<image id="Ded_Moroz" transform="translate(650 300) scale(1 1)" xlink:href="https://i.stack.imgur.com/LCvNN.png" width="60%" height="60%" opacity="0">
<animate id="Yes_Ded" attributeName="opacity" begin="no_fly.end" dur="2.5s" values="0;1"
repeatCount="1" fill="freeze" />
<animateTransform attributeName="transform" type="translate" begin="Yes_Ded.end+1s" values="650 300; 600 350;600 300;600 350;650 300;650 350;650 300" dur="2.5s" repeatCount="indefinite" />
</image>
<!-- Анимация снеговика -->
<image id="Snowman" transform="translate(970 480) scale(0.8 0.8)" x="0" xlink:href="https://i.stack.imgur.com/mbefD.png" width="40%" height="40%" opacity="0" filter="url(#shadow)" >
<animateTransform id="Snowman_Up" attributeName="transform" type="translate" values="750 455;755 425;760 415;755 435;750 455" dur="0.5s" begin="zayka_Up.begin+4.5s;Snowman_Up2.end" repeatCount="11" />
<animate attributeName="x" begin="zayka_Up.begin+4.5s" dur="2.5s" values="0;50;70;100;70;50;50;0" repeatCount="indefinite" />
<animate attributeName="opacity" begin="zayka_Up.begin+4.5s" dur="4.5s" values="0;1" repeatCount="1" fill="freeze" />
<!-- Анимация снеговика + заец -->
<animateTransform id="Snowman_Up2" attributeName="transform" type="translate" values="270 450;275 430;280 410;275 430;270 450" dur="0.5s" begin="Snowman_Up.end" repeatCount="11" />
</image>
<!-- Анимация появления снегурочки -->
<image id="SnowMaiden" transform="translate(750 310)" xlink:href="https://i.stack.imgur.com/MAz5g.png"
width="60%" height="60%" opacity="0" >
<animate id="Maiden"
attributeName="opacity"
values="0;1"
begin="no_Princess.end-0.5s"
dur="2s"
repeatCount="1"
fill="freeze"
restart="whenNotActive"/>
<!-- Анимация движения снегурочки -->
<animateTransform id="RunMaiden"
attributeName="transform"
type="translate"
values="750 310; 300 310"
begin="Maiden.end"
dur="2s"
fill="freeze"
restart="whenNotActive" />
<!-- Анимация движения снегурочки после стихов мальчика -->
<animateTransform id="RunMaiden2"
attributeName="transform"
type="translate"
values="300 310; 100 310"
begin="an_fill_none.end"
dur="2s"
fill="freeze"
restart="whenNotActive" />
</image>
<g id="MaidenWords">
<!-- Контур для слов снегурочки -->
<path transform="scale(0.9) translate(150 -70)" filter="url(#shadow)" fill="none" stroke="white" fill-opacity="0.8" stroke-width="2" stroke-dasharray="1549" stroke-dashoffset="1549" d="m525 495q-45-75 0-75h105a52.5 52.5 0 1 0 0-105H390a52.5 52.5 0 1 0 0 105q75 0 135 75z" >
<!-- анимация прорисовки контура слов снегурочки -->
<animate id="Maiden_str"
attributeName="stroke-dashoffset"
values="1549;0"
begin="RunMaiden.end+0.5s"
dur="2s"
repeatCount="1"
fill="freeze"
restart="whenNotActive"/>
<!-- анимация заполнения фона контура -->
<animate id="Maiden_fill"
attributeName="fill"
values="transparent;white"
begin="Maiden_str.end"
dur="2s"
repeatCount="1"
fill="freeze"
restart="whenNotActive"/>
</path>
<text id="txt1" transform="translate(500 350 )" style="font-size:24px;fill:#0D440D;font-family:Garamond; opacity:0;"
x="0"
y="0">
<tspan x="-10" y="-100">Кто прочтёт стихи про</tspan>
<tspan x="-10" y="-50">ёлочку. Кому подарки? </tspan>
</text>
<!-- Анимация появления текста снегурочки -->
<animate id="text_opacity"
xlink:href="#txt1"
attributeName="opacity"
values="0;1"
dur="1s"
begin="Maiden_fill.end"
fill="freeze"
restart="whenNotActive" />
<!-- Исчезновение текста снегурочки -->
<animate id="disWordMaiden"
xlink:href="#MaidenWords"
attributeName="opacity"
values="1;0"
dur="1s"
begin="text_opacity.end+2s"
fill="freeze"
restart="whenNotActive" />
</g>
<!-- Контур для стихов мальчика -->
<path transform="scale(0.6) translate(0 200)" filter="url(#shadow)" fill="none" stroke="white" fill-opacity="0.8" stroke-width="2" stroke-dasharray="1549" stroke-dashoffset="1549" d="M 375 425 Q 450 300 375 300 L 200 300 A 50 50 0 1 1 200 125 L 600 125 A 50 50 0 1 1 600 300 Q 475 300 375 425 Z" >
<!-- анимация прорисовки контура для стихов -->
<animate id="an_str"
attributeName="stroke-dashoffset"
values="1549;0"
begin="an_img.end+0.5s"
dur="2s"
repeatCount="1"
fill="freeze"
restart="whenNotActive"/>
<!-- анимация заполнения фона контура -->
<animate id="an_fill"
attributeName="fill"
values="transparent;white"
begin="an_str.end"
dur="2s"
repeatCount="1"
fill="freeze"
restart="whenNotActive"/>
<!-- анимация исчезновения контура-->
<animate id="an_str_none"
attributeName="stroke-dashoffset"
values="0;1549"
begin="an_fill_none.end"
dur="2s"
repeatCount="1"
fill="freeze"
restart="whenNotActive"/>
<!-- анимация исчезновения фона контура -->
<animate id="an_fill_none"
attributeName="fill"
values="white;transparent"
begin="an_text.end"
dur="2s"
repeatCount="1"
fill="freeze"
restart="whenNotActive"/>
</path>
<!-- Блок стихов -->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
width="30%" height="40%" viewBox="0 40 -200 100">
<text transform="translate(120 175 )" style="font-size:24px;fill:#0D440D;font-family:Garamond;
filter:"url(#shadow);"
x="0"
y="0">
<tspan x="0" y="0">Нарядная, пушистая</tspan>
<tspan x="0" y="100">К нам ёлочка пришла</tspan>
<tspan x="0" y="150">И аромат душистый</tspan>
<tspan x="0" y="200">Домой к нам принесла!</tspan>
<tspan x="0" y="250">Вокруг неё, зелёной,</tspan>
<tspan x="0" y="300">Мы водим хоровод,</tspan>
<tspan x="0" y="350">Сегодня встретим новый,</tspan>
<tspan x="0" y="400">Счастливый самый год!</tspan>
<!-- Анимация движения строчек стихов -->
<animateMotion id="an_text"
path="M 0 0 L 0 -400"
begin="an_fill.end+0.5s"
dur="8s"
repeatCount="1"
fill="freeze"
restart="whenNotActive" />
</text>
</svg>
<!-- Анимация появления картинки мальчика, читающего стихи под ёлочкой на табуретке -->
<g transform="scale(0.6) translate(-320 470)">
<image id="img2" xlink:href="https://i.stack.imgur.com/MChyh.png" width="100%" height="100%" opacity="0" filter="url(#shadow)" >
<animate id="an_img"
attributeName="opacity"
values="0;1"
begin="disWordMaiden.end+1s"
dur="2s"
repeatCount="1"
fill="freeze"
restart="whenNotActive"/>
</image>
</g>
<!-- Корзина с подарками -->
<image id="img4" transform="translate(370 480)" xlink:href="https://i.stack.imgur.com/F4BVa.png" width="30%" height="30%" opacity="0" filter="url(#shadow)" >
<animate id="Basket_Op"
attributeName="opacity"
values="0;1"
dur="0.1s"
begin="RunMaiden2.end"
fill="freeze"
restart="whenNotActive" />
<!-- Анимация Корзины с подарками к мальчику -->
<animateTransform id="Basket_Up" attributeName="transform" type="translate" values="370 480;150 240; 70 480" dur="2s" begin="Basket_Op.end" fill="freeze" />
<!-- Анимация исчезновения снегурочки -->
<animate id="No_Maiden"
attributeName="opacity"
xlink:href="#SnowMaiden"
values="1;0"
begin="Basket_Up.end-1.5s"
dur="2s"
repeatCount="1"
fill="freeze"
restart="whenNotActive"/>
</image>
<!-- Анимация зайчика с гитарой -->
<image id="zayka" transform="translate(270 450) scale(1 1)" x="0" xlink:href="https://i.stack.imgur.com/3xzEW.png" width="40%" height="40%"
opacity="0" filter="url(#shadow)" >
<animateTransform id="zayka_Up" attributeName="transform" type="translate" values="270 450;275 430;280 410;275 430;270 450" dur="0.5s" begin="RunMaiden2.end" repeatCount="indefinite" />
<animate attributeName="x" begin="RunMaiden2.end" dur="2.5s" values="0;50;70;100;70;50;50;0" repeatCount="indefinite" />
<animate attributeName="opacity" begin="RunMaiden2.end" dur="1.5s" values="0;1" repeatCount="1" fill="freeze" />
</image>
</svg>
</div>
<audio src="https://svg-art.ru/files/diskoteka_avariya_novogodnyaya.mp3" autoplay="autoplay"></audio>
Новоиспечённый снеговичок бает сказы:
html {background:
repeating-linear-gradient(45deg, #666, #222, #666, #ea8, #666, #222, #666, #8ce, #666 4%) fixed; }
body {max-width: 70rem;}
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 1200 680" width="100%" height="100%" preserveaspectratio="none"
style="background-color:#ccc;">
<pattern id="sneg" width="100%" height="100%" fill="none">
<rect id="rec2" x="0" y="0" rx="15" stroke="none"
width="1200px" height="300px" style="cursor: pointer;">
<!-- красим фон rec2 -->
<animate id="an_fill" attributeName="fill"
values="transparent; #dee"
begin="an_str.end" dur="2s"
repeatCount="1" fill="freeze"/>
<!-- стираем фон rec2 -->
<animate id="an_fill_none" attributeName="fill"
values="#dee;transparent"
begin="an_text.end" dur="2s"
repeatCount="1" fill="freeze"/>
</rect>
<image id="sn" opacity="0" width="10%" style="x:670; y:50;"
xlink:href="https://r.mtdata.ru/r480x-/u28/photo0F6D/20814230894-0/original.jpeg" />
<!-- рисуем снежинку -->
<animate id="an_sn" xlink:href="#sn"
attributeName="opacity" values="0; 1"
begin="an_text.begin+5s" dur="2s"
repeatCount="1" fill="freeze"/>
<!-- стираем снежинку -->
<animate id="an_nosn" xlink:href="#sn"
attributeName="opacity" values="1; 0"
begin="an_text.end-5s" dur="2s"
repeatCount="1"fill="freeze"/>
<text style="font-family: Arial; font-size: 36px; font-style: italic; fill: #000;">
<tspan x="100" y="350">Путь млечный тучка подпирает, </tspan>
<tspan x="100" y="400">Луну и звёзды - ночь верстает, </tspan>
<tspan x="100" y="450">Закрыты глазки сном подушки, </tspan>
<tspan x="100" y="500">Под песен ласки спят игрушки. </tspan>
<tspan x="100" y="550">Парят снежинки за окошком, </tspan>
<tspan x="100" y="600">Щекотят нос котам и кошкам, </tspan>
<tspan x="100" y="650">А после, покружив немножко, </tspan>
<tspan x="100" y="700">Ковром ложатся на дорожку, </tspan>
<tspan x="100" y="800">Укрыв дома, деревья, землю </tspan>
<tspan x="100" y="850">- Периной тёплой... </tspan>
<tspan x="100" y="900">- Пусть подремлют, </tspan>
<tspan x="100" y="950">Угомонившись до весны; </tspan>
<tspan x="100" y="1000">- Им тоже будут сниться сны. </tspan>
<tspan x="100" y="1100">Растут сугробы от порога, </tspan>
<tspan x="100" y="1150">Впотьмах теряется дорога, </tspan>
<tspan x="100" y="1200">А тучки - снова снег роняют, </tspan>
<tspan x="100" y="1250">Снежинки - сон твой охраняют. </tspan>
<tspan fill="#800" x="100" y="1350">Я завтра горочку построю </tspan>
<tspan fill="#800" x="100" y="1400">И бабу снежную слеплю, </tspan>
<tspan fill="#800" x="100" y="1450">А после вам весь Мир открою; </tspan>
<tspan fill="#800" x="100" y="1500">Ведь в нём я только вас люблю!..</tspan>
<!-- transform="translate(80 100 )" an_text -->
<!-- пишем стихи -->
<animateMotion id="an_text"
path="M 0 0 L 0 -1500"
begin="an_fill.end +.5s" dur="28s"
repeatCount="1" fill="freeze" />
</text>
<!-- красим фон rec3 -->
<rect id="rec3" x="0" y="240" rx="15" stroke="none"
width="1200px" height="200px" style="cursor: pointer;">
<animate id="an_fill" attributeName="fill"
values="transparent;#dee"
begin="an_str.end" dur="2s"
repeatCount="1" fill="freeze"/>
<!-- стираем фон rec3 -->
<animate id="an_fill_none" attributeName="fill"
values="#dee;transparent"
begin="an_text.end" dur="2s"
repeatCount="1"fill="freeze"/>
</rect>
</pattern>
<pattern id="god" width="100%" height="100%" fill="none">
<rect id="rec2" x="0" y="0" rx="15" stroke="none"
width="1200px" height="300px" style="cursor: pointer;">
<!-- красим фон rec2 -->
<animate id="an_fill1" attributeName="fill"
values="transparent; #dee"
begin="an_str1.end" dur="2s"
repeatCount="1" fill="freeze"/>
<!-- стираем фон rec2 -->
<animate id="an_fill1_none" attributeName="fill"
values="#dee;transparent"
begin="an_text1.end" dur="2s"
repeatCount="1" fill="freeze"/>
</rect>
<text style="font-family: Arial; font-size: 32px; font-style: italic; fill: #000;">
<tspan x="100" y="350">А на другом краю деревни, - (через брод), </tspan>
<tspan x="100" y="400">Уже шагает праздник древний... </tspan>
<tspan fill="#068" x="100" y="450">-Новый год-, </tspan>
<tspan x="100" y="500">Отнюдь, не знает заграничных яств - стол, </tspan>
<tspan x="100" y="550">Зато дороже всяких "царств"... </tspan>
<tspan fill="#080" x="100" y="600">-Лес и Дол!- </tspan>
<tspan x="100" y="700">Пришли "волхвы", - Я дверь им отворил: </tspan>
<tspan x="100" y="750">- Озябли? (те в ответ мне стали "ухать"), </tspan>
<tspan x="100" y="800">- Чем Бог послал... (и самогону им налил), </tspan>
<tspan x="100" y="850">На закусь - рукавом пришлось "занюхать"... </tspan>
<tspan fill="#800" x="100" y="950">А у соседей, что ни день - гулянка, </tspan>
<tspan fill="#800" x="100" y="1000">И импортная "Скатерть-Самобранка"...</tspan>
<!-- пишем стихи -->
<animateMotion id="an_text1"
path="M 0 0 L 0 -1100"
begin="an_fill1.end +.5s" dur="28s"
repeatCount="1" fill="freeze" />
</text>
<!-- красим фон rec3 -->
<rect id="rec3" x="0" y="240" rx="15" stroke="none"
width="1200px" height="200px" style="cursor: pointer;">
<animate id="an_fill1" attributeName="fill"
values="transparent;#dee"
begin="an_str1.end" dur="2s"
repeatCount="1" fill="freeze"/>
<!-- стираем фон rec3 -->
<animate id="an_fill1_none" attributeName="fill"
values="#dee;transparent"
begin="an_text1.end" dur="2s"
repeatCount="1"fill="freeze"/>
</rect>
</pattern>
<!-- <image xlink:href="https://www.1zoom.ru/big2/10/121920-aleni.jpg" width="100%"/> -->
<image xlink:href="https://i.stack.imgur.com/jiuun.jpg" width="100%" />
<path id="ballon" fill="url(#sneg)"
stroke="red" stroke-width="2"
stroke-dasharray="2124" stroke-dashoffset="2124"
d="M 550 350
Q 600 260 500 260
L 400 260 A 50 50 0 1 1 400 20
L 1000 20 A 50 50 0 1 1 1000 260
L1000 260 800 260
Q 600 260 550 350 Z" >
</path>
<path id="contur" fill="url(#god)"
stroke="red" stroke-width="2"
stroke-dasharray="2124" stroke-dashoffset="2124"
d="M 550 350
Q 600 260 500 260
L 400 260 A 50 50 0 1 1 400 20
L 1000 20 A 50 50 0 1 1 1000 260
L1000 260 800 260
Q 600 260 550 350 Z" >
</path>
<!-- рисуем контур стихов -->
<animate id="an_str" xlink:href="#ballon"
attributeName="stroke-dashoffset"
begin="btn.click +0.5s" values="2124;0"
dur="2s" repeatCount="1" fill="freeze"/>
<!-- стираем контур стихов -->
<animate id="an_str_none" xlink:href="#ballon"
attributeName="stroke-dashoffset"
begin="an_fill_none.end" values="0;2124"
dur="2s" repeatCount="1" fill="freeze"/>
<!-- рисуем контур стихов про Новый год -->
<animate id="an_str1" xlink:href="#contur"
attributeName="stroke-dashoffset"
begin="btn1.click +0.5s" values="2124;0"
dur="2s" repeatCount="1" fill="freeze"/>
<!-- стираем контур стихов про Новый год -->
<animate id="an_str1_none" xlink:href="#contur"
attributeName="stroke-dashoffset"
begin="an_fill1_none.end" values="0;2124"
dur="2s" repeatCount="1" fill="freeze"/>
<!-- рисуем губы -->
<path fill="#caa" fill-opacity="0.8" stroke="#922" stroke-width="6"
stroke-linecap="round" stroke-linejoin="round"
d="M 410 370
Q 450 415 500 375
Q 450 415 410 370 Z">
<animate id="an_path" attributeName="d"
begin="an_fill.end+3s; an_fill1.end+3s" dur="1.5s"
keyTimes="0; .25; .5; .75; 1"
calcMode="spline"
keySplines="1 .5 0 1;
.5 1 0 .75;
0 .75 1 .5;
.5 1 .75 0"
values="M 410 370
Q 450 415 500 375
Q 450 415 410 370 Z;
M 440 380
Q 435 435 460 385
Q 455 350 440 380 Z;
M 420 370
Q 435 410 480 375
Q 450 400 420 370 Z;
M 440 380
Q 435 435 460 385
Q 455 350 440 380 Z;
M 410 370
Q 440 415 500 375
Q 450 415 410 370 Z"
repeatCount="15" fill="freeze"
restart="whenNotActive"/> <!--/**/-->
</path>
<g id="btn">
<rect id="rec1" x="0" y="10" rx="15" width="180px" height="40px"
style="cursor: pointer; stroke: #822; fill:greenyellow; fill-opacity: 0.8"/>
<text x="16" y="40" font-size="32" fill="crimson" style="cursor: pointer;"> Снежинки </text>
</g>
<g id="btn1">
<rect id="rec1" x="0" y="50" rx="15" width="180px" height="40px"
style="cursor: pointer; stroke: #822; fill:greenyellow; fill-opacity: 0.8"/>
<text x="16" y="80" font-size="32" fill="crimson" style="cursor: pointer;"> Новый год </text>
</g>
</svg>
Для начала покажу ёлочку!
Ёлочка составлена из увеличивающихся звездочек.
Нужно просматривать в полноэкранном режиме.
function add(){
var height = 20; // высота ёлочки, можете её спокойно поменять.
var f_c = 2 * height + 1;
var c = 1;
var row;
for(var j = 0; j < height; j++){
row = "";
row += "<div id = 'tree_row'>";
for(var i = 0; i < ((f_c - c) / 2); i++){
row += "<svg aria-hidden='true' width='1%' height='1%' viewBox='0 0 18 18' id = 'star' style = 'visibility: hidden'><path d='M9 12.65l-5.29 3.63 1.82-6.15L.44 6.22l6.42-.17L9 0l2.14 6.05 6.42.17-5.1 3.9 1.83 6.16z' fill='#E2FA00'></path></svg>";
}
for(var i = 0; i < c; i++){
row += "<svg aria-hidden='true' width='1%' height='1%' viewBox='0 0 18 18' id = 'star' style = '-webkit-animation-delay: " + (i - j) + "s'><path d='M9 12.65l-5.29 3.63 1.82-6.15L.44 6.22l6.42-.17L9 0l2.14 6.05 6.42.17-5.1 3.9 1.83 6.16z' fill='#E2FA00'></path></svg>";
}
for(var i = 0; i < ((f_c - c) / 2); i++){
row += "<svg aria-hidden='true' width='1%' height='1%' viewBox='0 0 18 18' id = 'star' style = 'visibility: hidden'><path d='M9 12.65l-5.29 3.63 1.82-6.15L.44 6.22l6.42-.17L9 0l2.14 6.05 6.42.17-5.1 3.9 1.83 6.16z' fill='#E2FA00'></path></svg>";
}
row += "</div>"
$("#tree").append(row);
if(j % 2){
c+=2;
}
}
}
add();
#star{
animation: animate 2s infinite;
}
@keyframes animate{
33%{
transform: scale(1, 1);
}
66%{
transform: scale(2, 2);
}
99%{
transform: scale(1, 1);
}
}
body{
background-color: darkblue;
}
#tree_row{
margin-top: calc(0.1wv / 3);
}
#tree{
position: fixed;
bottom:0;
left: 30%;
width: calc(1% * 100);
margin-right: calc(1% * 300);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="tree"></div>
А теперь сборка всех моих ответов.
Также нужен полноэкранный режим.
function add(){
var height = 20;
var f_c = 2 * height + 1;
var c = 1;
for(var j = 0; j < height; j++){
$("#tree").append("<div id = 'tree_row'>");
for(var i = 0; i < ((f_c - c) / 2); i++){
$("#tree").append("<svg aria-hidden='true' width='1%' height='1%' viewBox='0 0 18 18' id = 'star' style = 'visibility: hidden'><path d='M9 12.65l-5.29 3.63 1.82-6.15L.44 6.22l6.42-.17L9 0l2.14 6.05 6.42.17-5.1 3.9 1.83 6.16z' fill = '#E2FA00'></path></svg>");
}
for(var i = 0; i < c; i++){
if(c != 1){
$("#tree").append("<svg aria-hidden='true' width='1%' height='1%' viewBox='0 0 18 18' id = 'star' style = '-webkit-animation-delay: " + (i - j) + "s'><path d='M9 12.65l-5.29 3.63 1.82-6.15L.44 6.22l6.42-.17L9 0l2.14 6.05 6.42.17-5.1 3.9 1.83 6.16z' fill = '#E2FA00'></path></svg>");
}
}
if(c == 1 && j == 0){
$("#tree").append("<div id='star_back'><svg aria-hidden='true' width='10%' height='10%' viewBox='0 0 18 18' id = 'main_star'><path d='M9 12.65l-5.29 3.63 1.82-6.15L.44 6.22l6.42-.17L9 0l2.14 6.05 6.42.17-5.1 3.9 1.83 6.16z' fill='gold'></path></svg></div>");
}
for(var i = 0; i < ((f_c - c) / 2); i++){
$("#tree").append("<svg aria-hidden='true' width='1%' height='1%' viewBox='0 0 18 18' id = 'star' style = 'visibility: hidden'><path d='M9 12.65l-5.29 3.63 1.82-6.15L.44 6.22l6.42-.17L9 0l2.14 6.05 6.42.17-5.1 3.9 1.83 6.16z' fill = '#E2FA00'></path></svg>");
}
$("#tree").append("</div>");
if(j % 2){
c+=2;
}
}
}
url = ["https://ya-webdesign.com/images/5-point-snowflake-png-3.png", "https://www.nextibs.com/wp-content/uploads/2013/04/2744.png", "https://www.shareicon.net/download/2015/09/08/97611_snowflake_512x512.png", "https://unixtitan.net/images/blue-snowflake-clipart-5.png"];
function generate(){
var ran_bot = 0;
var ran_top = $(window).width()-100;
var random = Math.floor(Math.random() * ran_top) + ran_bot;
var rand = url[Math.floor(Math.random() * url.length)];
var img = document.createElement("img");
img.setAttribute("height", "50px");
img.setAttribute("src", rand);
img.setAttribute("style", "opacity: 0.7; animation: fall 3s ease-in; position: absolute; top: -100px; left: " + random + "px; -webkit-filter: drop-shadow( -5px -5px 20px lightblue ); filter: drop-shadow( 0px 0px 20px lightblue ); z-index: 1");
img.addEventListener("webkitAnimationEnd", function(){
img.remove();
});
img.addEventListener("animationend", function(){
img.remove();
});
$("body").append(img);
setTimeout(generate, Math.floor(Math.random() * 300) + 1);
}
function garland() {
nums = document.getElementById('nums_1').innerHTML
if (nums == 1) {
document.getElementById('garland').className = 'garland_1';
document.getElementById('nums_1').innerHTML = '2'
}
if (nums == 2) {
document.getElementById('garland').className = 'garland_2';
document.getElementById('nums_1').innerHTML = '3'
}
if (nums == 3) {
document.getElementById('garland').className = 'garland_3';
document.getElementById('nums_1').innerHTML = '4'
}
if (nums == 4) {
document.getElementById('garland').className = 'garland_4';
document.getElementById('nums_1').innerHTML = '1'
}
}
setInterval(function() {
garland()
}, 600)
generate();
add();
#star{
animation: animate 2s infinite;
}
@keyframes animate{
33%{
transform: scale(1, 1);
}
66%{
transform: scale(2, 2);
}
99%{
transform: scale(1, 1);
}
}
@keyframes rays{
from{
transform: rotate(0deg);
}
to{
transform: rotate(-360deg);
}
}
@keyframes rays2{
from{
transform: rotate(180deg) ;
}
to{
transform: rotate(-180deg);
}
}
html, body {
width: 100%;
height: 100%;
margin: 0;
background-color: #00003f;
overflow:hidden;
}
#star_back {
position: relative;
width: 100%;
height: 100%;
}
#star_back:after, #star_back:before {
content: '';
position: fixed;
background: linear-gradient(90deg, transparent 50%, black 50%, black), linear-gradient(82deg, transparent 50%, #00003f 50%, #00003f), linear-gradient(67deg, transparent 50%, #f4c430 50%, #ffed00), linear-gradient(52deg, transparent 50%, #00003f 50%, #00003f), linear-gradient(37deg, transparent 50%, #f4c430 50%, #f4c430), linear-gradient(22deg, transparent 50%, #00003f 50%, #00003f), linear-gradient(7deg, transparent 50%, #f4c430 10%, #f4c430), linear-gradient(-8deg, transparent 50%, #00003f 50%, #00003f), linear-gradient(-23deg, transparent 50%, #f4c430 50%, #f4c430), linear-gradient(-38deg, transparent 50%, #00003f 50%, #00003f), linear-gradient(-53deg, transparent 50%, #f4c430 50%, #f4c430), linear-gradient(-68deg, transparent 50%, #00003f 50%, #00003f), linear-gradient(-83deg, transparent 50%, #f4c430 50%, #f4c430), linear-gradient(-90deg, transparent 50%, #00003f 50%, #00003f), radial-gradient(transparent 90%, white 10%);
background-position: 0% 0%;
background-size: 200% 100%;
height: 240px;
width: 120px;
border-top-left-radius: 50%;
border-bottom-left-radius: 50%;
right: 49.5%;
margin-top: -60px;
margin-left: 240px;
transform-origin: center right;
animation: rays 2s linear infinite;
}
#star_back:before {
transform: translateX(120px) rotate(180deg);
animation: rays2 2s linear infinite;
}
#main_star{
position: fixed;
left: 50%;
width: 100px;
height: 100px;
-webkit-filter: drop-shadow( -5px -5px 5px gold );
filter: drop-shadow( 0px 0px 10px gold );
margin-left: -40px;
z-index: 2;
}
#tree_top{
position: absolute;
}
@keyframes fall{
from{
transform: translateY(0) rotate(0deg);
}
to{
transform: translateY(99vh) rotate(360deg);
}
}
@keyframes santa{
0%{
transform: translateX(0) translateY(0);
}
100%{
transform: translateX(1000vh) translateY(-100vh);
}
}
#santa{
animation: santa 10s linear infinite;
margin-left: -500px;
width: 20%;
z-index: 1;
}
#house_body{
width: 20vw;
height: 20vw;
position: absolute;
left: 0;
bottom: 0;
background-color: sandybrown;
border: 1px solid black;
}
#tree_row{
margin-top: calc(0.1vw / 3);
}
#tree{
position: fixed;
bottom:0;
left: 30%;
width: calc(1% * 100);
margin-right: calc(1% * 300);
z-index: 1;
}
#snow{
position: fixed;
background-color: white;
height: 50px;
width: 100%;
bottom: 0;
}
#roof {
width: 0;
height: 0;
border-left: 10vw solid transparent;
border-right: 10vw solid transparent;
border-bottom: 10vw solid DarkSlateGray;
position: fixed;
bottom: 20vw;
}
#window{
background-color: lightblue;
height: 5vw;
width: 5vw;
border-radius: 50%;
position: fixed;
margin-left: 2vw;
margin-top: 2vw;
border: 5px solid brown;
}
#hor{
width: 100%;
height: 5px;
position: absolute;
background-color: brown;
top: 50%;
}
#ver{
width: 5px;
height: 100%;
position: absolute;
background-color: brown;
left: 50%;
}
#door{
background-color: brown;
height: 10vw;
width: 4vw;
position: fixed;
margin-left: 13vw;
bottom: 0;
border: 5px solid brown;
}
#handle{
background-color: sienna;
height: 1vw;
width: 1vw;
border-radius: 50%;
position: fixed;
margin-left: 0.1vw;
margin-top: 3vw;
}
#garland {
position: absolute;
top: 0;
left: 0;
background-image: url('http://imapo.ru/img/christmas.png');
height: 36px;
width: 100%;
overflow: hidden;
z- index: 99
}
#nums_1 {
padding: 100px
}
.garland_1 {
background-position: 0 0
}
.garland_2 {
background-position: 0 -36px
}
.garland_3 {
background-position: 0 -72px
}
.garland_4 {
background-position: 0 -108px
}
#new_year{
font-family: 'Coiny', cursive;
color: white;
position: fixed;
bottom: 50px;
left: 0;
font-size: 3vw;
left: 50%;
margin-left: calc(1vw * -15);
z-index: 1;
animation: animate_new_year 3s infinite;
}
@keyframes animate_new_year{
25%{
transform: scale(1, 1);
}
75%{
transform: scale(1.1, 1.1);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="tree">
</div>
<div></div>
<div><img src="https://i.stack.imgur.com/MdwXD.png" id = "santa"></div>
<div id = "house">
<div id="roof"></div>
<div id="house_body">
<div id="window">
<div id="hor"></div>
<div id="ver"></div>
</div>
<div id="door">
<div id = "handle"></div>
</div>
</div></div>
<div id = "house" style="margin-left: 20vw">
<div id="roof"></div>
<div id="house_body" style="margin-left: 20vw">
<div id="window">
<div id="hor"></div>
<div id="ver"></div>
</div>
<div id="door">
<div id = "handle"></div>
</div>
</div></div>
<div id = "house" style="margin-left: 60vw">
<div id="roof"></div>
<div id="house_body" style="margin-left: 60vw">
<div id="window">
<div id="hor"></div>
<div id="ver"></div>
</div>
<div id="door">
<div id = "handle"></div>
</div>
</div></div>
<div id = "house" style="margin-left: 80vw">
<div id="roof"></div>
<div id="house_body" style="margin-left: 80vw">
<div id="window">
<div id="hor"></div>
<div id="ver"></div>
</div>
<div id="door">
<div id = "handle"></div>
</div>
</div></div>
<div id="snow"></div>
<div id="garland" class="garland_4">
<div id="nums_1">1</div>
</div>
<div id = "new_year">HAPPY NEW YEAR!</div>
<link href="https://fonts.googleapis.com/css?family=Coiny" rel="stylesheet">
Если у кого-то есть идеи по улучшению или проблема с нормальным показом — не стесняйтесь, пишите.
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Виртуальный выделенный сервер (VDS) становится отличным выбором
У меня такая ситуация,что нужно объяснить концепцию операторов break/continue(зачем они нужны и как работают),с первым все понятно,а со вторым возникают...
Мне необходимо удалить узел дерева, если у него имеются двое детейНаходил примеры удаления на других языках, но без понятия, как это реализовать...