عندما كنت أتصفح CSSDesignAwards، وجدت تأثيرًا يقسم محتوى الصورة (موقع الويب: https://weareludwig.com، يمكنك النقر عليه لإلقاء نظرة عليه. لقد كان رائعًا جدًا، لذلك حاولت تنفيذه بنفسي). وكان التأثير جيدًا. تحقق من التأثير https://codepen.io/geeknoble/pen/OQaOVG
تحليلأولا نجد أن محتوى الصورة مقسم إلى مستطيلات صغيرة، ويتم ترجمة كل مستطيل بشكل عشوائي. يمكن لوظيفة drawImage في Canvas قص محتوى الصورة ورسمها في لوحة Canvas، لذا فإن مبدأ التنفيذ الرئيسي لهذا التأثير هو استخدام drawImage. هناك تأثيران رئيسيان، أحدهما تعطيل محتوى الصورة واستعادته، والآخر هو التبديل إلى الصورة التالية. ويمكن استخدام DrawImage لكلا التأثيرين، لكن مسافة الحركة مختلفة. بمجرد حصولك على الفكرة العامة، يمكنك البدء في تنفيذها.
العمل الأولينحتاج أولاً إلى تهيئة بعض المتغيرات، مثل عرض الصورة وارتفاعها، وعدد المستطيلات، وحجم القطع، وما إلى ذلك، ثم حساب إحداثيات كل مستطيل، واستخدام حلقة مزدوجة لحفظ إحداثيات المستطيل في البيانات. كل مستطيل لديه إزاحة عشوائية، ويجب أيضًا حفظ هذه الإزاحة بشكل عشوائي. من بينها، x وy يمثلان إحداثيات لوحة القماش، ويمثل x1 وy1 إحداثيات اقتصاص الصورة.
init: function (context, width, height, Area, img) { this.context = context; this.img = img; this.imgWidth = img[0].width; // عرض الصورة وارتفاعها this.imgHeight = img[ 0 ].height; this.index = 0; // رقم الصورة الحالية this.width = width; // عرض القماش وارتفاعه this.height = height; // طول المستطيل الصغير this.countX = width / this.area; // عدد المستطيلات الصغيرة في الاتجاهين الأفقي والرأسي this.countY = height / this.area; .countX; // عرض الصورة وارتفاعها في المستطيل الصغير this.wy = this.imgHeight / this.countY; حالة الإحداثيات، صحيح يعني عدم إضافة قيمة عشوائية لهذه المدة = 1000; // وقت الرسوم المتحركة this.duration2 = 1500; this.startTime = 0; // معلومات إحداثيات مستطيل صغير this.randoms = []; // تهيئة إحداثيات المستطيل var x1 = 0, y1 = 0, x = 0, y = 0; for (var i = 0; i < this.countY; i++) { for (var j = 0; j < this.countX; j++) { context.drawImage(this.img[this.index], x1, y1, this.wx, this.wy, x, y, this.area, this.area); this.data.push({ x1: x1, y1: y1, x: x, y: y }); // أضف قيم عشوائية this.randoms.push(random(-this.area, this.area)); wy; x = 0; y += this.area;كشف الحواف
قبل إضافة إزاحة إلى المستطيل، نحتاج إلى تحديد ما إذا كانت الإحداثيات المُزاحة تتجاوز حد الصورة، على سبيل المثال، إذا كان المستطيل الموجود في الأعلى يتحرك على المحور الصادي، فيمكنه التحرك للأعلى فقط الإحداثي الحالي بالإضافة إلى قيمة الإزاحة أقل من 0 أو أكبر من عرض الصورة وارتفاعها. إذا كانت الإحداثيات المحدثة أقل من 0، فيجب أن تكون القيمة العشوائية رقمًا سالبًا، وتحتاج إلى تغيير القيمة العشوائية إلى رقم موجب، وإذا كانت أكبر من ارتفاع الصورة، فقم بتغييرها إلى رقم سالب. وبما أن كل مستطيل يتحرك في اتجاه واحد، أكتب هنا أن البتات ذات الأرقام الزوجية تحرك المحور السيني والبتات ذات الأرقام الفردية تحرك المحور الصادي.
// كشف حافة checkMargin: function () { var self = this; this.data.forEach(function (item, Index) { if (index % 2 == 0) { // انقل المحور السيني عندما يكون الفهرس مضاعف 2، وإلا قم بتحريك المحور y if (item.x1 + self.randoms[index] < 0) // التغيير إلى رقم موجب self.randoms[index] = -self.randoms[index]; .x1 + self.wx + self.randoms[index] > self.imgWidth ) // التغيير إلى الرقم السلبي self.randoms[index] = -Math.abs(self.randoms[index]) } else { if (item.y1 + self Randoms[index] < 0) self.randoms[index] = -self.randoms[index]; if (item.y1 + self.randoms[index] + self.wy > self.imgHeight) self.randoms[index] = -Math.abs(self.randoms[index]) } }) }الانفصال والانتعاش
فصل محتوى الرسوم المتحركة واستعادته هو تحديث قيمة الإحداثيات المستطيلة لتعطيل المحتوى، ما عليك سوى إضافة قيم عشوائية إلى الإحداثيات في البيانات، والاستعادة هي طرح القيم العشوائية.
// كشف حافة checkMargin: function () { var self = this; this.data.forEach(function (item, Index) { if (index % 2 == 0) { // انقل المحور السيني عندما يكون الفهرس مضاعف 2، وإلا قم بتحريك المحور y if (item.x1 + self.randoms[index] < 0) // التغيير إلى رقم موجب self.randoms[index] = -self.randoms[index]; .x1 + self.wx + self.randoms[index] > self.imgWidth ) // التغيير إلى الرقم السلبي self.randoms[index] = -Math.abs(self.randoms[index]) } else { if (item.y1 + self Randoms[index] < 0) self.randoms[index] = -self.randoms[index]; if (item.y1 + self.randoms[index] + self.wy > self.imgHeight) self.randoms[index] = -Math.abs(self.randoms[index]) } }) }
بعد تخزين الإحداثيات، يمكنك تنفيذ الرسوم المتحركة للترجمة. تتميز عملية الحركة بانتقال سلس. يمكننا استخدام خوارزمية التخفيف الخاصة بـ Tween.js. تحتوي هذه الخوارزمية على 4 معلمات: الوقت الحالي، والموقع الأولي، والموقع النهائي. وقت الرسوم المتحركة. للحصول على التفاصيل، يرجى الرجوع إلى مقالة Zhang Xinxu https://www.zhangxinxu.com/wordpress/2016/12/how-use-tween-js-animation-easing/. يمكن استخدام Tween.js لحساب مسافة التحرك في كل إطار، ثم استخدام requestAnimationFrame لتحديث الإحداثيات.
blockAnimation: function () { var flag = 1; if (this.state) { // تحديد ما إذا كان سيتم تعطيل الصورة أو استعادتها this.update(true) } else { flag = -1; } var self = this; this.startTime = +new Date(); // احصل على الوقت الحالي this.state = !this.state; >= self.startTime + self.duration) { // شرط نهاية الرسوم المتحركة return false; } self.data.forEach(function (item, Index) { if (index % 2 == 0) { var pos = Math.tween.Expo. easyInOut(t - self.startTime, 0, self.randoms[index] * flag, self.duration); احسب المسافة المنقولة في كل إطار self.context.drawImage(self.img[self.index], item.x1 + pos, item.y1, self.wx, self.wy, item.x, item.y, self. Area, self.area); } else { var pos = Math.tween.Expo.easeInOut(t - self.startTime, 0, self.randoms[index] * flag, self.duration); self.context.drawImage(self.img[self.index], item.x1, item.y1 + pos, self.wx, self.wy, item.x, item.y, self.area, self.area); } });
في هذه المرحلة، تم تنفيذ الرسوم المتحركة للفصل والاستعادة.
تبديل الصورةبعد ذلك، نبدأ في معالجة جزء تبديل الصورة، وهذا يشبه إلى حد ما الصورة الدائرية. تعمل الرسوم المتحركة للصورة الدائرية على تحريك موضع كل صورة حسب عرض النافذة المرئية الارتفاع لتحقيق y التبديل على المحور. تختلف عن الصورة الدائرية، لدينا علامة قماش واحدة فقط هنا عند التبديل، نحتاج فقط إلى تغيير إحداثيات الصورة الحالية والصورة التالية، ومسافة الحركة للصورة الحالية هي y1 + pos الصورة التالية هي y1 + pos - imgHeight (غني عن القول لماذا يجب تقليل imgHeight).
// الرسوم المتحركة المنزلقة عموديًا: function (val) { if (!this.time2) { return false } this.checkTime(2); مرر لأعلى أو لأسفل if ((this.index + val) < 0 || (this.index + val) >= (this.img.length)) { // تحديد ما إذا كان الرقم التسلسلي للصورة هو النهاية return false } this.state this.update(true) : this.update(false); this.startTime = +new Date(); (function Animation() { var t = +new Date(); if (t >= self.startTime + self .duration2) { val === 1 ? self.index++ : self.index--; // ضبط ترتيب الصور self.index < 0 ? self.index = self.img.length - 1 : self.index self .الفهرس >= self.img.length ? self.index = 0 : self.index; return false; } self.data.forEach(function (item) { var pos = Math.tween.Cubic.easeInOut(t - self.startTime, 0, (self.imgHeight) * val, self.duration2); // تحديث إحداثيات الصورة الحالية self.context.drawImage(self.img[self.index], item.x1, item.y1 + pos, self.wx, self.wy, item.x, item.y, self.area, self.area); // تحديث إحداثيات الصورة التالية self.context.drawImage(self.img[] self.index + val], item.x1, item.y1 + pos - self.imgHeight * val, self.wx, self.wy, item.x, item.y, self.area, self.area); }); requestAnimationFrame(animation })() });
وينطبق الشيء نفسه على تبديل المحور السيني. والآن أصبحت جميع الوظائف مكتملة تقريبًا.
ما ورد أعلاه هو المحتوى الكامل لهذه المقالة وآمل أن يكون مفيدًا لدراسة الجميع وآمل أيضًا أن يدعم الجميع شبكة VeVb Wulin.