! Сегодня

Главная » Web и Технологии » 3D-анимация «Рождественская елка» в стиле Minecraft для сайта

3D-анимация «Рождественская елка» в стиле Minecraft для сайта

Когда человек действительно хочет чего-то, вся Вселенная вступает в сговор, чтобы помочь этому человеку осуществить свою мечту.

24-ноября-2023, 22:03   0   0

3D-анимация «Рождественская елка»  в стиле Minecraft для сайта

От абстракционизма до ультрамодернизма, 3D-анимация рождественской елки  обладает определенным качеством Minecraft. В этом нет ничего особенного. Но именно эта простота и кубизм отделяют это решение от других. Ёлка построена при помощи HTML и CSS. Она идеально подходит для новогодних праздников. Ею можно украсить тематический сайт или блог посвящённый Майинкрафту или просто привнести настроение для пользователей вашего веб-проекта.

Pug

- var blocks = 31;
- var plates = 1;

.container
  .surface
    - for (var b = 1;b <= blocks;++b) {
      div(class="block b" + b)
        .block-outer
          .block-inner
            .back
            .front
            .left
            .right
            .top
    - }
    - for (var p = 1;p <= plates;++p) {
      div(class="plate p" + p)
    - }


SCSS

$sqSize: 16px;
$contW: 100%;
$contH: 100%;
$xSpaces: 13;
$ySpaces: 13;
$zSpaces: 19;
$xAngle: 60deg;
$zAngle: -45deg;
$prsp: 800px;
$dur: 3s;

// * Colors *
$LG: #6ccf76;
$G: #080;
$Y: #d8cb59;
$t: transparent;
$r: #f44;
$y: #ff4;
$g: #4f4;
$b: #4cf;

// * Block placement *
// parameters: x-pos,y-pos,z-pos, width,depth,height, color
$blocks:
  // * tree *
  // main
  (1,1,1, 13,13,1, $G)
  (3,3,2, 9,9,1, $G)
  (3,3,3, 9,9,1, $G)
  (3,3,4, 9,9,1, $G)
  (2,2,5, 11,11,1, $G)
  (4,4,6, 7,7,1, $G)
  (4,4,7, 7,7,1, $G)
  (4,4,8, 7,7,1, $G)
  (3,3,9, 9,9,1, $G)
  (5,5,10, 5,5,1, $G)
  (5,5,11, 5,5,1, $G)
  (5,5,12, 5,5,1, $G)
  (4,4,13, 7,7,1, $G)
  (6,6,14, 3,3,1, $G)
  (6,6,15, 3,3,1, $G)
  (6,6,16, 3,3,1, $G)
  // * ornaments *
  // left
  (4,7,12, 1,1,1, $y)
  (3,9,8, 1,1,1, $b)
  (3,5,8, 1,1,1, $r)
  (2,10,4, 1,1,1, $r)
  (2,7,4, 1,1,1, $g)
  (2,4,4, 1,1,1, $y)
  // front
  (7,4,12, 1,1,1, $b)
  (9,3,8, 1,1,1, $y)
  (5,3,8, 1,1,1, $g)
  (10,2,4, 1,1,1, $g)
  (7,2,4, 1,1,1, $r)
  (4,2,4, 1,1,1, $b)
  // * star *
  (7,7,17, 1,1,1, #d8cb59)
  (7,6,18, 1,3,1, #d8cb59)
  (7,7,19, 1,1,1, #d8cb59)
  ;

// * Plate placement *
// parameters: x-pos,y-pos,z-pos, width,depth, color, x-angle,y-angle,z-angle, x-origin,y-origin
// this plate covers certain blocks at the bottom during animation
$plates: 
  (0,0,1, 1,1, $t, 0,0,180, 50%,50%);

@mixin placeBlock($x, $y, $z, $w, $d, $h, $c) {
  display: inherit;
  transform: translate3d(
    $sqSize*($x - 1),
    $sqSize*(-$y - ($d - 1)),
    ($sqSize*$z) + ($sqSize*($h - 1))
  );
  .block-inner div {
    background-color: $c;
  &.top, &.bottom {
      width: $sqSize * $w;
      height: $sqSize * $d;
    }
    &.top  {
      transform: rotateX(-90deg) translateY(-$sqSize*($d - 1));
    }
    &.bottom {
      transform: rotateX(-90deg) translateY(-$sqSize*($d - 1)) translateZ($sqSize*$h);
    }
    &.front, &.back {
      width: $sqSize * $w;
      height: $sqSize * $h;
    }
    &.front {
      transform: translateZ($sqSize * ($d - 1));
    }
    &.left, &.right {
      width: $sqSize * $d;
      height: $sqSize * $h;
    }
    &.right {
      transform: rotateY(-270deg) translate3d($sqSize, 0, $sqSize*($w - $d));
    }
  }
}
@mixin moveBlock($x, $y, $z) {
  transform: translate3d($sqSize * $x,$sqSize * -$y,$sqSize * $z);
}
@mixin placePlate($x, $y, $z, $w, $d, $c, $ax, $ay, $az, $xo, $yo) {
  background-color: $c;
  background-size: $sqSize $sqSize;
  display: inherit;
  font-size: $sqSize;
  line-height: $sqSize;
  width: $sqSize * $w;
  height: $sqSize * $d;
  transform: translate3d(
    $sqSize*($x - 1),
    $sqSize*(-$y + 1),
    $sqSize*($z - 1)
  ) rotateX(0deg + $ax) rotateY(0deg + $ay) rotateZ(0deg + $az);
  transform-origin: $xo $yo;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
body {
  height: 100vh;
  margin: 0;
}
.container {
  background-color: $LG;
  display: flex;
  margin: auto;
  overflow: hidden;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: $contW;
  height: $contH;
  perspective: $prsp;
  transform-style: preserve-3d;
}
.surface {
  animation: spin $dur/2 ease-out, jerk $dur/25 $dur*0.92 linear;
  display: block;
  width: $sqSize * $xSpaces;
  height: $sqSize * $ySpaces;
  margin: auto;
  transform-style: preserve-3d;
  transform: translateY($sqSize * $zSpaces/3) rotateX($xAngle) rotateZ($zAngle);
  will-change: transform;
}
.block, .plate {
  display: none;
  transform-style: preserve-3d;
  position: absolute;
  bottom: 0;
}
.block-inner > div, .plate {
  width: $sqSize;
  height: $sqSize;
}
.block-inner > div {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  position: absolute;
  width: $sqSize;
  height: $sqSize;
  &.front, &.back, &.left, &.right {
    &:before {
      background-color: #000;
      content: "";
      width: 100%;
      height: 100%;
    }
  }
  &.front, &.back {
  &:before {
    opacity: 0.2;
  }
  }
  &.left, &.right {
    &:before {
      opacity: 0.4;
    }
  }
}
.block-outer, .block-inner {
  position: relative;
  width: $sqSize;
  transform-style: preserve-3d;
}
.block-inner {
  transform: rotateX(-90deg) translateZ($sqSize);
}
.back {
  transform: translateZ(-$sqSize) rotateY(180deg);
}
.left {
  transform-origin: center left;
  transform: rotateY(270deg) translateX(-$sqSize);
}
.right {
  transform-origin: top right;
}
.top, .bottom {
  transform-origin: top center;
}

// * Render blocks *
// one block only
@if length(nth($blocks,1)) == 1 {
  .b1 {
      @include placeBlock(
        nth($blocks, 1),
        nth($blocks, 2),
        nth($blocks, 3),
        nth($blocks, 4),
        nth($blocks, 5),
        nth($blocks, 6),
        nth($blocks, 7)
      );
    }
}
// more than one block
@else {
  @for $b from 1 through length($blocks) {
    .b#{$b} {
      @include placeBlock(
        nth(nth($blocks, $b), 1),
        nth(nth($blocks, $b), 2),
        nth(nth($blocks, $b), 3),
        nth(nth($blocks, $b), 4),
        nth(nth($blocks, $b), 5),
        nth(nth($blocks, $b), 6),
        nth(nth($blocks, $b), 7)
      );
    }
  }
}
// * Render plates *
// one plate only
@if length(nth($plates,1)) == 1 {
  .p1 {
    @include placePlate(
      nth($plates, 1),
      nth($plates, 2),
      nth($plates, 3),
      nth($plates, 4),
      nth($plates, 5),
      nth($plates, 6),
      nth($plates, 7),
      nth($plates, 8),
      nth($plates, 9),
      nth($plates, 10),
      nth($plates, 11)
    );
  }
}
// more than one plate
@else {
  @for $p from 1 through length($plates) {
    .p#{$p} {
      @include placePlate(
        nth(nth($plates, $p), 1),
        nth(nth($plates, $p), 2),
        nth(nth($plates, $p), 3),
        nth(nth($plates, $p), 4),
        nth(nth($plates, $p), 5),
        nth(nth($plates, $p), 6),
        nth(nth($plates, $p), 7),
        nth(nth($plates, $p), 8),
        nth(nth($plates, $p), 9),
        nth(nth($plates, $p), 10),
        nth(nth($plates, $p), 11)
      );
    }
  }
}
@for $a from 1 through 28 {
  .b#{$a} .block-outer {
    $argsFor17_28: ($dur/3 + $dur*0.02 * ($a - 9)) linear forwards;
    @if $a <= 16 {
      animation: b#{$a}Move $dur/2 ease-out;
    }
    @elseif $a <= 22 {
      animation: popOutLeft $dur/15 $argsFor17_28;
    }
    @else {
      animation: popOutFwd $dur/15 $argsFor17_28;
    }
    @if $a > 16 {
      visibility: hidden;
    }
  }
}
.block:nth-of-type(n + 29) .block-outer {
  animation: placeDown $dur/25 $dur*0.88 linear forwards;
  visibility: hidden;
  .block-inner div {
    animation: glow $dur/2 $dur*0.92 linear forwards;
  }
}
/* Animations */
@keyframes spin {
  from {
    transform: translateY($sqSize * $zSpaces/3) rotateX($xAngle) rotateZ($zAngle + 180) scale(0,0);
  }
  to {
    transform: translateY($sqSize * $zSpaces/3) rotateX($xAngle) rotateZ($zAngle) scale(1,1);
  }
}
@keyframes jerk {
  from, to {
    transform: translateY($sqSize * $zSpaces/3) rotateX($xAngle) rotateZ($zAngle);
  }
  50% {
    transform: translateY($sqSize * $zSpaces/3 + $sqSize/2) rotateX($xAngle) rotateZ($zAngle);
  }
}
@for $k from 1 through 16 {
  @keyframes b#{$k}Move {
    from {@include moveBlock(0,0,-$k)}
    to {@include moveBlock(0,0,0)}
  }
}
@keyframes popOutLeft {
  from {
    @include moveBlock(0,0,0);
    visibility: hidden;
  }
  50% {
    @include moveBlock(-0.25,0,0);
    visibility: visible;
  }
  to {
    @include moveBlock(0,0,0);
    visibility: visible;
  }
}
@keyframes popOutFwd {
  from {
    @include moveBlock(0,0,0);
    visibility: hidden;
  }
  50% {
    @include moveBlock(0,-0.25,0);
    visibility: visible;
  }
  to {
    @include moveBlock(0,0,0);
    visibility: visible;
  }
}
@keyframes placeDown {
  from {
    @include moveBlock(0,0,4);
    visibility: hidden;
  }
  to {
    @include moveBlock(0,0,0);
    visibility: visible;
  }
}
@keyframes glow {
  from, to { filter: brightness(1); }
  15%, 45% { filter: brightness(2); }
}
+1

Поделиться

Tags

  • bowtiesmilelaughingblushsmileyrelaxedsmirk
    heart_eyeskissing_heartkissing_closed_eyesflushedrelievedsatisfiedgrin
    winkstuck_out_tongue_winking_eyestuck_out_tongue_closed_eyesgrinningkissingstuck_out_tonguesleeping
    worriedfrowninganguishedopen_mouthgrimacingconfusedhushed
    expressionlessunamusedsweat_smilesweatdisappointed_relievedwearypensive
    disappointedconfoundedfearfulcold_sweatperseverecrysob
    joyastonishedscreamtired_faceangryragetriumph
    sleepyyummasksunglassesdizzy_faceimpsmiling_imp
    neutral_faceno_mouthinnocent
Человек быстро решит загадку пять умножить на пять и минус 25 ?

Редакторы выбирают

Web и Технологии