في هذه المقالة سنوضح لك كيفية إنشاء مكعب ثلاثي الأبعاد باستخدام CSS، مع صورة مرفقة بكل وجه من أوجه. وبعدها ستتمكن من تدوير المكعب وتسويته بحيث يظهر كل وجه وصورته المتطابقة.
نعمل بشكل أساسي على إنشاء معرض صور من نوع مختلف حيث يتم تمثيل الصور كوجوه المكعب في الفضاء على هيئة ثلاثية الأبعاد. هذا ما ستتمكن من إنشاؤه بعد قراءة هذه المقالة.
يستوعب المكعب ما يصل إلى 6 صور مختلفة على كل جانب من جوانبها، والنقر المزدوج على أي منها سيؤدي إلى إظهار المكب بشكل مسطح، مما يعطي النتيجة التالية للصور المنتشرة بجوار بعضها البعض:
دعونا نتذكر بسرعة محاور نظام الإحداثيات الديكارتية ثلاثي الأبعاد:
نظام الإحداثيات الديكارتية لمساحة ثلاثية الأبعاد هو ثلاثة أعمدة مرتبة من الخطوط (المحاور) التي تكون متعامدة. ولها وحدة طول واحدة لجميع المحاور الثلاثة ولها اتجاه لكل محور- ويكيبيديا
يمثل المحور X المحور الأفقي، والمحور y هو المحور الرأسي ، ويفترض أن يكون المحور z خارجًا من الشاشة باتجاهك.
كل الأعمال التي تتعلق بالدوران تعتمد على هذه المحاور، لذا استمتع بمزيد من التفاصيل إذا كنت ترغب في ذلك.
يحتوي كل وجه من المكعب على عنصر HTML خاص به
<div>
مع اسم الفئة المعين لها والذي يتوافق مع:
cube-top, cube-bottom, cube-left
مع فئة أخرى للمكعب، حيث أننا نحتاج إلى تدويرها معاً ككل.
تتضمن حاوية المكعب متعددة الأبعاد أيضًا على مجمّع أساسي خاص بها من غلاف المكعب فئة:
cube-wrapper.
<div class="cube-wrapper">
<div class="cube">
<div class="cube-top"></div>
<div class="cube-bottom"></div>
<div class="cube-left"></div>
<div class="cube-right"></div>
<div class="cube-front"></div>
<div class="cube-back"></div>
</div>
</div>
إرفاق صورة لكل جانب من جوانب المكعب أمر سهل. سنستخدم CSS للصورة الخلفية لتعيين صورة كل وجه من أوجه المكعب.
<div class="cube-wrapper">
<div class="cube">
<div class="cube-top" style="background-image: url('')"></div>
<div class="cube-bottom" style="background-image: url('')"></div>
<div class="cube-left" style="background-image: url('')"></div>
<div class="cube-right" style="background-image: url('')"></div>
<div class="cube-front" style="background-image: url('')"></div>
<div class="cube-back" style="background-image: url('')"></div>
</div>
</div>
ببساطة إضافة مسار للصورة داخل أقواس URL.
أولًا،نحتاج إلى إعداد عنص
.cube-wrapper
الخارجي. الذي يلف المكعب والأوجه الخاصة به، ليعمل بمثابة منصة للمكعب. نستخدم خاصية CSS Perspective لمنحها العمق المطلوب. يمكنك قراءة كيفية عمل المنظور بشكل صحيح على موقع MDN الإلكتروني.
.cube-wrapper {
position: relative;
height: 200px;
width: 200px;
margin: 100px;
perspective: 1000px;
}
سيكون عرض المكعب 200 بكسل، وسنمنحه موضعًا نسبيًا، لذا سيكون كل وجه مرتبطًا به. سوف نمنح المكعب نمط تحويل ثلاثي الأبعاد للحفاظ على المكعب في النموذج الثلاثي الأبعاد، وإلا سيتم عرض محتوياته كصور مسطحة.
.cube {
position: relative;
width: 200px;
transform-style: preserve-3d;
transform-origin: 100px 100px;
}
للحصول على مظهر ثلاثي الأبعاد للمكعب، نحتاج إلى وضع كل وجه وفقًا لذلك في موضعه المناسب. إن فهم كل من نظام الإحداثيات الديكارتية وطريقة عمله في CSS سيقطع شوطا طويلا في فهم هذه الخطوة.
.cube-top { -webkit-transform: translate3d(0, -100px, 0) rotateX(90deg); transform: translate3d(0, -100px, 0) rotateX(90deg); } .cube-bottom { -webkit-transform: translate3d(0, 100px, 0) rotateX(90deg); transform: translate3d(0, 100px, 0) rotateX(90deg); } .cube-left { -webkit-transform: translate3d(-100px, 0, 0) rotateY(90deg); transform: translate3d(-100px, 0, 0) rotateY(90deg); } .cube-right { -webkit-transform: translate3d(100px, 0, 0) rotateY(-90deg); transform: translate3d(100px, 0, 0) rotateY(-90deg); } .cube-front { -webkit-transform: translate3d(0, 0, 100px) rotateY(0); transform: translate3d(0, 0, 100px) rotateY(0); } .cube-back { -webkit-transform: translate3d(0, 0, -100px) rotateY(-180deg); transform: translate3d(0, 0, -100px) rotateY(-180deg); }
ملاحظة: ترتيب العمليتين مهم هنا، وهذا بسبب طبيعة عمل المصفوفات المضاعفة.
let el = null;
let wrapper = null;
let currentX = 0;
let currentY = 0;
let rorateX = 0;
let rotateY = 0;
let opened = false;
function Cube(selector) {
el = document.querySelector(element);
_initData();
_initEvents();
}
function _initData() {
wrapper = el.parentNode;
el.style.transform = 'translate3d(0, 0, 0) rotateX(-200deg) rotateY(45deg)'
}
الآن نقوم بتعريف الدالة الخاصة بنا لتهيئة listener لحدث السحب عندما نضغط باستمرار على زر الماوس الأيسر على أحد وجوه المكعب. ستقوم الدالة أيضًا بتعيين قيم الإحداثيات x و y التي تم النقر فوقها إلى المتغيرات الخاصة بها.
ونحصل أيضًا على قيم التدوير من خلال التعبير العادي. لاحظ أنه كان علينا تحليل ما يقوم RegEx بإرجاعه كرقم، لأنه يقوم بإرجاع سلسلة بشكل افتراضي.
function _initEvents() {
el.addEventListener('mousedown', (event) => {
event.preventDefault();
currentX = event.clientX;
currentY = event.clientY;
rotateX = Number(el.style.transform.match(/rotateX\((-?[0-9]+(\.[0-9])?)*deg\)/)[1]);
rotateY = Number(el.style.transform.match(/rotateY\((-?[0-9]+(\.[0-9])?)*deg\)/)[1]);
document.addEventListener('mousemove', drag);
document.addEventListener('mouseup', release)
});
e.addEventListener('dblclick', open);
}
function drag(event) {
let draggedX = (event.clientX - currentX);
let draggedY = (event.clientY - currentY);
// check if the left mouse button is clicked
if(event.buttons !== 1) return;
el.style.transform = `rotateX(${rotateX - (draggedY / 2)}deg) rotateY(${rotateY + (draggedX / 2)}deg)`;
}
function release(event) {
document.removeEventListener('mousemove', drag);
document.removeEventListener('mouseup', release);
}
سنقوم بتعريف فئة لحالة المكعب المسطح. باستخدام التحويلات المناسبة، يمكننا تقديم كل جانب من المكعب بجانب الآخر:
.cube.is-opened {
animation: none;
opacity: 1;
transform: translate3d(0, 0, 0) rotateY(0deg) rotateX(0deg) !important;
}
.cube.is-opened .cube-top {
transform: translate3d(-550px, 0, 0) rotateX(0);
}
.cube.is-opened .cube-bottom {
transform: translate3d(-550px, 0, 0) rotateX(0);
}
.cube.is-opened .cube-left {
transform: translate3d(-330px, 0, 0) rotateY(0);
}
.cube.is-opened .cube-right {
transform: translate3d(330px, 0, 0) rotateY(0);
}
.cube.is-opened .cube-front {
transform: translate3d(110px, 0, 0) rotateY(0);
}
.cube.is-opened .cube-back {
transform: translate3d(-110px, 0, 0) rotateY(0);
}