تأثير تحوم خيالي للصورة الرمزية الخاصة بك

تأثير تحوم خيالي للصورة الرمزية الخاصة بك

هل تعرف هذا النوع من التأثير حيث يبرز رأس شخص ما في دائرة أو ثقب؟ إن الرسوم المتحركة الشهيرة Porky Pig حيث يلوح وداعًا أثناء الخروج من سلسلة من الحلقات الحمراء هي المثال المثالي ، و قام كيليان فالكهوف بإعادة إنشاء ذلك هنا على CSS-Tricks منذ فترة.

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

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

HTML: عنصر واحد فقط

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

<img src="" alt="">

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

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

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

تأثير تحويم رائع لذكاء بيانات الصورة الرمزية PlatoBlockchain. البحث العمودي. منظمة العفو الدولية.
صمم بواسطة cang

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

قبل القفز إلى CSS ، دعنا أولاً نحلل التأثير. تصبح الصورة أكبر عند التمرير ، لذلك سنستخدمها بالتأكيد transform: scale() هناك. هناك دائرة خلف الصورة الرمزية ، ويجب أن يؤدي التدرج اللوني الشعاعي إلى الحل. أخيرًا ، نحتاج إلى طريقة لإنشاء حد في أسفل الدائرة يخلق مظهر الصورة الرمزية خلف الدائرة.

لنبدأ العمل!

تأثير المقياس

لنبدأ بإضافة التحويل:

img { width: 280px; aspect-ratio: 1; cursor: pointer; transition: .5s;
}
img:hover { transform: scale(1.35);
}

لا شيء معقد حتى الآن ، أليس كذلك؟ هيا لنذهب.

الدائرة

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

img { --b: 5px; /* border width */ width: 280px; aspect-ratio: 1; background: radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), #C02942 calc(100% - var(--b)) 99%, #0000 ); cursor: pointer; transition: .5s;
}
img:hover { transform: scale(1.35);
}

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

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

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

هنا عرض لتوضيح الحيلة. مرر الماوس لترى ما يحدث خلف الكواليس:

أضفت لونًا ثالثًا إلى ملف radial-gradient لتحديد منطقة التدرج اللوني عند التمرير بشكل أفضل:

radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), #C02942 calc(100% - var(--b)) 99%, lightblue
);

الآن علينا أن نضع خلفيتنا في وسط الدائرة ونتأكد من أنها تأخذ الارتفاع الكامل. أود أن أعلن كل شيء مباشرة على background خاصية الاختزال ، حتى نتمكن من إضافة موضع الخلفية لدينا والتأكد من عدم تكرارها عن طريق معالجة هذه القيم بعد radial-gradient():

background: radial-gradient() 50% / calc(100% / var(--f)) 100% no-repeat;

يتم وضع الخلفية في المركز (50%) ، بعرض يساوي calc(100%/var(--f))، ولها ارتفاع يساوي 100%.

لا شيء يقيس عندما --f مساوي ل 1 - مرة أخرى ، مقياسنا الأولي. وفي الوقت نفسه ، فإن التدرج يأخذ العرض الكامل للحاوية. عندما نزيد --f، يزداد حجم العنصر - بفضل ملف scale() تحويل - ويقل حجم التدرج.

إليك ما نحصل عليه عندما نطبق كل هذا على العرض التوضيحي الخاص بنا:

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

الحد السفلي

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

الحل الفعلي هو استخدام outline ملكية. نعم، outline، لا border. في مقالة سابقة، أريكم كيف outline قوي ويسمح لنا بإنشاء تأثيرات تحوم رائعة. مدموج مع outline-offset، لدينا بالضبط ما نحتاجه من أجل تأثيرنا.

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

الآن لدينا "الحد" السفلي (في الواقع ملف outline) جنبًا إلى جنب مع "الحد" الذي تم إنشاؤه بواسطة التدرج اللوني لإنشاء دائرة كاملة. ما زلنا بحاجة إلى إخفاء أجزاء من ملف outline (من الأعلى والجانبين) ، وهو ما سنصل إليه بعد قليل.

إليك الكود الخاص بنا حتى الآن ، بما في ذلك متغيرات CSS أخرى يمكنك استخدامها لتكوين حجم الصورة (--s) ولون "الحدود" (--c):

img { --s: 280px; /* image size */ --b: 5px; /* border thickness */ --c: #C02942; /* border color */ --f: 1; /* initial scale */ width: var(--s); aspect-ratio: 1; cursor: pointer; border-radius: 0 0 999px 999px; outline: var(--b) solid var(--c); outline-offset: calc((1 / var(--f) - 1) * var(--s) / 2 - var(--b)); background: radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), var(--c) calc(100% - var(--b)) 99%, #0000 ) 50% / calc(100% / var(--f)) 100% no-repeat; transform: scale(var(--f)); transition: .5s;
}
img:hover { --f: 1.35; /* hover scale */
}

نظرًا لأننا نحتاج إلى حد سفلي دائري ، فقد أضفنا a border-radius على الجانب السفلي ، مما يسمح لـ outline لتتناسب مع انحناء التدرج.

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

رسم تخطيطي لانتقال الخلفية.
تأثير تحوم خيالي للصورة الرمزية الخاصة بك

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

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

Offset = ((f - 1) * S/2) / f = (1 - 1/f) * S/2

نضيف علامة سالبة لأننا نحتاج إلى أن ينتقل المخطط التفصيلي من الخارج إلى الداخل:

Offset = (1/f - 1) * S/2

إليك عرض توضيحي سريع يوضح كيف يتبع المخطط التفصيلي التدرج اللوني:

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

outline-offset: calc((1 / var(--f) - 1) * var(--s) / 2) - var(--b));

الآن نحن بحاجة إلى إيجاد كيفية إزالة الجزء العلوي من المخطط التفصيلي. بمعنى آخر ، نريد فقط الجزء السفلي من الصورة outline.

أولاً ، دعنا نضيف مساحة في الجزء العلوي مع الحشو للمساعدة في تجنب التداخل في الجزء العلوي:

img { --s: 280px; /* image size */ --b: 5px; /* border thickness */ --c: #C02942; /* border color */ --f: 1; /* initial scale */ width: var(--s); aspect-ratio: 1; padding-block-start: calc(var(--s)/5); /* etc. */
}
img:hover { --f: 1.35; /* hover scale */
}

لا يوجد منطق معين لتلك المساحة المتروكة. الفكرة هي التأكد من أن المخطط لا يلمس رأس الصورة الرمزية. لقد استخدمت حجم العنصر لتحديد تلك المساحة لتكون دائمًا بنفس النسبة.

لاحظ أنني أضفت ملف content-box قيمة background:

background: radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), var(--c) calc(100% - var(--b)) 99%, #0000 ) 50%/calc(100%/var(--f)) 100% no-repeat content-box;

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

إضافة قناع CSS إلى المزيج

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

إليك رقم لتوضيح ما نحتاج إلى إخفائه أو ما نحتاج إلى إظهاره لنكون أكثر دقة

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

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

يمكننا تحديد جزأين من قناعنا:

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

إليك CSS النهائي لدينا:

img { --s: 280px; /* image size */ --b: 5px; /* border thickness */ --c: #C02942; /* border color */ --f: 1; /* initial scale */ --_g: 50% / calc(100% / var(--f)) 100% no-repeat content-box; --_o: calc((1 / var(--f) - 1) * var(--s) / 2 - var(--b)); width: var(--s); aspect-ratio: 1; padding-top: calc(var(--s)/5); cursor: pointer; border-radius: 0 0 999px 999px; outline: var(--b) solid var(--c); outline-offset: var(--_o); background: radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), var(--c) calc(100% - var(--b)) 99%, #0000) var(--_g); mask: linear-gradient(#000 0 0) no-repeat 50% calc(-1 * var(--_o)) / calc(100% / var(--f) - 2 * var(--b)) 50%, radial-gradient( circle closest-side, #000 99%, #0000) var(--_g); transform: scale(var(--f)); transition: .5s;
}
img:hover { --f: 1.35; /* hover scale */
}

دعونا نحلل ذلك mask ملكية. بالنسبة للمبتدئين ، لاحظ أن ملفًا مشابهًا radial-gradient() من background الممتلكات هناك. لقد أنشأت متغيرًا جديدًا ، --_g، للأجزاء المشتركة لجعل الأشياء أقل فوضى.

--_g: 50% / calc(100% / var(--f)) 100% no-repeat content-box; mask: radial-gradient( circle closest-side, #000 99%, #0000) var(--_g);

بعد ذلك ، هناك ملف linear-gradient() هناك أيضًا:

--_g: 50% / calc(100% / var(--f)) 100% no-repeat content-box; mask: linear-gradient(#000 0 0) no-repeat 50% calc(-1 * var(--_o)) / calc(100% / var(--f) - 2 * var(--b)) 50%, radial-gradient( circle closest-side, #000 99%, #0000) var(--_g);

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

calc(100% / var(--f) - 2 * var(--b))

ارتفاع المستطيل يساوي النصف 50%، من حجم العنصر.

نحتاج أيضًا إلى التدرج الخطي الموضوع في المركز الأفقي (50%) والإزاحة من الأعلى بنفس قيمة إزاحة المخطط التفصيلي. لقد أنشأت متغير CSS آخر ، --_o، بالنسبة للإزاحة التي حددناها مسبقًا:

--_o: calc((1 / var(--f) - 1) * var(--s) / 2 - var(--b));

أحد الأشياء المربكة هنا هو أننا بحاجة إلى ملف سلبي إزاحة للمخطط التفصيلي (لنقله من الخارج إلى الداخل) ولكن أ إيجابي تعويض التدرج اللوني (للانتقال من أعلى إلى أسفل). لذا ، إذا كنت تتساءل لماذا نضرب الإزاحة ، --_o، من خلال -1، حسنا الان تعرف!

إليك عرض توضيحي لتوضيح تكوين التدرج اللوني للقناع:

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

اختتام

عفوًا ، لقد انتهينا! ولم ننتهي فقط من خلال رسم متحرك بسيط ، ولكننا فعلنا كل ذلك باستخدام HTML واحد <img> عنصر. هذا فقط وأقل من 20 سطرًا من خداع CSS!

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

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

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

الطابع الزمني:

اكثر من الخدع المغلق