PHP / צבע אקראי

זה לא קוד מקורי מדי, אבל אם אפשר לחסוך לכם עבודה למה לא.

במערכת ניהול תוכן שלי, שהממשק בה די פשוט ולא צבעוני בעליל, אם המשתמש שמר פרטים חדשים הוא מקבל הודעת אישור במסך הבא. לא מקבל את מספר השינויים (למי יש כוח לספור אותם?) אלא רק איזה <p class='sysMsg'>השינויים נשמרו.</p>
מבחינת שימושיות, אפילו לי לא נוח כשאני שומרת כל פעם שינוי אחר – הריבוע "השינויים נשמרו" נשאר זהה.. זה נראה כאילו סתם עלה אותו מסך, ולא באמת התבצע שינוי במערכת.

אז נעשה שכל פעם הצבע של הריבוע ישתנה.. ממילא זו לא המערכת הכי אסתטית 🙂

והנה תיקון הקוד. אני ממש לא בטוחה לגבי החשבון, אבל בינתיים זה עובד:

CSS:
.sysMsg { border: 3px solid red; }

PHP:
srand(time());

# for ANY random color:
print '<p class="sysMsg" style="border-color: #' . str_pad(dechex((rand()*rand())%(pow(16,6))),6,'0').';">השינויים נשמרו.</p>';

# for stuff that isn't too white, say, maximum 0xDD (**) for each value of R, G, B
$ceil = 34+34*pow(16,1)+34*pow(16,2);
print '<p class="sysMsg" style="border-color: #' . str_pad(dechex((rand()*rand())%(pow(2,24)-$ceil)),6,'0').';">השינויים נשמרו.</p>';

מה עשינו פה?

קודם כל, שינינו רק את צבע ה BORDER, דרסנו את זה של ה CSS. ככה התערבנו ב CSS בצורה המינימלית ביותר שאני רואה לפחות (אלא אם מתחילים לדחוף פונקציות רנדומליות ל CSS, וזה נראה לי כאב ראש)

שנית, לגבי המתמטיקה.

בדוגמה ללא ההגבלה לצבע לא לבן:

  • pow(2,24)‎ נותן 0x‎ 1,000,000 , כלומר אחד מעל לצבע הכי גבוה שיש לנו (זה בעצם pow(2,8) . pow(2,8) . pow(2,8)‎ (*) ). מכיוון ש rand() % $x נותן לנו מספרים מ 0 ועד ‎$x-1 זה נותן לנו באמת מספר רנדומלי בטווח הזה.
  • ‎rand() * rand()‎ – לא קראתי את המדריך, אבל פרקטית כשהשתמשתי באחד המספרים יצאו קטנים מדי. כנראה שהמספר הרנדומלי הרגיל לא גדול מספיק. ככה הגדלנו אותו. מי יודע, אולי צריך להכפיל שוב, אבל אני מעריכה שלא.
  • צריך לוודא שיוצא לנו מספר של 3 או 6 ספרות, אחרת דפדפנים יתקעו על זה.

בדוגמה עם ההגבלה:

  • רצינו שכל ערך יהיה עד ‎0xDD, כלומר רצינו להחסיר ‎0x22 מהגבול העליון של כל ערך. בדצימלי ‎0x22 = 34 .
  • כדי להוריד 22 מהספרה השלישית והרביעית, לדוגמה, נצטרך להכפיל את 22 ב 16 בחזקת 2.(***)

והאמת?

שקצת רימיתי והשתמשתי בפתרון יותר מכוער, פשוט כי הוא היה הראשון שעבד לי ולא רציתי להכנס לבאגים עקב מתמטיקה שגויה:

$sysMsgColor = '#';
foreach (array('r','g','b') as $c)
$sysMsgColor.= dechex(rand()%226+30);

אבל הפתרון הזה לא מעניין מספיק לטעמי בשביל פוסט.

——————–

(*) למי שלא מכיר,קוד לצבע בHTMLית מורכב משלושה מרכיבים: אדום, ירוק, כחול. לכל אחד מאלו צריך להזין ערך בין 0 ל-255, כלומר בין 0 ל- ‎2^8-1 . זה צריך להיות בהקסאדצימלי, ושלושת הערכים מופיעים זה אחרי זה. למשל צבע שהוא זה 13 אדום, 255 ירוק, 0 כחול ולכן ‎#0DFF00 .

(**) הסימון ‎0xWHATEVER פירושו שהערך (WHATEVER) מוצג בהקסא. ואז למשל A = 9+1 .

(***) מה זאת אומרת פנית לכוכביות? עדיף לחפש חומר על בסיסי ספירה.

סגור לתגובות.