It is currently May 23rd, 2022, 4:41 am

PluginWebView - Make skin using web technology

Share and get help with Plugins and Addons
User avatar
khanhas
Posts: 40
Joined: October 26th, 2016, 5:00 pm

PluginWebView - Make skin using web technology

Post by khanhas »

Plugin to take advantage of Microsoft Edge WebView2 to display web content on a skin.
  • WebView window is attached into skin window so all skin configuration is respected (position, Z index, transparency,...)
  • Small memory usage and extremely fast skin loading time
  • Natively retrieve other Rainmeter measures' and plugins' values in JavasSript runtime
  • Web renderer provides unlimited rendering capabilites. And there are massive widget resources from the internet (Codepen, CSSHint.com, ...) that you customsize and make them functional
In example skins package, I demostrated how to setup WebView plugin measure and skin window to contain WebView window correctly.

Skin "player" and "visualizer" show how `RainmeterAPI` object is used to get AudioLevel and WebNowPlaying plugins values.
Skin "visualizer", "Miku" and "Minecraft" show 3D render capability. Note that they are for fun only, 3D rendering usew too much CPU and RAM.
"visualiser" is also interactable with mouse (zoom, pan, move)

Image

Download
Download Example Skins package in Releases page: https://github.com/khanhas/PluginWebView/releases to install skins + plugin.

Note: In first plugin load, it will prompt you to download and install WebView2 runtime if your Windows hasn't had it already. Click OK will open download link directly.


Github: https://github.com/khanhas/PluginWebView
Documentation: https://github.com/khanhas/PluginWebView#documentation
User avatar
Brian
Developer
Posts: 2415
Joined: November 24th, 2011, 1:42 am
Location: Utah

Re: PluginWebView - Make skin using web technology

Post by Brian »

Very interesting!
khanhas wrote: December 12th, 2021, 5:38 pm Download Example Skins package in Releases page: https://github.com/khanhas/PluginWebView/releases to install skins + plugin.
I don't see any releases on your github, I would very much like to test this out.

-Brian
User avatar
khanhas
Posts: 40
Joined: October 26th, 2016, 5:00 pm

Re: PluginWebView - Make skin using web technology

Post by khanhas »

:D I forgot to hit Publish drafted release.
I just did, please check Releases page again.
User avatar
death.crafter
Rainmeter Sage
Posts: 1364
Joined: April 24th, 2021, 8:13 pm

Re: PluginWebView - Make skin using web technology

Post by death.crafter »

Can't wait for it to be implemented as a native meter, and see Khan as a dev.
from the Realm of Death
User avatar
Jeff
Posts: 250
Joined: September 3rd, 2018, 11:18 am

Re: PluginWebView - Make skin using web technology

Post by Jeff »

I'm bracing myself for "why does my skin have a scrollbar??" questions.

Anyways, I think the plugin is really great, mainly for 2 reasons:
1. It makes up for a lot of shortcomings that Rainmeter has (for general meters you would have Effects (pixelization, bloom etc.) and 3D matricies; for the Container option it would be the fact it only works as an Union mask and not a Difference mask; for String meters you would have Line Height and honestly anything you can do with with CSS and Vector Text etc.);
2. This opens up skins for a lot more possibility, the possibility being going to three.js or codepen.io and adapting the stuff from there to Rainmeter skins (in a way that makes sense and not just making random samples into RM skins for the sake of it).

Only problem would be that it's a Windows 10+ feature, which is not something new to Rainmeter, rn the only Windows 7 specific feature is Blur, Windows 8(.1) is left in the dust and Windows 10 specific features are all the extra metrics in UsageMonitor plugin.
Maybe a warning popup similar to those when you have no meter in a file or when the SkinPath is wrong should popup anytime sometimes tries to load a skin using this plugin.
death.crafter wrote: December 14th, 2021, 3:34 am Can't wait for it to be implemented as a native meter, and see Khan as a dev.
You're saying this like it has happened before with some kind of GeometryMeter plugin, pffft, like it could ever :rofl:
Oh wait it did happen...
User avatar
khanhas
Posts: 40
Joined: October 26th, 2016, 5:00 pm

Re: PluginWebView - Make skin using web technology

Post by khanhas »

it's a Windows 10+ feature
WebView2 supports Windows 7, 8, and 10. https://docs.microsoft.com/en-us/microsoft-edge/webview2/#webview2-benefits
As long as users have Microsoft Edge Chromium and WebView2 runtime "Evergreen" installed.
User avatar
Yincognito
Rainmeter Sage
Posts: 4697
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: PluginWebView - Make skin using web technology

Post by Yincognito »

khanhas wrote: December 12th, 2021, 5:38 pmPlugin to take advantage of Microsoft Edge WebView2 to display web content on a skin.
I want to use this opportunity to thank and congratulate you for this plugin - hopefully it will be developed further and evolve into something that can be part of the standard Rainmeter package. I just replicated the basics of what my rotating 3D Earth skin does with just a couple of Javascript lines, and the performance is largely similar to my earlier native Rainmeter implementation (on my laptop). Luckily death.crafter let me know of this plugin's existence, and I'm quite impressed of what it can do.

Great job, looking forward to see it become even better! :thumbup: :bow: :rosegift:
User avatar
Yincognito
Rainmeter Sage
Posts: 4697
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: PluginWebView - Make skin using web technology

Post by Yincognito »

For reference, if one wants to drag or have the Rainmeter context menu in a skin having a WebView plugin measure when the CTRL key is pressed (as it's customary for Rainmeter), this should be added to the <body> element from the HTML (credit to death.crafter for the idea and the context menu part):

Code: Select all

    <script>
      document.body.onpointerdown = function(e) {if (e.button == 0 && e.ctrlKey) {e.preventDefault(); rm = true; clientX = e.clientX; clientY = e.clientY; try {controls.enabled = false;} catch {document.body.setPointerCapture(e.pointerId);};}};
      document.body.onpointermove = function(e) {if (typeof rm !== 'undefined' && rm) {e.preventDefault(); RainmeterAPI.Bang('[!Move ' + (e.screenX - clientX) + ' ' + (e.screenY - clientY) + ']');}};
      document.body.onpointerup   = function(e) {if (e.button == 0) {e.preventDefault(); rm = false; try {controls.enabled = true;} catch {document.body.releasePointerCapture(e.pointerId);};}};
      document.body.oncontextmenu = function(e) {if (e.button == 2 && e.ctrlKey) {e.preventDefault(); RainmeterAPI.Bang('[!SkinMenu]');}};
    </script>
It should work even if one drags the mouse outside the page, via setPointerCapture(), while also temporarily disabling a Three.js control like OrbitControls represented by the global variable called controls (TrackballControlls seems to "remember" the mouse move and keep doing it afterwards, due to some code differences compared to OrbitControls that I still need to investigate). This will work even if one doesn't have any controls in his page and the controls variable doesn't exist, via the try {} catch {} system. All the other variables are created globally and on the fly, no declaration required.

P.S. If by any chance the WebView page doesn't extend over all the skin area, simply subtract whatever left and top "margins" there are between the top-left corner of the skin and the top-left corner of the page / measure relative to the skin in the !Move bang formulas (e.g. if the WebView measure is positioned at X=8 and Y=8 in the skin, subtract 8 in both X and Y formulas) - I guess this can be done automatically via the RainmeterAPI as well, assuming the name of the measure is known.
User avatar
Yincognito
Rainmeter Sage
Posts: 4697
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: PluginWebView - Make skin using web technology

Post by Yincognito »

khanhas wrote: December 12th, 2021, 5:38 pm
  • Natively retrieve other Rainmeter measures' and plugins' values in JavasSript runtime
Either a bug or an omission somewhere:

Skin.ini:

Code: Select all

[SomeMeasure]
Measure=Calc
Formula=7
RegExpSubstitute=1
Substitute="^7$":"Seven"
...
...
...
[WebViewMeasure]
Measure=Plugin
Plugin=WebView
...
index.html:

Code: Select all

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="index.css"/>
  </head>
  <body>
    <script>
      console.log(RainmeterAPI.GetMeasure("SomeMeasure").GetNumber());
    </script>
  </body>
</html>
Result:
- Uncaught TypeError: Cannot read properties of null (reading 'GetNumber') in DevTools / Console
- Cant find measure in the Rainmeter log (spelling...)

Workaround:
- export measure value to a variable on measure update in Rainmeter, then use RainmeterAPI.GetVariable() to get the said value

Hopefully this won't turn into an abandoned project, since it's been several months since the issue has been reported on GitHub without any response...
User avatar
Yincognito
Rainmeter Sage
Posts: 4697
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: PluginWebView - Make skin using web technology

Post by Yincognito »

OK, one other thing: not sure whether it's because of how Rainmeter or the plugin works, but trying to resize the "measure" via adjusting its W and H (which I do by sending the appropriate bangs from Javascript on CTRL + mouse scroll, to have a skin / measure scaling effect) results in recreating the entire measure, with all that it encompasses (like recreating the webpage, reloading whatever imported libraries, resetting all things to how they were at page creation, etc). This is obviously slow and a bit flickering due to doing everything all over again, so a better way of updating the measure, where it would retain everything and just resize its "container" would be nice to have.

Currently, I avoided the above by setting the dimensions of the measure to the ones for the entire screen, then in the webpage using a <div> as a container for the displayed contents, which I can easily redimension according to the related variables from the skin. This partially solves the issue as it's very fast and working almost perfectly, but it involves having a webpage much larger than the visible contents needs, and even though the invisible part is not displayed, its (or the measure's) size impacts the GPU usage (I'm using hardware acceleration in Rainmeter lately) just as if the whole screen sized measure was visible. So, having a way to do the redimensioning from the measure without recreating and resetting the entire webpage would be optimal.

P.S. This could very well be an effect of how Rainmeter meters behave (where their size impacts the resource usage even though they may not be visible or only partially visible - something I noticed a while ago when designing another skin), so handling resizing from the WebView measure would get that particularity out of the way. Not sure how this should be implemented since the plugin doesn't use window.open() to create its "viewport", but I'm sure there is a feasible way of achieving it.