• Browser
  • Mail
  • News
  • Community
  • About
Register Login
HomeBlogsForumThemesContributeSocial

Vivaldi

  • Browser
  • Mail
  • News
  • Community
  • About

Navigation

    • Home
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups

    We will be doing maintenance work on Vivaldi Translate on the 11th of May starting at 03:00 (UTC) (see the time in your time zone).
    Some downtime and service disruptions may be experienced.
    Thanks in advance for your patience.

    1. Home
    2. Desktop
    3. Customizations & Extensions
    4. Modifications
    5. Moon Phase

    Moon Phase

    Modifications
    javascript modding
    8
    74
    7.7k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • luetage
      L
      luetage Supporters Soprano
      last edited by luetage

      The moon phase mod shows a different icon for each moon phase in form of a command chain button and adds age, progress, and name of the moon phase to the button title (hover). Add it to any toolbar, the moon phase updates when first loaded and after each click on the button. This is a Javascript modification, basic installation instructions for Javascripts files available from here: official guide. Follow additional instructions below.

      moon phase icon
      New Moon Screenshot from 2021-10-09 16-07-01.png
      Waxing Crescent Screenshot from 2021-10-09 16-07-44.png
      First Quarter Screenshot from 2021-10-09 16-08-14.png
      Waxing Gibbous Screenshot from 2021-10-09 16-08-50.png
      Full Moon Screenshot from 2021-10-09 16-09-53.png
      Waning Gibbous Screenshot from 2021-10-09 16-10-19.png
      Last Quarter Screenshot from 2021-10-09 16-10-48.png
      Waning Crescent Screenshot from 2021-10-09 16-11-15.png

      Start by creating a command chain in vivaldi://settings/qc, name it Moon Phase and add any command(s) you like. If you don’t know what to add yet, leave the default delay. Afterwards open the Toolbar Editor, select Command Chains from the dropdown and drag the button to the toolbar of your choice.

      Create an SVG file and paste the code below. This file has to be loaded in vivaldi://settings/themes/ ⇒ themes ⇒ editor ⇒ icons in your currently active icon theme as replacement for the default Command Chain icon for the Moon Phase button. Alternatively you can load the file directly from Github.

      moon-phase.svg

      <?xml version="1.0" encoding="UTF-8" standalone="no"?>
      <svg
        viewBox="-14 -14 28 28"
        width="28"
        height="28"
        xmlns="http://www.w3.org/2000/svg"
      >
        <g opacity="1">
          <defs>
            <clipPath id="vm-mp-cut">
              <rect
                id="vm-mp-mod"
                x="-5"
                y="-5"
                width="10"
                height="0"
                transform="rotate(0)"
              />
            </clipPath>
          </defs>
          <circle
            cx="0"
            cy="0"
            r="7"
            fill="none"
            stroke="currentColor"
            stroke-width="1.5"
          />
          <circle cx="0" cy="0" r="5" clip-path="url(#vm-mp-cut)" />
        </g>
      </svg>
      

      Then add the Javascript file to the application as usual. The mod uses the command chain identifier to load the current moon phase, therefore you need to inspect the UI, copy the ID for your own button out of the HTML and replace it with the existing ID in the file. As a second step add your latitude, which will adjust the perspective of the moon icon.

      Finally restart Vivaldi and the mod should work as expected 🎆

      moon-phase.js

      // Moon Phase
      // version 2024.11.0
      // https://forum.vivaldi.net/post/461432
      // Displays the current moon phase as command chain button. Download the
      // moon-phase.svg file and load it in theme settings. Moon phase calculation
      // adapted from https://minkukel.com/en/various/calculating-moon-phase/
      
      (async function moonPhase() {
        "use strict";
      
        // EDIT START
        // choose a digit from 0 to 4 approximating your latitude
        // north[0] northern[1] equator[2] southern[3] south[4]
        const approx = 0;
        // alternatively input your exact latitude in degrees (between 90 and -90)
        const latitude = 48.3;
        // command chain identifier (inspect UI and input your own)
        const command = "COMMAND_cln9yq818001n2v649xyaiird";
        // EDIT END
      
        const lunation = 29.53058770576;
        const lunartime = lunation * 86400;
        const newmoon = 947182440;
        const moon = {
          phases: [
            ["New Moon", 1],
            ["Waxing Crescent", 6.38264692644],
            ["First Quarter", 8.38264692644],
            ["Waxing Gibbous", 13.76529385288],
            ["Full Moon", 15.76529385288],
            ["Waning Gibbous", 21.14794077932],
            ["Last Quarter", 23.14794077932],
            ["Waning Crescent", 28.53058770576],
            ["", lunation],
          ],
          illum: [
            [-5, 0],
            [-5, 3],
            [-5, 5],
            [-5, 7],
            [-5, 10],
            [-2, 7],
            [0, 5],
            [2, 3],
          ],
          lat: [90, 45, 0, -45, -90],
          phase: () => {
            const unixtime = Math.floor(Date.now() / 1000);
            const progress = ((unixtime - newmoon) % lunartime) / lunartime;
            const age = progress * lunation;
            for (let i = 0; i < moon.phases.length; i++) {
              if (age <= moon.phases[i][1]) {
                if (i === 8) i = 0;
                return {
                  name: moon.phases[i][0],
                  age: Math.trunc(age),
                  progress: Math.trunc(progress * 100),
                  coordinate: moon.illum[i][0],
                  range: moon.illum[i][1],
                  angle: typeof latitude === "number" ? latitude : moon.lat[approx],
                };
              }
            }
          },
        };
      
        function moonwatch(btn) {
          const get = moon.phase();
          const number = get.age === 1 ? "day" : "days";
          btn.title = `${get.name}\n${get.age} ${number} \u{21ba} ${get.progress}%`;
          const mod = btn.querySelector("#vm-mp-mod");
          if (mod) {
            mod.setAttribute("y", get.coordinate);
            mod.setAttribute("height", get.range);
            mod.setAttribute("transform", `rotate(${get.angle})`);
            btn.classList.add("vm-mp");
          }
        }
      
        function conflate(el) {
          const btn = el.getElementsByTagName("BUTTON");
          console.info(btn.length);
          for (let i = 0; i < btn.length; i++) {
            if (btn[i].name === command && !btn[i].classList.contains("vm-mp")) {
              const send = () => moonwatch(btn[i]);
              send();
              btn[i].addEventListener("click", send);
            }
          }
        }
      
        const wait = () => {
          return new Promise((resolve) => {
            const check = document.getElementById("browser");
            if (check) return resolve(check);
            else {
              const startup = new MutationObserver(() => {
                const el = document.getElementById("browser");
                if (el) {
                  startup.disconnect();
                  resolve(el);
                }
              });
              startup.observe(document.body, { childList: true, subtree: true });
            }
          });
        };
      
        const lazy = (el, observer) => {
          observer.observe(el, { childList: true, subtree: true });
        };
      
        await wait().then((browser) => {
          const lazy_obs = new MutationObserver(() => {
            lazy_obs.disconnect();
            setTimeout(() => {
              conflate(browser);
              lazy(browser, lazy_obs);
            }, 666);
          });
          conflate(browser);
          lazy(browser, lazy_obs);
        });
      })();
      

      History

      • 2021-03-26 Release (full moon 🌕)
      • 2021-03-27 Clean up code and svg icons.
      • 2021-03-28 Improved moon phase calculation.
      • 2021-03-29 Switch to J2000 (waning gibbous moon 🌖)
      • 2021-05-04 Add display for southern hemisphere (last quarter moon 🌗)
      • 2021-10-09 New SVG icons, remove CSS file.
      • 2022.4.0 Cleanup
      • 2022.12.0 Rewrite for custom buttons feature
      • 2023.2.0 Only one SVG file needed in new Vivaldi versions
      • 2023.9.0 New version uses a native command chain button
      • 2024.4.0 Simplify phase names
      • 2024.6.0 Age (days) in the tooltip alongside with progress and name
      • 2024.6.2 Latitude setting
      • 2024.10.0 Handle error when icon loads slowly on first run
      • 2024.11.0 Move to mutation observer

      github ◊ vfm

      code3
      C
      1 Reply Last reply
      Reply Quote 18
      • luetage
        L
        luetage Supporters Soprano
        last edited by

        Replying to my own topic, sad times ^^ Anyway, I cleaned up the code, but especially the svgs have improved. They look and behave like Vivaldi’s native icons now. The second path is transparent and shows the panel background, which has adjustable opacity since the latest release. The moon phase icon also became a little smaller to better harmonize with the other buttons. What this means is we could potentially run a background with a tiny moon at the right place, which would then shine through our icon o.O

        github ◊ vfm

        1 Reply Last reply Reply Quote 2
        • luetage
          L
          luetage Supporters Soprano
          last edited by luetage

          Another update. I found a better and more accurate way to calculate and display the moon phases. Additionally the progress of the current lunar cycle will be shown as a percentage.

          New script adapted from this excellent article ☛ https://minkukel.com/en/various/calculating-moon-phase/. The reference point for our calculation is the first new moon in 2000. There was no need to make the mod work for any point in the past. Should you find an issue, please let me know.

          github ◊ vfm

          1 Reply Last reply Reply Quote 0
          • Pathduck
            P
            Pathduck Moderator Soprano Supporters
            last edited by

            Why do you need to know the moon phases?

            Are you, or have you ever been, a member of the witch and/or warlock councils?

            alt text

            🎻Volunteer helper · Forum moderator · Sopranos tester 🛠️Troubleshooting 🐛Report a bug 📜Markdown help
            🦆"With a rubber duck, one's never alone" -Douglas Adams🦆

            luetage
            L
            Hadden89
            H
            Stardust
            S
            3 Replies Last reply
            Reply Quote 3
            • code3
              C
              code3 @luetage
              last edited by

              @luetage This is a nice project, I may go back to the clock though. I installed your mods, and I wanted to ask you why did you hide the minimize button?

              1 Reply Last reply Reply Quote 1
              • luetage
                L
                luetage Supporters Soprano @Pathduck
                last edited by luetage

                @Pathduck Both actually.

                @code3 The minimize button? That’s not part of any of my mods. Are you using my backup files?

                github ◊ vfm

                code3
                C
                1 Reply Last reply
                Reply Quote 0
                • Hadden89
                  H
                  Hadden89 @Pathduck
                  last edited by

                  @Pathduck This mod could be also useful in case of lycantrophy :3

                  Vivaldi Stable+Snap | Patience Is The Key To Get The Vivaldi Spree | Unsupported Extensions | Github | windows 11 | Manjaro KDE | Q4OS Trinity | Android 13

                  1 Reply Last reply Reply Quote 5
                  • code3
                    C
                    code3 @luetage
                    last edited by

                    @luetage

                    /* window buttons */
                    .window-buttongroup button.window-maximize, .window-buttongroup button.window-minimize {
                        display: none;
                    }
                    .linux #tabs-container:not(.none).top {
                        padding-right: 40px;
                    }
                    

                    This is in the GitHub repo, uimods.css

                    luetage
                    L
                    1 Reply Last reply
                    Reply Quote 0
                    • luetage
                      L
                      luetage Supporters Soprano @code3
                      last edited by

                      @code3 Yeah, uimod.css and uimod.js are my backup files, use them at your own risk, sometimes there are breaking changes in there. The reason I remove maximize and minimize buttons is I’m on Gnome desktop environment and by default hide these buttons in all native windows too. I use keyboard shortcuts to minimize and maximize.

                      github ◊ vfm

                      code3
                      C
                      1 Reply Last reply
                      Reply Quote 0
                      • code3
                        C
                        code3 @luetage
                        last edited by

                        @luetage Ok, oops. I will take your backup files out. Thanks!

                        luetage
                        L
                        1 Reply Last reply
                        Reply Quote 0
                        • Stardust
                          S
                          Stardust @Pathduck
                          last edited by

                          @Pathduck said in Project History Moon:

                          Why do you need to know the moon phases?

                          @luetage lives near the ocean coast and high and low tides are caused by the Moon.

                          @luetage is surfer! 🏄🏻♂

                          alt text

                          code3
                          C
                          1 Reply Last reply
                          Reply Quote 4
                          • luetage
                            L
                            luetage Supporters Soprano @code3
                            last edited by luetage

                            @code3 The code is fine most of the time, after all it’s a backup, not a working version. But it makes more sense to take the mods you want and build your own version. The javascript backup file can help you with that, since it shows how to combine mods which share the prototype appendchild approach.

                            github ◊ vfm

                            code3
                            C
                            1 Reply Last reply
                            Reply Quote 1
                            • code3
                              C
                              code3 @luetage
                              last edited by

                              @luetage Yes, it didn’t break anything. I discovered an excellent project from @lonm to help with combining the files and adding them to Vivaldi; it also supports custom colors and page actions. I have been building the config.Jason with various mods - history clock, themes import export, auto save sessions, and some css styles. Thank you for sharing your mods! I hope to share some soon, I am working on a floating tab bar right now, but I am still a beginner at this.

                              1 Reply Last reply Reply Quote 0
                              • code3
                                C
                                code3 @Stardust
                                last edited by

                                @Stardust said in Project History Moon:

                                @Pathduck said in Project History Moon:

                                Why do you need to know the moon phases?

                                @luetage lives near the ocean coast and high and low tides are caused by the Moon.

                                @luetage is surfer! 🏄🏻♂

                                alt text

                                Are you?

                                luetage
                                L
                                Stardust
                                S
                                2 Replies Last reply
                                Reply Quote 0
                                • luetage
                                  L
                                  luetage Supporters Soprano @code3
                                  last edited by

                                  @code3 Does listening to Beach Boys count? Then yes, I am a surfer.

                                  But seriously, I don’t like non‐functioning clock‐faces. The moon phase icon is an alternative, slower timekeeper and it complements the existing clock in the toolbar.

                                  github ◊ vfm

                                  code3
                                  C
                                  1 Reply Last reply
                                  Reply Quote 4
                                  • Stardust
                                    S
                                    Stardust @code3
                                    last edited by

                                    @code3 I am an internet surfer! You?

                                    1 Reply Last reply Reply Quote 2
                                    • code3
                                      C
                                      code3 @luetage
                                      last edited by

                                      @luetage Alright, good job on your work with the moonphases, it looks like a lot of work. Personally, I prefer the History Clock Mod you made earlier because it seems like a better icon to represent "history." Maybe I will try putting the history moon in the status bar.

                                      1 Reply Last reply Reply Quote 0
                                      • code3
                                        C
                                        code3
                                        last edited by code3

                                        @luetage Here is my adaption: the moon is in the status bar, and replaces the normal icon for Break Mode. If anyone wants to use this, remember to use history-moon.css as well but delete the first part that hides the history button.
                                        It seems to be working correctly, thanks to luetage's moon math!
                                        @luetage Also, do you know if the history clock (not moon) is broken in snapshot?

                                        //  Moon Status
                                        // https://forum.vivaldi.net/topic/58821/project-history-moon/
                                        // Puts the moon in the status bar as the , with the correct phase.
                                        // Depends on the installation of additional CSS code (history-moon.css). Please remove the first rule of the history-moon.css file. It looks like this:
                                        /*
                                        #switch button.history svg:not(.history-moon) {
                                            display: none;
                                        }
                                        */
                                        // Moon phase calculation adapted from https://minkukel.com/en/various/calculating-moon-phase/
                                        // This is an adaption of the history clock mod from luetage. The adaption is from @code3, but nearly all of this  code and all of the work is from @luetage.
                                        // document.querySelector('[title="Take a Break"]').classList.add(".warlock-clock") should be executed upon loading of the browser.
                                        function initMod(){
                                            if(document.querySelector("#browser")){
                                                // History moon
                                                document.querySelector('[title="Take a Break"]').classList.add("warlock-clock");
                                            } else {
                                                setTimeout(initMod, 500);
                                            }
                                        }
                                        initMod();
                                        {
                                            let moon = {
                                                phases: [['New', 0, 1], ['Waxing Crescent', 1, 6.38264692644], ['First Quarter', 6.38264692644, 8.38264692644], ['Waxing Gibbous', 8.38264692644, 13.76529385288], ['Full', 13.76529385288, 15.76529385288], ['Waning Gibbous', 15.76529385288, 21.14794077932], ['Last Quarter', 21.14794077932, 23.14794077932], ['Waning Crescent', 23.14794077932, 28.53058770576], ['end', 28.53058770576, 29.53058770576]],
                                                phase: () => {
                                                    const lunarcycle = 29.53058770576;
                                                    const lunartime = lunarcycle * 86400;
                                                    const unixtime = Math.round(Date.now()/1000);
                                                    const newmoon = 947182440;
                                                    const diff = unixtime - newmoon;
                                                    const mod = diff % lunartime;
                                                    const frac = mod / lunartime;
                                                    const age = frac * lunarcycle;
                                                    for (let i = 0; i < 9; i++) {
                                                        if (age >= moon.phases[i][1] && age <= moon.phases[i][2]) {
                                                            if (i === 8) i = 0;
                                                            return {phase: i, name: moon.phases[i][0], progress: Math.trunc(frac * 100)};
                                                        }
                                                    }
                                                }
                                            }
                                        
                                            let historymoon = phase => {
                                                const hbtn = document.querySelector('[title="Take a Break"]') || document.querySelector(".warlock-clock");
                                                hbtn.innerHTML = `<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 216.2 216.2" class="history-moon"><path class="history-moon-${phase}" d="" fill-rule="evenodd"></path></svg>`;
                                            }
                                        
                                            let moonwatch = (mutations, phase) => {
                                                mutations.forEach(mutation => {
                                                    if (mutation.attributeName === 'class') historymoon(phase);
                                                })
                                            }
                                        
                                            let appendChild = Element.prototype.appendChild;
                                            Element.prototype.appendChild = function () {
                                                if (this.tagName === 'BUTTON') {
                                                    setTimeout(function() {
                                                        if (this == document.querySelector('[title="Take a Break"]') || this == document.querySelector(".warlock-clock")) {
                                                            const p = moon.phase();
                                                            historymoon(p.phase);
                                                            this.title += "! Get Outside!" + '\n' + "Tonight's Moon is a " + p.name + " " + p.progress + '%';
                                                            const mw = (mutations) => moonwatch(mutations, p.phase);
                                                            const resist = new MutationObserver(mw);
                                                            resist.observe(this, {attributes: true});
                                                        }
                                                    }.bind(this, arguments[0]));
                                                }
                                                return appendChild.apply(this, arguments);
                                            }
                                        }
                                        
                                        
                                        luetage
                                        L
                                        1 Reply Last reply
                                        Reply Quote 0
                                        • luetage
                                          L
                                          luetage Supporters Soprano @code3
                                          last edited by luetage

                                          @code3 Yes, it’s broken for two reasons: First of all the styles for the clock hands have been removed, which were an anchor point for the calculated angles. Secondly the redesign of the panel icons introduced the automatic replacement of the svg/s, whenever an icon is being selected or deselected.

                                          github ◊ vfm

                                          code3
                                          C
                                          1 Reply Last reply
                                          Reply Quote 0
                                          • code3
                                            C
                                            code3 @luetage
                                            last edited by

                                            @luetage said in Project History Moon:

                                            First of all the styles for the clock hands have been removed, which were an anchor point for the calculated angles

                                            Let me see if I can get the styles for the clock hands.

                                            @luetage said in Project History Moon:

                                            Secondly the redesign of the panel icons introduced the automatic replacement of the svg/s, whenever an icon is being selected or deselected.

                                            Couldn’t this be solved by replacing the SVGs yourself on click?

                                            luetage
                                            L
                                            1 Reply Last reply
                                            Reply Quote 0
                                            Loading More Posts
                                            • Oldest to Newest
                                            • Newest to Oldest
                                            • Most Votes
                                            Reply
                                            • Reply as topic
                                            Log in to reply
                                            • 1
                                            • 2
                                            • 3
                                            • 4
                                            • 1 / 4
                                            • First post
                                              Last post

                                            Looks like your connection to Vivaldi Forum was lost, please wait while we try to reconnect.

                                            Copyright © Vivaldi Technologies™ — All rights reserved. Privacy Policy | Code of conduct | Terms of use | Vivaldi Status