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

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

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

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

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

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

هناك فارغة. الآن تحتاج إلى إضافة الشبكة. نظرًا لأننا أردنا تغيير حجم التقويم ، ويجب أن تكون خطوط الشبكة دائمًا ذات بكسل واحد ، فقد استخدمنا السمة vector-effect = non-scaling-stroke. هذا يؤدي إلى حقيقة أنه بغض النظر عن كيفية تغيير حجمنا أو التكبير ، ستكون هناك دائمًا شبكة أحادية بكسل. يكفي فقط إضافة الكمية المناسبة من الخطوط الأفقية والعمودية ، وستكون هناك مثل هذه الشبكة.

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

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

الآن سيكون هناك أصعب مثال من التقرير بأكمله ، كن صبورًا ومشاهدًا ، ستكون هناك ثلاث خطوات ، سيصبح الأمر أسهل.
لنبدأ بالترتيب. تحتوي SVG على علامة <defs> ، فهي تسمح لك بالإعلان عن العناصر التي بداخلها غير معروضة ، ولكن يمكنك استخدامها بالرجوع إليها ، بالرجوع إليها. أول شيء سنفعله هو إعلان <defs> وإنشاء نمط فيه. <pattern> هي علامة تتيح لك إعلان نمط يمكنك استخدامه لملء عنصر معين بنمط معين.
نحن بحاجة إلى جعل الخلايا في هذا النمط. لدينا 60 × 60 بكسل ، يجب أن تكون الخلايا 6 × 6 ، لذلك أعلنا نقش 12 × 12 ورسم <مسار> بداخله ، كما في المخطط على اليسار. يحتوي على سمة d ، والتي تشير بالضبط إلى كيفية تحرك الخط. يبدأ من النقطة 0 ، ثم تُظهر الإحداثيات الأسهم كيف يتم رسمها. إذا ملأنا اللون الأبيض ، فسوف نحصل على النمط التالي: ما لا يفيض بالأبيض ، يملؤه بالأسود.

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

تحتاج الآن إلى تحديد الأحداث التي يجب تضمينها في التقويم في يوم معين. لدينا منطقة زمنية +3 ، نجلس فيها جميعًا ، ولها مقياس من 9 إلى 20 ساعة. هناك أيضًا شخص يجلس في أورينبورغ الشرطية ، ولديه منطقة زمنية +5 ، ويقابل مقياسه ساعتان بالنسبة لنا. سنقوم بعمل إسقاط على التوقيت العالمي المتفق عليه (UTC) ، ونرى أنه في UTC ، يجب عرض هذه الفترة الزمنية من الأعلى إلى الأسفل في الأسفل حتى يتمكن المستخدم من التبديل بين المناطق الزمنية ورؤية الأحداث التي تندرج في تقويمه وتقويم الشخص الذي يبحث عنه .
تذكر هذه الأرقام ، التي يتم تعويضها ، لأنه من الأسهل وضع الأحداث التي تصل إلى UTC في نفس التوقيت العالمي المنسق. للقيام بذلك ، نأخذ العلامة <g> ، والتي تشير إلى مجموعة في SVG ، ونضع جميع الأحداث هناك تمامًا حسب التوقيت العالمي المتفق عليه (UTC) ، وسنتحول <g> من عدد البكسل الذي نحتاجه لعرض منطقة زمنية واحدة أو أخرى.

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

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

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

يبقى لإضافة HTML بحيث تكون هناك حروف وأرقام في الأعلى. الحصول على التقويم.


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

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