Maison >interface Web >tutoriel CSS >Création du logo DigitalOcean en 3D avec CSS

Création du logo DigitalOcean en 3D avec CSS

Joseph Gordon-Levitt
Joseph Gordon-Levittoriginal
2025-03-13 11:02:09401parcourir

Création du logo DigitalOcean en 3D avec CSS

Howdy y'all! À moins que vous ne viviez sous un rocher (et peut-être même à ce moment-là), vous avez sans aucun doute entendu la nouvelle que CSS-Tricks a été acquise par DigitalOcean. Félicitations à tout le monde! ?

En tant que petit hourra pour commémorer l'occasion, je voulais créer le logo DigitalOcean dans CSS. Je l'ai fait, mais je l'ai fait un peu plus loin avec un peu de 3D et de parallaxe. Cela fait également un assez bon article car la façon dont j'ai fait le logo utilise diverses pièces à partir d'articles précédents que j'ai écrits. Cette petite démo cool rassemble plusieurs de ces concepts.

Alors, plongeons-nous directement!

Création du logo DigitalOcean

Nous allons «tracer» le logo DigitalOcean en en prenant une version SVG de SimpleIcons.org.

 <svg role="img" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
  <title> DigitalOcean </title>
  <path d="M12.04 0C5.408-.02.005 5.37.005 11.992H4.638C0-4.923 4.882-8.731 10.064-6.855a6.95 6.95 0 014.147 4.148c1.889 5.177-1.924 10.055-6.84 10.064v-4.61h7.391v4.623h4.61v24c7.86 0 13.967-7.588 11.397-15.83-1.115-3.59-3.985-6.446-7.575-7.575a12.8 12.8 0 0012.039 0zm7.39 19.362H3.828V3.564H7.39ZM-3.563 0V-2.978H.85V2.978Z ">  Path>
</path></svg>

Étant conscient que nous prenons cette 3D, nous pouvons envelopper notre SVG dans un élément .Scène. Ensuite, nous pouvons utiliser la technique de traçage de mon article «Advanced CSS Illustrations». Nous utilisons PUG afin que nous puissions tirer parti de ses mixins et réduire la quantité de balisage que nous devons écrire pour la partie 3D.

 - Const Size = 40
.scène
  svg (role = 'img' Viewbox = '0 0 24 24' xmlns = 'http: //www.w3.org/2000/svg')
    Titre DigitalOcean
    PATH (D = 'M12.04 0C5.408-.02.005 5.37.005 11.992H4.638C0-4.923 4.882-8.731 10.064-6.855a6.95 6.95 0 014.147 4.148c1.889 5.177-1.924 10.055-6.84 10.064v-4.61h7.391v4.623h4.61v24c7.86 0 13.967-7.588 11.397-15.83-1.115-3.59-3.985-6.446-7.575-7.575a12.8 12.8 0 0012.039 0zm7.39 19.362H3.828V3.564H7.39ZM-3.563 0V-2.978H.85V2.978Z ')
  .logo (style = `--size: $ {size}`)
    .logo__arc.logo__arc - inter
    .logo__arc.logo__arc - Bouetter
    .logo__square.logo__square - un
    .logo__square.logo__square - deux
    .logo__square.logo__square - trois

L'idée est de coiffer ces éléments afin qu'ils chevauchent notre logo. Nous n'avons pas besoin de créer la partie «arc» du logo car nous pensons à l'avance parce que nous allons fabriquer ce logo en 3D et pouvons créer l'arc avec deux formes de cylindre. Cela signifie pour l'instant tout ce dont nous avons besoin, c'est des éléments de contenu pour chaque cylindre, l'arc intérieur et l'arc extérieur.

Découvrez cette démo qui présente les différentes pièces du logo DigitalOcean. Si vous basculez les éléments «exploser» et survolez, vous pouvez en quoi consiste le logo.

Si nous voulions un logo DigitalOcean plat, nous pourrions utiliser un masque CSS avec un gradient de conique. Ensuite, nous n'aurions besoin que d'un seul élément «arc» qui utilise une bordure solide.

 .logo__arc - Bouter {
  Border: calc (var (- taille) * 0,1925vmin) solide # 006Aff;
  Masque: gradient conique (transparent 0Deg 90Deg, # 000 90DEG);
  Transformer: traduire (-50%, -50%) Rotation (180 degrés);
}

Cela nous donnerait le logo. La «révélation» transit un chemin à clip qui montre l'image SVG tracé en dessous.

Consultez mon article «Conseils pour les illustrations CSS complexes» pour des conseils sur le travail avec des illustrations avancées dans CSS.

Extruder pour la 3D

Nous avons le plan pour notre logo DigitalOcean, il est donc temps de faire cette 3D. Pourquoi n'avons-nous pas créé des blocs 3D dès le départ? La création d'éléments contenant est plus facile de créer une 3D via l'extrusion.

Nous avons couvert la création de scènes 3D dans CSS dans mon article «Apprendre à penser en cubes au lieu des boîtes». Nous allons utiliser certaines de ces techniques pour ce que nous faisons ici. Commençons par les carrés du logo. Chaque carré est un cuboïde. Et en utilisant PUG, nous allons créer et utiliser un mélange cuboïde pour aider à les générer tous.

 Mélanger Cuboid ()
  .cuboid (classe! = attributs.class)
    Si Block
      bloc
    - Soit S = 0
    tandis que S <p> Ensuite, nous pouvons l'utiliser dans notre balisage:</p><pre rel="Pug" data-line=""> .scène
  .logo (style = `--size: $ {size}`)
    .logo__arc.logo__arc - inter
    .logo__arc.logo__arc - Bouetter
    .logo__square.logo__square - un
       cuboïde (). carré-cuboïde.square-cuboïde - un
    .logo__square.logo__square - deux
       cuboid (). carré-cuboïde.square-cuboïde - deux
    .logo__square.logo__square - trois
       cuboïde (). carré-cuboïde.square-cuboïde - trois

Ensuite, nous avons besoin des styles pour afficher nos cuboïdes. Notez que les cuboïdes ont six côtés, nous avons donc des styles de pseudo au nord de type () tout en tirant parti de l'unité de longueur VMIN pour garder les choses réactives.

 .cuboid {
  Largeur: 100%;
  hauteur: 100%;
  Position: relative;
}
.cuboid__side {
  filtre: luminosité (var (- b, 1));
  Position: absolue;
}
.cuboid__side: nth of-type (1) {
  --B: 1.1;
  hauteur: calc (var (- profondeur, 20) * 1vmin);
  Largeur: 100%;
  en haut: 0;
  Transformer: traduire (0, -50%) Rotatex (90Deg);
}
.cuboid__side: nth of-type (2) {
  --B: 0,9;
  hauteur: 100%;
  Largeur: calc (var (- profondeur, 20) * 1vmin);
  en haut: 50%;
  à droite: 0;
  Transformer: traduire (50%, -50%) Rotatey (90 degrés);
}
.cuboid__side: nth of-type (3) {
  --B: 0,5;
  Largeur: 100%;
  hauteur: calc (var (- profondeur, 20) * 1vmin);
  en bas: 0;
  Transformée: traduire (0%, 50%) Rotatex (90deg);
}
.cuboid__side: nth of-type (4) {
  --B: 1;
  hauteur: 100%;
  Largeur: calc (var (- profondeur, 20) * 1vmin);
  à gauche: 0;
  en haut: 50%;
  Transformer: traduire (-50%, -50%) Rotatey (90deg);
}
.cuboid__side: nth of-type (5) {
  --B: 0,8;
  hauteur: 100%;
  Largeur: 100%;
  Transform: tradlate3d (0, 0, calc (var (- profondeur, 20) * 0,5 Vmin));
  en haut: 0;
  à gauche: 0;
}
.cuboid__side: nth of-type (6) {
  --B: 1.2;
  hauteur: 100%;
  Largeur: 100%;
  Transform: tradlate3d (0, 0, calc (var (- profondeur, 20) * -0,5vmin)) Rotatey (180Deg);
  en haut: 0;
  à gauche: 0;
}

Nous abordons cela d'une manière différente de la façon dont nous l'avons fait dans les articles passés. Au lieu d'appliquer la hauteur, la largeur et la profondeur à un cuboïde, nous ne nous préoccupons que de sa profondeur. Et au lieu d'essayer de colorer chaque côté, nous pouvons utiliser le filtre: luminosité pour gérer cela pour nous.

Si vous avez besoin d'avoir des cuboïdes ou d'autres éléments 3D comme un enfant d'un côté à l'aide d'un filtre, vous devrez peut-être mélanger les choses. Un côté filtré aplatira tous les enfants 3D.

Le logo DigitalOcean a trois cuboïdes, nous avons donc un cours pour chacun et les styliser comme ceci:

 .Square-cuboid .cuboid__side {
  Contexte: HSL (var (- teinte), 100%, 50%);
}
.Square-cuboid - un {
  / * 0.1925? C'est un pourcentage de la taille de ce carré * /
  --pth: calc ((var (- taille) * 0,1925) * var (- profondeur-multiplicateur));
}
.Square-cuboid - deux {
  --pth: calc ((var (- taille) * 0,1475) * var (- profondeur-multiplicateur));
}
.Square-cuboid - trois {
  --pth: calc ((var (- taille) * 0,125) * var (- profondeur-multiplicateur));
}

… Ce qui nous donne quelque chose comme ceci:

Vous pouvez jouer avec le curseur de profondeur pour extruder les cuboïdes comme vous le souhaitez! Pour notre démo, nous avons choisi de fabriquer les cubes de cuboïdes avec une hauteur, une largeur et une profondeur égales. La profondeur de l'arc correspondra au plus grand cuboïde.

Maintenant pour les cylindres. L'idée est de créer deux extrémités qui utilisent le radius frontalier: 50%. Ensuite, nous pouvons utiliser de nombreux éléments comme côtés du cylindre pour créer l'effet. L'astuce est de positionner tous les côtés.

Nous pouvons adopter diverses approches pour créer les cylindres dans CSS. Mais, pour moi, si c'est quelque chose que je peux prévoir en utilisant plusieurs fois, je vais essayer de le faire à l'épreuve. Cela signifie faire un mixin et quelques styles que je peux réutiliser pour d'autres démos. Et ces styles devraient essayer de répondre aux scénarios que je pouvais voir apparaître. Pour un cylindre, il y a une configuration que nous pouvons vouloir considérer:

  • rayon
  • côtés
  • Combien de ces côtés sont affichés
  • Que ce soit pour montrer une ou les deux extrémités du cylindre

En assemblant cela, nous pouvons créer un mélange de carlin qui répond à ces besoins:

 Cylindre de mélange (rayon = 10, côtés = 10, coupé = [5, 10], haut = vrai, en bas = true)
  - const innerangle = (((côtés - 2) * 180) / côtés) * 0,5
  - const cosangle = math.cos (innerangle * (math.pi / 180))
  - constance const = 2 * rayon * math.cos (innerangle * (math.pi / 180))
  // - Utilisez la coupe pour déterminer combien de côtés sont rendus et de quel point
  .Cylinder (style = `- côté: $ {côté}; --sides: $ {côtés}; --radius: $ {radius};` class! = attributes.class)
    Si le haut
      .Cylinder__end.Cylinder__segment.Cylinder__end - au sommet
    Si en bas
      .Cylinder__end.Cylinder__segment.Cylinder__end - Bottom
    - const [start, fin] = coupe
    - Laissez i = démarrer
    Pendant que je finis
      .Cylinder__side.Cylinder__segment (style = `--Index: $ {i};`)
      - je

Voyez comment // - est admis au commentaire dans le code? Cela dit à Pug d'ignorer le commentaire et de le laisser de côté du balisage HTML compilé.

Pourquoi devons-nous passer le rayon dans le cylindre? Eh bien, malheureusement, nous ne pouvons pas tout à fait gérer la trigonométrie avec CSS calc () pour l'instant (mais ça arrive). Et nous devons déterminer des choses comme la largeur des côtés des cylindres et à quelle distance du centre qu'ils devraient projeter. La grande chose est que nous avons une belle façon de transmettre ces informations à nos styles via des propriétés personnalisées en ligne.

 .cylindre(
  style = `
    - côté: $ {côté};
    --sides: $ {côtés};
    --Radius: $ {rayon}; `
  classe! = attributs.class
)

Un exemple d'utilisation pour notre mixin serait le suivant:

 cylindre (20, 30, [10, 30])

Cela créerait un cylindre avec un rayon de 20, 30 côtés, où seuls les côtés de 10 à 30 sont rendus.

Ensuite, nous avons besoin de style. Le style des cylindres du logo DigitalOcean est assez simple, heureusement:

 .Cylinder {
  --BG: HSL (var (- teinte), 100%, 50%);
  Contexte: RGBA (255,43,0,0,5);
  hauteur: 100%;
  Largeur: 100%;
  Position: relative;
}
.Cylinder__ Segment {
  filtre: luminosité (var (- b, 1));
  Contexte: var (- bg, # e61919);
  Position: absolue;
  en haut: 50%;
  Gauche: 50%;
}
.Cylinder__end {
  --B: 1.2;
  - Fend-cofficient: 0,5;
  hauteur: 100%;
  Largeur: 100%;
  Border-Radius: 50%;
  Transform: tradlate3d (-50%, -50%, calc ((var (- profondeur, 0) * var (- fin-coefficient)) * 1VMIN));
}
.Cylinder__end - Bottom {
  --B: 0,8;
  - End-Coefficient: -0,5;
}
.Cylinder__side {
  --B: 0,9;
  hauteur: calc (var (- profondeur, 30) * 1vmin);
  Largeur: calc (var (- côté) * 1vmin);
  transformée: traduire (-50%, -50%) Rotatex (90Deg) Rotatey (calc ((var (- index, 0) * 360 / var (- côtés)) * 1deg)) tradate3d (50%, 0, calc (var (- rayon) * 1vmin));
}

L'idée est que nous créons tous les côtés du cylindre et les avons mis au milieu du cylindre. Ensuite, nous les faisons pivoter sur l'axe des y et les projetons à peu près à la distance du rayon.

Il n'est pas nécessaire de montrer les extrémités du cylindre dans la partie intérieure car ils sont déjà obscurcis. Mais nous devons les montrer pour la partie extérieure. Notre utilisation de mixin à deux cylindres ressemble à ceci:

 .logo (style = `--size: $ {size}`)
  .logo__arc.logo__arc - inter
     cylindre ((taille * 0,61) * 0,5, 80, [0, 60], faux, faux) .Cylinder-arc.linlinder-arc - inner
  .logo__arc.logo__arc - Bouetter
     cylindre ((taille * 1) * 0,5, 100, [0, 75], vrai, vrai) .Cylinder-arc.linlinder-arc - youter

Nous connaissons le rayon du diamètre que nous avons utilisé lors du traçage du logo plus tôt. De plus, nous pouvons utiliser les extrémités du cylindre extérieur pour créer les visages du logo DigitalOcean. Une combinaison de largeur des frontières et de trame de clip est utile ici.

 .Cylinder-arc - Youter .Cylinder__end - au sommet,
.Cylinder-arc - Youter .Cylinder__end - Bottom {
  / * En fonction du pourcentage de la taille nécessaire pour plafonner l'arc * /
  largeur de bordure: calc (var (- taille) * 0,1975vmin);
  Style de la frontière: solide;
  Color frontière: HSL (var (- teinte), 100%, 50%);
  - Clip: polygone (50% 0, 50% 50%, 0 50%, 0 100%, 100% 100%, 100% 0);
  Clip-path: var (- clip);
}

Nous sommes assez proches de l'endroit où nous voulons être!

Il manque cependant une chose: le plafonnement de l'arc. Nous devons créer des extrémités pour l'arc, qui nécessite deux éléments que nous pouvons positionner et tourner sur l'axe x ou y:

 .scène
  .logo (style = `--size: $ {size}`)
    .logo__arc.logo__arc - inter
       cylindre ((taille * 0,61) * 0,5, 80, [0, 60], faux, faux) .Cylinder-arc.linlinder-arc - inner
    .logo__arc.logo__arc - Bouetter
       cylindre ((taille * 1) * 0,5, 100, [0, 75], vrai, vrai) .Cylinder-arc.linlinder-arc - youter
    .logo__square.logo__square - un
       cuboïde (). carré-cuboïde.square-cuboïde - un
    .logo__square.logo__square - deux
       cuboid (). carré-cuboïde.square-cuboïde - deux
    .logo__square.logo__square - trois
       cuboïde (). carré-cuboïde.square-cuboïde - trois
    .logo__cap.logo__cap - au sommet
    .logo__cap.logo__cap - Bottom

Les extrémités plafonnées de l'arc supposeront la hauteur et la largeur en fonction de la valeur de la largeur des frontières de l'extrémité ainsi que de la profondeur de l'arc.

 .logo__cap {
  - Hue: 10;
  Position: absolue;
  Hauteur: calc (var (- taille) * 0,1925vmin);
  Largeur: calc (var (- taille) * 0,1975vmin);
  Contexte: HSL (var (- teinte), 100%, 50%);
}
.logo__cap - au sommet {
  en haut: 50%;
  à gauche: 0;
  Transformer: traduire (0, -50%) Rotatex (90Deg);
}
.logo__cap - Bottom {
  en bas: 0;
  à droite: 50%;
  Transformer: traduire (50%, 0) Rotatey (90deg);
  hauteur: calc (var (- taille) * 0,1975vmin);
  Largeur: calc (var (- taille) * 0,1925vmin);
}

Nous avons couronné l'arc!

Je mettant tout ensemble, nous avons notre logo DigitalOcean. Cette démo vous permet de le faire pivoter dans différentes directions.

Mais il y a encore un truc de plus dans notre manche!

Ajout d'un effet de parallaxe au logo

Nous avons notre logo 3D DigitalOcean, mais ce serait bien s'il était interactif d'une manière ou d'une autre. En novembre 2021, nous avons couvert comment créer un effet de parallaxe avec les propriétés personnalisées CSS. Utilisons cette même technique ici, l'idée étant que le logo tourne et se déplace en suivant le curseur de la souris d'un utilisateur.

Nous avons besoin d'une touche de JavaScript afin que nous puissions mettre à jour les propriétés personnalisées dont nous avons besoin pour un coefficient qui définit le mouvement du logo le long des axes X et Y dans le CSS. Ces coefficients sont calculés à partir de la position du pointeur d'un utilisateur. J'utiliserai souvent Greensock pour que je puisse utiliser gsap.utils.mapRange. Mais, voici une version JavaScript à la vanille qui implémente MapRange:

 const MapRange = (InputLower, InputUpper, OutputLower, OutputUpper) => {
  const INPUT_RANGE = InputUpper - InputLower
  const Output_Range = OutputUpper - OutputLower
  valeur de retour => outputLower (((valeur - inputLower) / input_range) * output_range || 0)
}

const Bounds = 100      
const update = ({x, y}) => {
  const pos_x = mapRange (0, window.innerwidth, -bounds, bounds) (x)
  const pos_y = mapRange (0, window.innerheight, -bounds, bounds) (y)
  document.body.style.setproperty ('- coefficient-x', pos_x)
  document.body.style.setproperty ('- coefficient-y', pos_y)
}

document.addeventListener ('Pointermove', mise à jour)

La magie se produit dans CSS-Land. Il s'agit de l'un des principaux avantages de l'utilisation de propriétés personnalisées de cette façon. JavaScript dit à CSS ce qui se passe avec l'interaction. Mais, cela ne se soucie pas de ce que CSS en fait. C'est un découplage rad. J'utilise cet extrait JavaScript dans tant de mes démos pour cette raison. Nous pouvons créer différentes expériences simplement en mettant à jour le CSS.

Comment faisons-nous cela? Utilisez Calc () et les propriétés personnalisées qui sont portée directement à l'élément .Scene. Considérez ces styles mis à jour pour .Scene:

 .scène {
  - rotation-y: 75deg;
  --rotation-x: -14deg;
  Transform: tradlate3d (0, 0, 100vmin)
    rotatex (-16deg)
    Rotatey (28deg)
    rotatex (calc (var (- coefficient-y, 0) * var (- rotation-x, 0deg))))
    Rotatey (calc (var (- coefficient-x, 0) * var (- rotation-y, 0deg)));
}

La scène tourne sur les axes x et y en fonction du mouvement du pointeur de l'utilisateur. Mais nous pouvons ajuster ce comportement en peaufinant les valeurs pour - rotation-x et - rotation-y.

Chaque cuboïde bougera sa propre voie. Ils sont capables de se déplacer sur l'axe x, y ou z. Mais, nous n'avons qu'à définir une seule transformation. Ensuite, nous pouvons utiliser des propriétés personnalisées dans les parasites pour faire le reste.

 .logo__square {
  Transform: tradlate3d (
    calc (min (0, var (- coefficient-x, 0) * var (- offset-x, 0)) * 1%),
    calc ((var (- coefficient-y) * var (- offset-y, 0)) * 1%),
    calc ((var (- coefficient-x) * var (- offset-z, 0)) * 1vmin)
  ));
}
.logo__square - un {
  --offset-x: 50;
  - Offset-y: 10;
  --offset-z: -2;
}
.logo__square - deux {
  --offset-x: -35;
  - Offset-y: -20;
  --offset-z: 4;
}
.logo__square - trois {
  --offset-x: 25;
  --Offset-y: 30;
  -Offset-z: -6;
}

Cela vous donnera quelque chose comme ceci:

Et nous pouvons les modifier au contenu de notre cœur jusqu'à ce que nous ayons quelque chose dont nous sommes satisfaits!

Ajout d'une animation d'intro au mélange

Ok, j'ai un peu frappé et j'ai une dernière (je promets!) La façon dont nous pouvons améliorer notre travail. Et si nous avions une sorte d'animation d'intro? Que diriez-vous d'une vague ou de quelque chose qui se lave et révèle le logo?

Nous pourrions le faire avec les pseudo-éléments de l'élément corporel:

 :racine {
  - Hue: 215;
  - du retard initial: 1;
  - Vérification de l'onde: 2;
}

corps: après,
corps: avant {
  contenu: '';
  Position: absolue;
  Hauteur: 100VH;
  Largeur: 100 VW;
  Contexte: HSL (var (- Hue), 100%, calc (var (- légèreté, 50) * 1%));
  transformée: traduire (100%, 0);
  nom d'animation: wave;
  Durée d'animation: calc (var (- wave-speed) * 1s);
  Animation-retard: calc (var (- deLay initial) * 1s);
  Animation-TIMing-Function: facilité;
}
corps: avant {
  - Lightness: 85;
  Animation-TIMing-Function: Facit-Out;
}
@keyframes wave {
  depuis {
    Transform: traduire (-100%, 0);
  }
}

Maintenant, l'idée est que le logo DigitalOcean est caché jusqu'à ce que la vague s'envole. Pour cet effet, nous allons animer nos éléments 3D d'une opacité de 0. Et nous allons animer tous les côtés à nos éléments 3D d'une luminosité de 1 pour révéler le logo. Parce que la couleur de l'onde correspond à celle du logo, nous ne le verrons pas s'estomper. De plus, en utilisant le mode de remplissage d'animation: les deux signifie que nos éléments étendront le style de nos images clés dans les deux sens.

Cela nécessite une forme de calendrier d'animation. Et c'est là que les propriétés personnalisées entrent en jeu. Nous pouvons utiliser la durée de nos animations pour calculer les retards des autres. Nous avons examiné cela dans ma baisse de «comment faire un pur pack CSS 3D» et des articles «animés de poupées matryoshka dans CSS».

 :racine {
  - Hue: 215;
  - du retard initial: 1;
  - Vérification de l'onde: 2;
  - Fade-Speed: 0,5;
  - Viltre-vitesse: 1;
}

.Cylinder__ Segment,
.cuboid__side,
.logo__cap {
  nom d'animation: fondu, filtre-in;
  Durée d'animation: calc (var (- fondu fade) * 1s),
    calc (var (- filtre-vitesse) * 1s);
  Animation-délay: calc ((var (- initial-delay) var (- wave-speed)) * 0,75s),
    calc ((var (- deLay initial) var (- wave-speed)) * 1.15s);
  Mode de remplissage d'animation: les deux;
}

@KeyFrames Filter-in {
  depuis {
    Filtre: luminosité (1);
  }
}

@KeyFrames Fade-in {
  depuis {
    Opacité: 0;
  }
}

Comment pouvons-nous obtenir le timing correctement? Un peu de bricolage et de l'utilisation de «l'inspecteur d'animations» dans Devtool de Chrome va beaucoup. Essayez d'ajuster les horaires dans cette démo:

Vous pouvez constater que le timing de fondu n'est pas nécessaire si vous voulez que le logo soit là une fois que la vague est passée. Dans ce cas, essayez de régler le fondu 0. Et en particulier, expérimentez les coefficients du filtre et de la fondu. Ils se rapportent aux 0,75 et 1,15 à partir du code ci-dessus. Cela vaut la peine d'ajuster les choses et de jouer dans l'inspecteur de l'animation de Chrome pour voir comment les choses sont dans le temps.

C'est ça!

En me réunissant, nous avons cette intro soignée pour notre logo 3D DigitalOcean!

Et, bien sûr, cette seule approche pour créer le logo DigitalOcean en 3D avec CSS. Si vous voyez d'autres possibilités ou peut-être quelque chose qui peut être optimisé davantage, déposez un lien vers votre démo dans les commentaires!

Félicitations, encore une fois, à l'équipe CSS-Tricks et à DigitalOcean pour leur nouveau partenariat. Je suis ravi de voir où les choses vont avec l'acquisition. Une chose est sûre: CSS-Tricks continuera d'inspirer et de produire un contenu fantastique pour la communauté. ?

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn