إنشاء مطبعة CSS ثلاثية الأبعاد تقوم بالطباعة فعلًا!

لفترة من الزمان، كنت أقوم بإنشاء مشاهد ثلاثية الأبعاد باستخدام CSS للمتعة — عادةً على بثي المباشر.

كل تجربة هي فرصة لتجربة شيء مختلف أو العمل على إيجاد طرق للقيام بأشياء باستخدام CSS. ما أفعله غالبًا هو اتخاذ اقتراحات حول ما يجب أن نحاول صنعه في البث. اقتراح آخر كان طابعة تطبع بـ “3D”. وها هي ما جمعته!

صنع الأشياء 3D باستخدام CSS

I’ve written about making things 3D with CSS before. The general gist is that most scenes are a composition of cuboids.

لصنع مكعب، يمكننا استخدام تحولات CSS لتحديد جوانب المكعب — الخاصية السحرية هي transform-style. تحديد هذا إلى preserve-3d يسمح لنا بتحويل العناصر في البعد الثالث:

* {
  transform-style: preserve-3d;
}

بمجرد إنشاء عدة من هذه المشاهد، تبدأ في التقاط طرق لتسريع الأمور. أحب استخدام Pug كما تحويل HTML. قدرة المزيج تمكنني من إنشاء المكعبات بشكل أسرع. تستخدم أمثلة الترميز في هذا المقال Pug. ولكل مثال CodePen يمكنك استخدام خيار “عرض الترميز المجمع” لرؤية الإخراج HTML:

mixin cuboid()
  .cuboid(class!=attributes.class)
    - let s = 0
    while s < 6
      .cuboid__side
      - s++

استخدام +cuboid()(class="printer__top") سينتج هذا:

<div class="cuboid printer__top">
  <div class="cuboid__side"></div>
  <div class="cuboid__side"></div>
  <div class="cuboid__side"></div>
  <div class="cuboid__side"></div>
  <div class="cuboid__side"></div>
  <div class="cuboid__side"></div>
</div>

ثم لدي مجموعة محددة من CSS التي أستخدمها لتنظيم المكعبات. الفرح هنا هو أنه يمكننا تحقيق CSS الخصائص المUSTومية لتحديد خصائص المكعب (كما هو موضح في الفيديو أعلاه):

.cuboid {
  // Defaults
  --width: 15;
  --height: 10;
  --depth: 4;
  height: calc(var(--depth) * 1vmin);
  width: calc(var(--width) * 1vmin);
  transform-style: preserve-3d;
  position: absolute;
  font-size: 1rem;
  transform: translate3d(0, 0, 5vmin);
}
.cuboid > div:nth-of-type(1) {
  height: calc(var(--height) * 1vmin);
  width: 100%;
  transform-origin: 50% 50%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotateX(-90deg) translate3d(0, 0, calc((var(--depth) / 2) * 1vmin));
}
.cuboid > div:nth-of-type(2) {
  height: calc(var(--height) * 1vmin);
  width: 100%;
  transform-origin: 50% 50%;
  transform: translate(-50%, -50%) rotateX(-90deg) rotateY(180deg) translate3d(0, 0, calc((var(--depth) / 2) * 1vmin));
  position: absolute;
  top: 50%;
  left: 50%;
}
.cuboid > div:nth-of-type(3) {
  height: calc(var(--height) * 1vmin);
  width: calc(var(--depth) * 1vmin);
  transform: translate(-50%, -50%) rotateX(-90deg) rotateY(90deg) translate3d(0, 0, calc((var(--width) / 2) * 1vmin));
  position: absolute;
  top: 50%;
  left: 50%;
}
.cuboid > div:nth-of-type(4) {
  height: calc(var(--height) * 1vmin);
  width: calc(var(--depth) * 1vmin);
  transform: translate(-50%, -50%) rotateX(-90deg) rotateY(-90deg) translate3d(0, 0, calc((var(--width) / 2) * 1vmin));
  position: absolute;
  top: 50%;
  left: 50%;
}
.cuboid > div:nth-of-type(5) {
  height: calc(var(--depth) * 1vmin);
  width: calc(var(--width) * 1vmin);
  transform: translate(-50%, -50%) translate3d(0, 0, calc((var(--height) / 2) * 1vmin));
  position: absolute;
  top: 50%;
  left: 50%;
}
.cuboid > div:nth-of-type(6) {
  height: calc(var(--depth) * 1vmin);
  width: calc(var(--width) * 1vmin);
  transform: translate(-50%, -50%) translate3d(0, 0, calc((var(--height) / 2) * -1vmin)) rotateX(180deg);
  position: absolute;
  top: 50%;
  left: 50%;
}

باستخدام الخصائص المUSTومية، يمكننا التحكم في صفات مختلفة للمكعبات، وهكذا:

  • --width: عرض المكعب على الطائرة
  • --height: ارتفاع المكعب على الطائرة
  • --depth: عمق المكعب على الطائرة
  • --x: الموضع X على الطائرة
  • --y: الموضع Y على الطائرة

هذا ليس مثيرًا للإعجاب حتى نضع المكعب في مشهد ونديره. مرة أخرى، أستخدم الخصائص المUSTومية للتلاعب بالمشهد أثناء العمل على صنع شيء ما. Dat.GUI يأتي هنا بشكل ممتاز.

إذا تفحصت العرض التوضيحي، باستخدام لوحة التحكم تتحديث الخصائص المUSTومية CSS على المشهد. هذا التحديث المUSTومي للخصائص المUSTومية CSS يوفر الكثير من الترميز المتكرر ويحافظ على جدوى التطبيق.

أكثر من طريقة واحدة

تمامًا مثل العديد من الأشياء في CSS، هناك أكثر من طريقة واحدة لفعلها. غالبًا ما يمكنك تكوين مشهد من المكعبات وتحديد مواقع الأشياء حسب الحاجة. قد يصبح الأمر صعب الإدارة على الرغم من ذلك. غالبًا ما يكون هناك حاجة لتجميع الأشياء أو إضافة نوع من الحاويات.

فكر في هذا المثال حيث الكرسي هو مشهد فرعي خاص به يمكن نقله.

العديد من الأمثلة الأخيرة ليست بهذه التعقيد. لقد كنت أستخدم الانفصال. هذا يعني أنه يمكنني تعيين أي شيء أقوم به باستخدام العناصر ثنائية الأبعاد. على سبيل المثال، إليك مروحية قمت بإنشائها مؤخرًا:

.helicopter
  .helicopter__rotor
  .helicopter__cockpit
    .helicopter__base-light
    .helicopter__chair
      .helicopter__chair-back
      .helicopter__chair-bottom
    .helicopter__dashboard
  .helicopter__tail
  .helicopter__fin
    .helicopter__triblade
    .helicopter__tail-light
  .helicopter__stabilizer
  .helicopter__skids
    .helicopter__skid--left.helicopter__skid
    .helicopter__skid--right.helicopter__skid
  .helicopter__wing
    .helicopter__wing-light.helicopter__wing-light--left
    .helicopter__wing-light.helicopter__wing-light--right
  .helicopter__launchers
    .helicopter__launcher.helicopter__launcher--left
    .helicopter__launcher.helicopter__launcher--right
  .helicopter__blades

ثم يمكننا إسقاط المكعبات في جميع الحاويات باستخدام الميكسين. ثم تطبيق “السماكة” المطلوبة على كل مكعب. تُحدد السماكة من قبل الخصائص المUSTOM المحلية. يتم تبديل هذا العرض التوضيحي --thickness الخاصة بالمكعبات التي تكون المروحية. يعطي فكرة عن ما كان يبدو عليه الرسم الثنائي المبدئي.

هذه هي جوهر كيفية عمل الأشياء ثلاثية الأبعاد باستخدام CSS. التعمق في الكود سيكشف بالتأكيد بعض الحيل. ولكن، بشكل عام، ابن مشهدًا، استيعاب المكعبات، وصبغ المكعبات. غالبًا ما ترغب في بعض الظلال المختلفة للألوان حتى نتمكن من تمييز جوانب المكعب. أي تفاصيل إضافية هي إما الأشياء التي يمكننا إضافتها إلى جانب المكعب أو التحولات التي يمكن تطبيقها على المكعب. على سبيل المثال، التناوب والتحرك على المحور Z.

دعونا نفكر في مثال مبسط:

.scene
  .extrusion
    +cuboid()(class="extrusion__cuboid")

يمكن أن يبدو ال CSS الجديد لإنشاء مكعب باستخدام الانفصال هكذا. لاحظ كيف ندمج الخصائص المUSTOM المحلية للون كل جانب كذلك. سيكون من الحكمة إسقاط بعض القيم الافتراضية تحت :root هنا أو القيم المتداخلة:

.cuboid {
  width: 100%;
  height: 100%;
  position: relative;
}
.cuboid__side:nth-of-type(1) {
  background: var(--shade-one);
  height: calc(var(--thickness) * 1vmin);
  width: 100%;
  position: absolute;
  top: 0;
  transform: translate(0, -50%) rotateX(90deg);
}
.cuboid__side:nth-of-type(2) {
  background: var(--shade-two);
  height: 100%;
  width: calc(var(--thickness) * 1vmin);
  position: absolute;
  top: 50%;
  right: 0;
  transform: translate(50%, -50%) rotateY(90deg);
}
.cuboid__side:nth-of-type(3) {
  background: var(--shade-three);
  width: 100%;
  height: calc(var(--thickness) * 1vmin);
  position: absolute;
  bottom: 0;
  transform: translate(0%, 50%) rotateX(90deg);
}
.cuboid__side:nth-of-type(4) {
  background: var(--shade-two);
  height: 100%;
  width: calc(var(--thickness) * 1vmin);
  position: absolute;
  left: 0;
  top: 50%;
  transform: translate(-50%, -50%) rotateY(90deg);
}
.cuboid__side:nth-of-type(5) {
  background: var(--shade-three);
  height: 100%;
  width: 100%;
  transform: translate3d(0, 0, calc(var(--thickness) * 0.5vmin));
  position: absolute;
  top: 0;
  left: 0;
}
.cuboid__side:nth-of-type(6) {
  background: var(--shade-one);
  height: 100%;
  width: 100%;
  transform: translate3d(0, 0, calc(var(--thickness) * -0.5vmin)) rotateY(180deg);
  position: absolute;
  top: 0;
  left: 0;
}

اخترنا ثلاثة ألوان لهذا المثال. ولكن في بعض الأحيان قد تحتاج إلى المزيد. يجمع هذا العرض التوضيحي ذلك معاً ويسمح لك بتغيير الخصائص المUSTOM المألوفة. قيمة “السماكة” ستغير استضاءة المكعب. ستؤثر التحولات والأبعاد على العنصر المحتوي بالفئة “استضاءة”.

تأسيس طابعة

للبدء، يمكننا تأسيس جميع القطع التي نحتاجها. مع الممارسة تصبح الأمور أكثر وضوحًا. ولكن القاعدة العامة هي محاولة تصور كل شيء كصناديق. وهذا يمنحك فكرة جيدة عن كيفية تفكيك شيء ما:

.scene
  .printer
    .printer__side.printer__side--left
    .printer__side.printer__side--right
    .printer__tray.printer__tray--bottom
    .printer__tray.printer__tray--top
    .printer__top
    .printer__back

معرفة ما إذا كان بإمكانك تصور ما نأمل الوصول إليه هنا. تترك القطعتان الجانبيتان فجوة في الوسط. ثم لدينا مكعب يقع على الجزء العلوي وواحد يملأ الخلف. ثم مكعبان لتشكيل صحن الورق.

بمجرد وصولك إلى هذه المرحلة، يأتي الأمر في مجموعة المكعبات، والتي تبدو هكذا:

.scene
  .printer
    .printer__side.printer__side--left
      +cuboid()(class="cuboid--side")
    .printer__side.printer__side--right
      +cuboid()(class="cuboid--side")
    .printer__tray.printer__tray--bottom
      +cuboid()(class="cuboid--tray")
    .printer__tray.printer__tray--top
      +cuboid()(class="cuboid--tray")
    .printer__top
      +cuboid()(class="cuboid--top")
    .printer__back
      +cuboid()(class="cuboid--back")      

لاحظ كيف نتمكن من إعادة استخدام أسماء الفئات مثل cuboid--side. من المحتمل أن تكون هذه المكعبات بنفس السماكة واستخدام نفس الألوان. تحدد موضعها وحجمها العنصر المحتوي.

من خلال تجميعها معًا، يمكننا الحصول على شيء مثل هذا.

تفجير العرض التوضيحي يظهر المكعبات المختلفة التي تشكل الطابعة. إذا قمت بإيقاف تشغيل الاستضاءة، يمكنك رؤية العناصر المحتوية بشكل مسطح.

إضافة بعض التفاصيل

الآن، ربما لاحظت أن هناك المزيد من التفاصيل مما قد تحصل عليه ببساطة عن طريق إضافة الألوان إلى كل جانب. وهذا يعود إلى إيجاد طرق لإضافة تفاصيل إضافية. لدينا خيارات مختلفة اعتمادًا على ما نريد إضافته.

إذا كانت صورة أو بعض التغييرات الأساسية في الألوان، يمكننا استخدام background-image لتكديس التدرجات، وما إلى ذلك.

على سبيل المثال، الجزء العلوي من الطابعة يحتوي على تفاصيل، وكذلك فتحة الطابعة. هذا الكود يعالج الجانب العلوي من المكعب العلوي. يتعامل التدرج مع فتحة الطابعة والتفاصيل:

.cuboid--top {
  --thickness: var(--depth);
  --shade-one: linear-gradient(#292929, #292929) 100% 50%/14% 54% no-repeat, linear-gradient(var(--p-7), var(--p-7)) 40% 50%/12% 32% no-repeat, linear-gradient(var(--p-7), var(--p-7)) 30% 50%/2% 12% no-repeat, linear-gradient(var(--p-3), var(--p-3)) 0% 50%/66% 50% no-repeat, var(--p-1);
}

بالنسبة لشعار الدب، يمكننا استخدام background-image أو حتى استدعاء عنصر شبه عنصر وتحديد موضعه:

.cuboid--top > div:nth-of-type(1):after {
  content: '';
  position: absolute;
  top: 7%;
  left: 10%;
  height: calc(var(--depth) * 0.12vmin);
  width: calc(var(--depth) * 0.12vmin);
  background: url("https://assets.codepen.io/605876/avatar.png");
  background-size: cover;
  transform: rotate(90deg);
  filter: grayscale(0.5);
}

إذا احتجنا لإضافة تفاصيل أكثر شمولاً، سنحتاج على الأرجح للخروج من استخدام ميكسين المكعب. على سبيل المثال، الجزء العلوي من طابعتنا سيحتوي على شاشة استعراض باستخدام عنصر img:

.printer__top
  .cuboid.cuboid--top
    .cuboid__side
    .cuboid__side
    .cuboid__side
    .cuboid__side
      .screen
        .screen__preview
          img.screen__preview-img
    .cuboid__side
    .cuboid__side

أضف بعض التفاصيل الإضافية ونحن على استعداد لوضع بعض الورق في المزيج!

رحلة الورق

ما هي الطابعة بدون بعض الورق؟ نريد تحريك بعض الأوراق التي تطير إلى الطابعة وتُطلق من الطرف الآخر. شيء مثل هذا العرض: انقر فوق أي مكان لرؤية قطعة من الورق تغادر الطابعة وتطبع.

يمكننا إضافة كتلة من الورق إلى المشهد باستخدام مكعب ومن ثم استخدام عنصر منفصل لتصرفه كورقة واحدة:

.paper-stack.paper-stack--bottom
  +cuboid()(class="cuboid--paper")
.paper-stack.paper-stack--top
  .cuboid.cuboid--paper
    .cuboid__side
      .paper
        .paper__flyer
    .cuboid__side
    .cuboid__side
    .cuboid__side
    .cuboid__side
    .cuboid__side

لكن تحريك الورق الطائر إلى الطابعة يتطلب بعض التجارب والأخطاء. من الحكمة أن تلعب مع تحولات مختلفة في مفتش DevTools. هذه طريقة جيدة لرؤية كيف ستبدو الأشياء. غالباً، من الأسهل استخدام عناصر التفريغ أيضاً. نستخدم عنصر .paper لإجراء النقل ثم نستخدم .paper__flyer لتحريك تغذية الورق:

:root {
  --load-speed: 2;
}

.paper-stack--top .cuboid--paper .paper {
  animation: transfer calc(var(--load-speed) * 0.5s) ease-in-out forwards;
}
.paper-stack--top .cuboid--paper .paper__flyer {
  animation: fly calc(var(--load-speed) * 0.5s) ease-in-out forwards;
}
.paper-stack--top .cuboid--paper .paper__flyer:after {
  animation: feed calc(var(--load-speed) * 0.5s) calc(var(--load-speed) * 0.5s) forwards;
}

@keyframes transfer {
  to {
    transform: translate(0, -270%) rotate(22deg);
  }
}

@keyframes feed {
  to {
    transform: translate(100%, 0);
  }
}

@keyframes fly {
  0% {
    transform: translate3d(0, 0, 0) rotateY(0deg) translate(0, 0);
  }
  50% {
    transform: translate3d(140%, 0, calc(var(--height) * 1.2)) rotateY(-75deg) translate(180%, 0);
  }
  100% {
    transform: translate3d(140%, 0, var(--height)) rotateY(-75deg) translate(0%, 0) rotate(-180deg);
  }
}

ستلاحظ أن هناك استخدامًا كبيرًا من calc في هذا الجزء. لتكوين جدول زمني للرسم المتحرك، يمكننا استخدام خصائص CSS المخصصة. بالرجوع إلى هذه الخاصية، يمكننا حساب التأخيرات الصحيحة لكل رسم متحرك في السلسلة. تنقلب وتطير الورقة في نفس الوقت. رسم متحرك واحد يتعامل مع تحريك الحاوية، وآخر يتعامل مع تدوير الورقة. بمجرد انتهاء هذين الرسمين المتحركين، تُغادر الورقة الطابعة مع رسم المتحرك feed. تكون مدة التأخير للرسم المتحرك مساوية لمدة الرسوم المتحركة الأولى التي تعمل في نفس الوقت.

قم بتشغيل هذه التجربة حيث لونت عناصر الحاوية بالأحمر والأخضر. نستخدم .paper__flyer العنصر الوهمي لتمثيل قطعة الورق. لكن عناصر الحاوية هي التي تقوم بالعمل الجاد:

قد تتساءل عن موعد خروج الورقة من الطرف الآخر. ولكن، في الواقع، الورقة ليست نفس العنصر طوال الوقت. نستخدم عنصرًا واحدًا لدخول الطابعة. وعنصر آخر للورقة عندما تطير من الطابعة. هذه حالة أخرى تجعل حياتنا أسهل بوجود عناصر إضافية.

تستخدم الورقة أكثر من عنصر لإكمال الحلقة، ثم يتم تحديد موضع الورقة على حافة ذلك العنصر. تشغيل هذه التجربة مع المزيد من عناصر الحاوية الملونة توضح كيفية عملها.

مرة أخرى، يتطلب ذلك بعض التجارب والأخطاء، وكذلك التفكير في كيف يمكننا تحقيق أقصى استفادة من استخدام عناصر الحاوية. وجود حاوية بـ transform-origin مُتأرجح يتيح لنا إنشاء الحلقة.

الطباعة

لدينا كل شيء مستأنف. الآن يأتي الوقت لطباعة شيئ ما. لفعل ذلك، سنضيف نموذجًا يتيح للمستخدمين إرسال عنوان URL لصورة:

form.customer-form
  label(for="print") Print URL
  input#print(type='url' required placeholder="URL for Printing")
  input(type="submit" value="Print")

بتصميم بسيط، نحصل على شيء كهذا.

السلوك الطبيعي للنماذج واستخدام الكود required و type="url" يعني أننا نقبل فقط عناوين URL. يمكننا تطوير هذا باستخدام pattern والتحقق من أنواع الصور معينة. ولكن بعض الروابط العشوائية للصور لا تشمل نوع الصور، مثل https://source.unsplash.com/random.

إرسال نموذجنا لا يتصرف كما نريد، وأيضًا يعمل الرسم المتحرك للطباعة مرة واحدة عند التحميل. طريقة للتغلب على هذا هي تشغيل الرسم المتحرك فقط عندما يتم تطبيق فئة معينة على الطابعة.

عندما نرسل النموذج، يمكننا إجراء طلب للحصول على الرابط ومن ثم تعيين src للصور في مشهدنا – صورة واحدة هي المعاينة المرئية على الطابعة، والأخرى هي صورة على جانب واحد من الورق. في الواقع، عندما نطبع، سنضيف عنصرًا جديدًا لكل قطعة من الورق المطبوعة. بهذه الطريقة، يبدو أن كل طبعة يتم إضافتها إلى كومة. يمكننا إزالة قطعة الورق التي لدينا عند التحميل.

لنبدأ بالتعامل مع تقديم النموذج. سنمنع الحدث الافتراضي وندعو دالة PROCESS:

const PRINT = e => {
  e.preventDefault()
  PROCESS()
}

const PRINT_FORM = document.querySelector('form')
PRINT_FORM.addEventListener('submit', PRINT)

ستتعامل هذه الدالة مع إجراء الطلب لمصدر صورتنا:

let printing = false

const PREVIEW = document.querySelector('img.screen__preview-img')
const SUBMIT = document.querySelector('[type="submit"]')
const URL_INPUT = document.querySelector('[type="url"]')

const PROCESS = async () => {
  if (printing) return
  printing = true
  SUBMIT.disabled = true
  const res = await fetch(URL_INPUT.value)
  PREVIEW.src = res.url
  URL_INPUT.value = ''
}

كما حددنا متغير printing بقيمة true، والذي سنستخدمه لتتبع الحالة الحالية، وتعطيل زر النموذج.

لماذا نطلب الصورة بدلاً من تحديدها على الصورة؟ نريد عنوان URL مطلق لصورة. إذا استخدمنا عنوان “Unsplash” الذي ذكرناه أعلاه، ومن ثم نشاركه بين الصور، قد لا ينجح هذا. وذلك لأننا قد نواجه سيناريوهات تظهر فيها صور مختلفة.

بمجرد أن نحصل على مصدر الصورة، نقوم بتعيين مصدر الصورة المعاينة إلى ذلك الرابط وإعادة تعيين قيمة الإدخال في النموذج.

لتشغيل الرسوم المتحركة، يمكننا التوصيل بحدث “load” للصورة المعاينة لدينا. عندما يتم تنفيذ الحدث، نقوم بإنشاء عنصر جديد لقطعة الورق للطباعة ونضيفه إلى عنصر printer. وفي الوقت نفسه، نضيف فئة printing إلى طابعتنا. يمكننا استخدام هذا لتشغيل الجزء الأول من رسوم الورق المتحركة:

PREVIEW.addEventListener('load', () => {
  PRINTER.classList.add('printing')
  const PRINT = document.createElement('div')
  PRINT.className = 'printed'
  PRINT.innerHTML = `
    <div class="printed__spinner">
      <div class="printed__paper">
        <div class="printed__papiere">
          <img class="printed__image" src=${PREVIEW.src}/>
        </div>
      </div>
      <div class="printed__paper-back"></div>
    </div>
  `
  PRINTER.appendChild(PRINT)
  // بعد فترة معينة نعيد تعيين الحالة
  setTimeout(() => {
    printing = false
    SUBMIT.removeAttribute('disabled')
    PRINTER.classList.remove('printing')
  }, 4500)
})

بعد فترة معينة، يمكننا إعادة تعيين الحالة. طريقة بديلة هي تأخير حدث animationend تصاعدي. لكن يمكننا استخدام setTimeout، حيث نعرف مدة الرسوم المتحركة.

لكن طباعتنا ليست بالمقياس الصحيح. وذلك لأننا بحاجة إلى تكبير الصورة إلى قطعة الورق. نحتاج إلى قطعة صغيرة من CSS لهذا:

.printed__image {
  height: 100%;
  width: 100%;
  object-fit: cover;
}

سيكون من الجميل أيضًا إذا كانت الأضواء أمام الطابعة تشير إلى أن الطابعة مشغولة. يمكننا تعديل ألوان إحدى الأضواء عندما تكون الطابعة تعمل:

.progress-light {
  background: hsla(var(--progress-hue, 104), 80%, 50%);
}
.printing {
  --progress-hue: 10; /* يعادل اللون الأحمر */
}

قم بتجميع كل ذلك وحصلنا على طابعة “عاملة” مصنوعة من CSS والقليل من JavaScript.

هذا كل شيء!

لقد قمنا بإلقاء نظرة على كيف يمكننا صنع طابعة 3D عاملة مستخدمين CSS والقليل من JavaScript، وتحقيق ذلك من خلال Pug. جرب إضافة رابط الصورة التالية في حقل الرابط، أو أي رابط آخر تفضله، وجربها!

https://source.unsplash.com/random

شرحنا العديد من الأشياء المختلفة لتحقيق هذا، منها:

  • كيفية صنع أشياء ثلاثية الأبعاد باستخدام CSS
  • استخدام ميكانيزمات Pug
  • استخدام خصائص CSS مخصصة ذات مجال محدد لإبقاء الأمور جافة
  • استخدام التمدد لإنشاء مشاهد ثلاثية الأبعاد
  • التعامل مع النماذج باستخدام JavaScript
  • تكوين جداول التحريك باستخدام خصائص مخصصة

متعة إنشاء هذه التوضيحات هي أن العديد منها تصيب بمشاكل مختلفة يجب التغلب عليها، مثل كيفية إنشاء أشكال معينة أو تشكيل تحريكات معينة. غالبًا ما يكون هناك أكثر من طريقة واحدة لفعل شيء ما.

ما الأشياء الرائعة التي يمكنك صنعها باستخدام CSS ثلاثي الأبعاد؟ أحب أن أرى!

كالعادة، شكرًا للقراءة. هل تريد رؤية المزيد؟ تواصل معي على تويتر أو تفقد بثي المباشر!

الأسئلة الشائعة (FAQs) حول طابعة CSS ثلاثية الأبعاد

ما هي طابعة CSS ثلاثية الأبعاد؟

A 3D CSS Printer is a unique concept that uses Cascading Style Sheets (CSS), a style sheet language used for describing the look and formatting of a document written in HTML, to create a 3D representation of a printer. This innovative approach allows developers to create interactive and visually appealing web elements that can enhance user experience.

كيف تعمل طابعة CSS ثلاثية الأبعاد؟

A 3D CSS Printer works by using CSS properties to create a 3D model of a printer. It uses properties such as transform, perspective, and animation to create the 3D effect. The printer is made up of multiple elements, each styled and positioned to create the overall 3D effect. The animation property is then used to create the printing effect.

هل يمكنني تخصيص طابعة CSS ثلاثية الأبعاد؟

نعم، يمكنك تخصيص الطابعة الثلاثية الأبعاد باستخدام CSS. يمكنك تغيير الألوان، الحجم، وحتى سرعة التحريك. يتم ذلك عن طريق تعديل خصائص CSS لعناصر الطابعة. على سبيل المثال، يمكنك تغيير اللون عن طريق تعديل خاصية background-color لعناصر الطابعة.

كيف يمكنني دمج طابعة CSS ثلاثية الأبعاد في موقعي؟

دمج طابعة CSS ثلاثية الأبعاد في موقعك يتضمن نسخ رمز CSS و HTML إلى رمز موقعك. تحتاج إلى التأكد من أن رمز CSS مدرج في قسم head من مستند HTML الخاص بك، ويتم وضع الرمز HTML في المكان الذي ترغب في ظهور الطابعة في صفحة الويب الخاصة بك.

هل من الممكن تحريك طابعة CSS ثلاثية الأبعاد؟

نعم، من الممكن تحريك طابعة CSS ثلاثية الأبعاد. يتم تحقيق التحريك باستخدام خاصية CSS animation. تسمح لك هذه الخاصية بإنشاء إطارات رئيسية تحدد الحالات الأولى والأخيرة للتحريك، وكذلك أي خطوات متوسطة.

ما المتصفحات التي تدعم طابعة CSS ثلاثية الأبعاد؟

يجب أن تعمل طابعة CSS ثلاثية الأبعاد على جميع المتصفحات الحديثة التي تدعم خصائص CSS transform و animation. يشمل ذلك المتصفحات مثل Google Chrome، Mozilla Firefox، Safari، و Microsoft Edge.

هل يمكنني استخدام طابعة CSS ثلاثية الأبعاد لأغراض تجارية؟

نعم، يمكنك استخدام طابعة CSS ثلاثية الأبعاد لأغراض تجارية. ومع ذلك، من الجيد دائمًا التحقق من شروط الترخيص لأي رمز تستخدمه للتأكد من أنك تتوافق.

ما المهارات التي أحتاجها لإنشاء طابعة CSS ثلاثية الأبعاد؟

لإنشاء طابعة CSS ثلاثية الأبعاد، تحتاج إلى فهم جيد للـ HTML و CSS. يجب أن تكون على دراية بخصائص CSS مثل transform، perspective، و animation. المعرفة الأساسية بالنمذجة الثلاثية قد تكون مفيدة كذلك، ولكنها ليست ضرورية.

هل يمكنني استخدام JavaScript مع طابعة CSS ثلاثية الأبعاد؟

نعم، يمكنك استخدام JavaScript مع طابعة CSS ثلاثية الأبعاد. على الرغم من أن الطابعة يمكن إنشاؤها باستخدام فقط CSS، إلا أن JavaScript يمكن استخدامه لإضافة التفاعلية، مثل بدء أو إيقاف الرسم المتحرك بناءً على إجراءات المستخدم.

هل هناك موارد لمعرفة المزيد عن طابعة CSS ثلاثية الأبعاد؟

هناك العديد من الموارد على الإنترنت لمعرفة المزيد عن طابعة CSS ثلاثية الأبعاد. المواقع مثل SitePoint، CSS-Tricks، و MDN Web Docs توفر دروساً وإرشادات شاملة حول الرسوم المتحركة في CSS والتحولات ثلاثية الأبعاد. كما أن YouTube يحتوي على العديد من الدروس الفيديو في هذا الموضوع.

Source:
https://www.sitepoint.com/3d-css-printer/