كيفية عمل رسوم متحركة جميلة مشفرة للويب باستخدام Mo.JS

كيفية عمل رسوم متحركة جميلة مشفرة للويب باستخدام Mo.JS

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





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





سننظر اليوم في mo.js ، أحد الأطفال الجدد في المنطقة لإنشاء صور جميلة من التعليمات البرمجية. سنغطي بعض الوظائف الأساسية ، قبل إنشاء سلسلة رسوم متحركة تفاعلية للمستخدم تخلق أنماطًا جميلة.





أدخل Mo.js

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

قبل أن نذهب إلى أبعد من ذلك ، دعنا نلقي نظرة على ما سننشئه اليوم:



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

قم بإعداد قلم جديد ، وسيتم استقبالك بهذه الشاشة:





قبل أن نبدأ ، ستحتاج إلى إجراء بعض التغييرات. اضغط على إعدادات أعلى اليسار ، وانتقل إلى ملف جافا سكريبت التبويب.

سوف نستخدم بابل كمعالج مسبق للرمز الخاص بنا ، لذا حدد هذا من القائمة المنسدلة. يجعل Babel JavaScript أسهل قليلاً في الفهم ، إلى جانب توفير ECMAScript 6 دعم المتصفحات القديمة. إذا كنت لا تعرف ماذا يعني ذلك ، لا تقلق ، ستجعل حياتنا أسهل قليلاً هنا.





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

مع هذين الأمرين في مكانهما ، انقر فوق احفظ وأغلق . نحن جاهزون للبدء!

الأشكال الأساسية مع Mo.js

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

body{
background: rgba(11,11,11,1);
}

يعد إنشاء الشكل عملية بسيطة ، والمفهوم الكامن وراءه يقود المكتبة بأكملها. لنقم بإعداد شكل دائرة افتراضي. أدخل هذا الرمز في شبيبة خبز:

const redCirc = new mojs.Shape({
isShowStart:true
});

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

حتى الآن لم نمر بأي معايير باستثناء isShowStart: صحيح ، مما يعني أنه سيظهر على الشاشة حتى قبل أن نخصص له أي حركة. ستلاحظ أنها وضعت دائرة وردية في وسط الشاشة:

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

const redCirc = new mojs.Shape({
isShowStart:true,
shape:'rect'
});

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

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

أساسيات الحركة

للحصول على شيء يبدو أكثر إثارة للإعجاب ، دعنا ننشئ دائرة ، بضربة حمراء حولها ولا توجد تعبئة بالداخل.

const redCirc = new mojs.Shape({
isShowStart:true,
stroke:'red',
strokeWidth:5,
fill:'none',
radius:15
});

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

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

radius: {15:30},
opacity: {1:0},
duration:1000

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

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

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

الطلب والتخفيف مع Mo.js

الآن ، بمجرد ظهور الدائرة تبدأ في التلاشي. سيعمل هذا بشكل جيد تمامًا ، ولكن سيكون من الجيد أن يكون لديك المزيد من التحكم.

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

const redCirc = new mojs.Shape({
isShowStart:true,
stroke:'red',
strokeWidth:5,
fill:'none',
radius: 15,
duration:1000
}).then({
//do more stuff here
}).play();

الآن ، سيظهر شكلنا مع القيم التي قمنا بتعيينها له ، انتظر 1000 مللي ثانية ، قبل تنفيذ أي شيء نضعه في .من ثم() وظيفة. دعنا نضيف بعض التعليمات بين القوسين:

//do more stuff here
strokeWidth: 0,
scale: { 1: 2, easing: 'sin.in' },
duration: 500

يقدم هذا الرمز جزءًا مهمًا آخر من الرسوم المتحركة. حيث وجهنا تعليمات مقياس للتغيير من 1 إلى 2 ، قمنا أيضًا بتعيين التسهيل القائم على الموجة الجيبية بـ الخطيئة . يحتوي Mo.js على مجموعة متنوعة من منحنيات التسهيل المضمنة ، مع قدرة المستخدمين المتقدمين على إضافة منحنياتهم الخاصة. في هذه الحالة ، يحدث المقياس بمرور الوقت وفقًا لموجة جيبية تنحني لأعلى.

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

الأشكال هي أساس كل شيء في Mo.js ، لكنها ليست سوى بداية القصة. دعنا ننظر إلى رشقات نارية .

انفجار مع الإمكانات في Mo.js

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

const sparks = new mojs.Burst({
}).play();

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

const sparks = new mojs.Burst({
radius: {0:30, easing:'cubic.out'},
angle:{0: 90,easing:'quad.out'},
}).play();

لقد أضفنا بالفعل نصف قطر مخصص ودوران إلى انفجارنا:

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

const sparks = new mojs.Burst({
radius: {0:30, easing:'cubic.out'},
angle:{0: 90,easing:'quad.out'},
count:50,
children:{
shape: 'cross',
stroke: 'white',
points: 12,
radius:10,
fill:'none',
angle:{0:360},
duration:300
}
}).play();

ستلاحظ أن الخصائص الفرعية هي نفس خصائص الشكل التي عملنا معها بالفعل. هذه المرة اخترنا صليبًا ليكون الشكل. كل هذه الأشكال الخمسين لها نفس الخصائص الآن. لقد بدأت تبدو جيدة جدًا! هذا هو أول شيء يراه المستخدم عند النقر بالماوس.

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

نحن بعيدون عن الانتهاء من الرسوم المتحركة الخاصة بنا ، ولكن دعونا نتوقف لحظة لجعلها تفاعلية مع المستخدم.

الحدث الرئيسي

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

document.addEventListener( 'click', function(e) {
});

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

document.addEventListener( 'click', function(e) {
redCirc
.tune({ x: e.pageX, y: e.pageY, })
.replay();
sparks
.tune({ x: e.pageX, y: e.pageY })
.replay();
});

الوظيفتان اللتان نسميهما هنا هما .نغم() و .replay () . تشبه وظيفة إعادة التشغيل وظيفة التشغيل ، على الرغم من أنها تحدد أن الرسوم المتحركة يجب أن تبدأ مرة أخرى من البداية في كل مرة يتم النقر عليها.

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

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

شكلنا وانفجار لهما .لعب() في نهاية كتل التعليمات البرمجية الخاصة بهم. لم نعد بحاجة إلى هذا أكثر من ذلك .replay () يتم استدعاؤه في معالج الحدث. يمكنك إزالة .play () من كلا كتلي التعليمات البرمجية. لنفس السبب ، يمكنك إزالة isShowStart: صحيح أيضًا ، لأننا لم نعد بحاجة إلى إظهاره في البداية.

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

left: 0,
top: 0,

الآن قيم الموضع الوحيدة التي تأخذها كائناتنا هي قيم موضع الماوس التي تم تمريرها بواسطة مستمع الحدث. الآن يجب أن تعمل الأشياء بشكل أفضل.

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

الحصول على مخدر

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

const triangles = new mojs.Burst({
radius: { 0 : 1000,easing: 'cubic.out'},
angle: {1080 : 0,easing: 'quad.out'},
left: 0, top: 0,
count: 20,
children : {
shape: 'polygon',
points: 3,
radius: { 10 : 100 },
fill: ['red','yellow','blue','green'],
duration: 3000
}
});

يجب أن يكون كل شيء هنا مألوفًا إلى حد ما الآن ، على الرغم من وجود نقطتين جديدتين. ستلاحظ أنه بدلاً من تعريف الشكل على أنه مثلث ، فقد أطلقنا عليه اسم a مضلع قبل تعيين عدد نقاط لديها 3.

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

إذا كانت الشفرة لا تعمل من أجلك ، فتأكد من إضافة كائن المثلثات إلى فئة مستمع الأحداث كما فعلنا مع الكائنات السابقة.

مخدر جدا! دعونا نضيف انفجارًا آخر لمتابعته.

الرقص الخماسي

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

const pentagons = new mojs.Burst({
radius: { 0 : 1000,easing: 'cubic.out'},
angle: {0 : 720,easing: 'quad.out'},
left: 0, top: 0,
count: 20,
children : {
shape: 'polygon',
radius: { 1 : 300 },
points: 5,
fill: ['purple','pink','yellow','green'],
delay:500,
duration: 3000
}
});

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

القليل من العشوائية

دعنا نضيف تأثيرًا يستخدم القيم العشوائية. أنشئ انفجارًا بهذه الخصائص:

const redSparks = new mojs.Burst({
left: 0, top: 0,
count:8,
radius: { 150: 350 },
angle: {0:90 ,easing:'cubic.out'},
children: {
shape: 'line',
stroke: {'red':'transparent'},
strokeWidth: 5,
scaleX: {0.5:0},
degreeShift: 'rand(-90, 90)',
radius: 'rand(20, 300)',
duration: 500,
delay: 'rand(0, 150)',
}
});

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

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

هذا هو التأثير في حد ذاته:

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

redSparks
.tune({ x: e.pageX, y: e.pageY })
.replay()
.generate();

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

يمكنك استخدام قيم عشوائية لكل عنصر تقريبًا من عناصر كائنات mo.js ، وهي طريقة بسيطة لإنشاء رسوم متحركة فريدة.

كيفية زيادة سرعة تنزيل التورنت

ومع ذلك ، فإن العشوائية ليست هي الطريقة الوحيدة لإضافة حركات ديناميكية إلى الرسوم المتحركة. لنلقِ نظرة على ملف ترنح وظيفة.

خطوط مذهلة

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

const lines = new mojs.Burst({
radius: { 0 : 1000,easing: 'cubic.out'},
angle: {0 : 1440,easing: 'cubic.out'},
left: 0, top: 0,
count: 50,
children : {
shape: 'line',
radius: { 1 : 100,easing:'elastic.out' },
fill: 'none',
stroke: ['red','orange'],
delay:'stagger(10)',
duration: 1000
}
});

كل شيء هنا مألوف الآن ، انفجار يخلق 50 طفلاً بخطوط حمراء أو برتقالية. الاختلاف هنا هو أننا نجتاز تأخير الملكية أ ستاجر (10) وظيفة. هذا يضيف 10 مللي ثانية من التأخير بين انبعاث كل طفل ، مما يمنحه تأثير الدوران الذي نبحث عنه.

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

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

المربعات الذكية

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

const redSquares = new mojs.Burst({
radius: { 0 : 1000,easing: 'cubic.out'},
angle: {360 : 0,easing: 'quad.out'},
left: 0, top: 0,
count: 20,
children : {
shape: 'rect',
radiusX: { 1 : 1000 },
radiusY:50,
points: 5,
fill: 'none',
stroke: {'red':'orange'},
strokeWidth:{5:15},
delay:1000,
duration: 3000
}
});

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

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

مع إضافة هذا الكائن النهائي ، لقد انتهينا. دعونا نرى كل شيء في العمل.

Mo.js: أداة قوية للرسوم المتحركة على الويب

تغطي هذه المقدمة البسيطة إلى mo.js الأدوات الأساسية اللازمة لإنشاء رسوم متحركة جميلة. يمكن للطريقة التي يتم بها استخدام هذه الأدوات إنشاء أي شيء تقريبًا ، وبالنسبة للعديد من المهام ، تعد مكتبات الويب بديلاً بسيطًا للاستخدام محل تصوير أو After Effects أو برامج أخرى مكلفة.

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

يشارك يشارك سقسقة بريد الالكتروني هل يستحق الترقية إلى Windows 11؟

تم إعادة تصميم Windows. لكن هل هذا كافٍ لإقناعك بالانتقال من Windows 10 إلى Windows 11؟

اقرأ التالي
مواضيع ذات صلة
  • برمجة
  • جافا سكريبت
نبذة عن الكاتب إيان باكلي(216 مقالة منشورة)

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

المزيد من Ian Buckley

اشترك في نشرتنا الإخبارية

انضم إلى النشرة الإخبارية لدينا للحصول على نصائح تقنية ومراجعات وكتب إلكترونية مجانية وصفقات حصرية!

انقر هنا للاشتراك