mica effect emulation

This commit is contained in:
booploops 2022-03-10 20:16:20 -08:00
parent d1cf11f0b0
commit f1baf887cf
11 changed files with 164 additions and 29 deletions

View file

@ -39,7 +39,6 @@
"@sentry/electron": "^3.0.2", "@sentry/electron": "^3.0.2",
"@sentry/integrations": "^6.18.1", "@sentry/integrations": "^6.18.1",
"adm-zip": "0.4.10", "adm-zip": "0.4.10",
"castv2-client": "^1.2.0", "castv2-client": "^1.2.0",
"chokidar": "^3.5.3", "chokidar": "^3.5.3",
"discord-rpc": "^4.0.1", "discord-rpc": "^4.0.1",
@ -49,7 +48,6 @@
"electron-notarize": "^1.1.1", "electron-notarize": "^1.1.1",
"electron-store": "^8.0.1", "electron-store": "^8.0.1",
"electron-updater": "^4.6.5", "electron-updater": "^4.6.5",
"electron-window-state": "^5.0.3", "electron-window-state": "^5.0.3",
"express": "^4.17.3", "express": "^4.17.3",
"get-port": "^5.1.1", "get-port": "^5.1.1",
@ -67,6 +65,7 @@
"source-map-support": "^0.5.21", "source-map-support": "^0.5.21",
"typescript": "^4.5.5", "typescript": "^4.5.5",
"v8-compile-cache": "^2.3.0", "v8-compile-cache": "^2.3.0",
"wallpaper": "5.0.1",
"ws": "^8.5.0", "ws": "^8.5.0",
"xml2js": "^0.4.23", "xml2js": "^0.4.23",
"youtube-search-without-api-key": "^1.0.7" "youtube-search-without-api-key": "^1.0.7"

View file

@ -13,6 +13,8 @@ import {wsapi} from "./wsapi";
import {utils} from './utils'; import {utils} from './utils';
import {Plugins} from "./plugins"; import {Plugins} from "./plugins";
import {watch} from "chokidar"; import {watch} from "chokidar";
const wallpaper = require('wallpaper');
// @ts-ignore // @ts-ignore
import * as AdmZip from "adm-zip"; import * as AdmZip from "adm-zip";
@ -593,6 +595,16 @@ export class BrowserWindow {
/********************************************************************************************************************** /**********************************************************************************************************************
* ipcMain Events * ipcMain Events
****************************************************************************************************************** */ ****************************************************************************************************************** */
ipcMain.on("get-wallpaper", async (event) => {
const wpPath:string = await wallpaper.get();
// get the wallpaper and encode it to base64 then return
const wpBase64:string = await readFileSync(wpPath, 'base64')
// add the data:image properties
const wpData:string = `data:image/png;base64,${wpBase64}`
event.returnValue = wpData;
})
ipcMain.on("cider-platform", (event) => { ipcMain.on("cider-platform", (event) => {
event.returnValue = process.platform; event.returnValue = process.platform;
}); });

View file

@ -176,7 +176,11 @@ export default class mpris {
*/ */
onBeforeQuit(): void { onBeforeQuit(): void {
console.debug(`[Plugin][${mpris.name}] Stopped.`); console.debug(`[Plugin][${mpris.name}] Stopped.`);
mpris.clearState() try {
mpris.clearState()
}catch(e) {
e = null
}
} }
/** /**

View file

@ -105,6 +105,9 @@ function fallbackinitMusicKit() {
}) })
setTimeout(() => { setTimeout(() => {
app.init() app.init()
if(app.cfg.visual.window_background_style == "mica") {
app.spawnMica()
}
}, 1000) }, 1000)
} }
@ -131,6 +134,9 @@ document.addEventListener('musickitloaded', function () {
function waitForApp() { function waitForApp() {
if (typeof app.init !== "undefined") { if (typeof app.init !== "undefined") {
app.init() app.init()
if(app.cfg.visual.window_background_style == "mica") {
app.spawnMica()
}
} }
else { else {
setTimeout(waitForApp, 250); setTimeout(waitForApp, 250);

2
src/renderer/lib/stackblur.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -6,6 +6,7 @@ import {CiderAudio} from '../audio/audio.js'
import {Events} from './events.js' import {Events} from './events.js'
import { wsapi } from "./wsapi_interop.js" import { wsapi } from "./wsapi_interop.js"
import { MusicKitTools } from "./musickittools.js" import { MusicKitTools } from "./musickittools.js"
import { spawnMica } from "./mica.js"
// Define window objects // Define window objects
@ -26,5 +27,6 @@ if (app.cfg.advanced.AudioContext){
// Import gamepad support // Import gamepad support
app.simulateGamepad = simulateGamepad app.simulateGamepad = simulateGamepad
app.spawnMica = spawnMica
Events.InitEvents() Events.InitEvents()

84
src/renderer/main/mica.js Normal file
View file

@ -0,0 +1,84 @@
async function spawnMica() {
const micaDiv = document.createElement('div');
const blurIterations = 6
micaDiv.id = 'micaEffect';
micaDiv.style.position = "fixed"
micaDiv.style.top = "0"
micaDiv.style.left = "0"
micaDiv.style.right = "0"
micaDiv.style.bottom = "0"
micaDiv.style.width = window.innerWidth + 'px';
micaDiv.style.height = window.innerHeight + 'px';
micaDiv.style.zIndex = -1
let lastScreenX;
let lastScreenY;
let lastScreenWidth;
let lastScreenHeight;
let imgSrc = await ipcRenderer.sendSync("get-wallpaper")
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');
let img = new Image();
img.src = imgSrc;
img.onload = function () {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
for (let i = 0; i < blurIterations; i++) {
StackBlur.canvasRGB(canvas, 0, 0, img.width, img.height, 128);
}
let imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
micaDiv.style.backgroundImage = `url(${canvas.toDataURL()})`;
document.body.appendChild(micaDiv);
// on animation finished set animation to unset
micaDiv.addEventListener('animationend', function () {
micaDiv.style.opacity = '1';
micaDiv.style.animation = 'unset';
})
}
function onScreenMove(cb) {
function detectScreenMove() {
if (lastScreenY !== window.screenY || lastScreenX !== window.screenX) {
lastScreenY = window.screenY;
lastScreenX = window.screenX;
cb();
}
// window size change
if (lastScreenWidth !== window.innerWidth || lastScreenHeight !== window.innerHeight) {
lastScreenWidth = window.innerWidth;
lastScreenHeight = window.innerHeight;
cb();
}
if (true) {
requestAnimationFrame(detectScreenMove);
}
}
if (true) {
requestAnimationFrame(detectScreenMove);
}
}
onScreenMove(function () {
const screenHeight = window.screen.height;
const screenWidth = window.screen.width;
const windowHeight = window.innerHeight;
const windowWidth = window.innerWidth;
const ratio = windowWidth / windowHeight;
const x = window.screenX;
const y = window.screenY;
micaDiv.style.backgroundSize = `${screenWidth}px ${screenHeight}px`;
// micaDiv.style.backgroundPosition = `-${x}px -${y}px`;
if (x < 0) {
micaDiv.style.backgroundPosition = `${screenWidth + x}px -${y}px`;
} else {
micaDiv.style.backgroundPosition = `-${x}px -${y}px`;
}
});
return true
}
export {spawnMica}

View file

@ -7018,6 +7018,7 @@ fieldset:disabled .btn {
font-size: 0.875rem; font-size: 0.875rem;
word-wrap: break-word; word-wrap: break-word;
opacity: 0; opacity: 0;
pointer-events: none;
} }
.tooltip.show { .tooltip.show {
opacity: 0.9; opacity: 0.9;
@ -8023,6 +8024,10 @@ fieldset:disabled .btn {
box-shadow: var(--mediaItemShadow); box-shadow: var(--mediaItemShadow);
color: #eee; color: #eee;
} }
.cd-mediaitem-list-item.disabled {
opacity: 0.5;
pointer-events: none;
}
.cd-mediaitem-list-item.compact { .cd-mediaitem-list-item.compact {
height: 40px; height: 40px;
font-size: 13px; font-size: 13px;
@ -9103,6 +9108,13 @@ input[type=checkbox][switch]:checked:active::before {
.notyf-info { .notyf-info {
background: var(--keyColor); background: var(--keyColor);
} }
.tooltip-inner {
background: #2f2f2f;
opacity: 1;
border: 1px solid rgba(0, 0, 0, 0.35);
transition: all 0.3s ease-in-out;
box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.25);
}
.modal-fullscreen { .modal-fullscreen {
display: flex; display: flex;
justify-content: center; justify-content: center;
@ -11218,38 +11230,16 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
height: 100%; height: 100%;
} }
body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.minimize { body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.minimize {
height: 12px; display: none;
width: 12px;
background-color: #ff5c5c;
border-radius: 50%;
display: inline-block;
margin: auto 4px;
color: #820005;
-webkit-app-region: no-drag;
background-image: unset;
} }
body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls { body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls {
width: 67px; display: none;
} }
body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.minmax { body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.minmax {
height: 12px; display: none;
width: 12px;
background-color: #ffbd4c;
border-radius: 50%;
display: inline-block;
margin: auto 4px;
-webkit-app-region: no-drag;
background-image: unset;
} }
body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.close { body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.close {
height: 12px; display: none;
width: 12px;
background-color: #00ca56;
border-radius: 50%;
display: inline-block;
margin: auto 4px auto 4px;
-webkit-app-region: no-drag;
background-image: unset;
} }
.app-chrome .app-chrome-item.playback-controls { .app-chrome .app-chrome-item.playback-controls {
width: 80%; width: 80%;
@ -12499,6 +12489,20 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
width: 100%; width: 100%;
justify-content: center; justify-content: center;
} }
#micaEffect {
opacity: 1;
filter: brightness(0.5);
}
@keyframes micaEnter {
0% {
opacity: 0;
transform: translateY(10px);
}
100% {
opacity: 1;
transform: translateY(0px);
}
}
@keyframes rotate { @keyframes rotate {
from { from {
transform: rotate(0deg); transform: rotate(0deg);
@ -13022,6 +13026,7 @@ body[platform="linux"] #window-controls-container {
#app.twopanel .app-chrome.chrome-bottom { #app.twopanel .app-chrome.chrome-bottom {
height: var(--chromeHeight2); height: var(--chromeHeight2);
box-shadow: 0px -1px 0px rgba(0, 0, 0, 0.25); box-shadow: 0px -1px 0px rgba(0, 0, 0, 0.25);
z-index: 1;
} }
#app.twopanel .app-sidebar-footer--controls { #app.twopanel .app-sidebar-footer--controls {
display: none !important; display: none !important;

View file

@ -2614,6 +2614,23 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
// Cider App // Cider App
#micaEffect {
opacity:1;
// animation: micaEnter 1s ease-in-out forwards;
filter: brightness(0.5);
@keyframes micaEnter {
0% {
opacity: 0;
transform: translateY(10px);
}
100% {
opacity: 1;
transform: translateY(0px);
}
}
}
@keyframes rotate { @keyframes rotate {
from { from {
transform: rotate(0deg); transform: rotate(0deg);

View file

@ -38,6 +38,7 @@
<script src="./lib/velocity.min.js"></script> <script src="./lib/velocity.min.js"></script>
<script src="./lib/fast-plural-rules.js"></script> <script src="./lib/fast-plural-rules.js"></script>
<script src="./lib/resonance-audio.min.js"></script> <script src="./lib/resonance-audio.min.js"></script>
<script src="./lib/stackblur.min.js"></script>
<script type="module" src="./main/app.js"></script> <script type="module" src="./main/app.js"></script>
<style> <style>

View file

@ -174,6 +174,9 @@
<option value="image"> <option value="image">
{{$root.getLz('settings.header.visual.windowBackgroundStyle.image')}} {{$root.getLz('settings.header.visual.windowBackgroundStyle.image')}}
</option> </option>
<option value="mica">
Mica (Beta)
</option>
</select> </select>
</div> </div>
</div> </div>