diff --git a/README.md b/README.md index 421cda5..d2890bb 100644 --- a/README.md +++ b/README.md @@ -48,8 +48,9 @@ This extension is not only more useless than the cube, but it is also much more | **Pixel Wheel**
This simple effect pixelates the window and hides the pixels in a wheel-like fashion. | | | **Pixel Wipe**
This effect pixelates the window and hides the pixels radially, starting from the pointer position. | | | **Portal**
This ridiculous effect teleports your windows from and to alternative dimensions. It may resemble the portal from a well-known cartoon series... | | -| **RGB Warp**
Red Blue and Green go bye bye. | | +| **RGB Warp**
Red Blue and Green go bye bye. | | | **Snap of Disintegration**
Dissolve your windows into a cloud of dust. | | +| **TeamRocket**
TeamRocket is Blasting off AAAAGGGGGAAAAAIIINNNN! | | | **T-Rex Attack**
Destroy your windows with a series of violent slashes! | | | **TV Effect**
This is a very simple effect to demonstrate that this extension could also be used in a more professional environment. | | | **TV Glitch**
This effect combines the Glitch and the TV Effect. | | @@ -89,6 +90,7 @@ Below is a table which summarizes the current availability for all effects. Portal ✅ ✅ ✅ ✅ RGB Warp ✅ ✅ ✅ ✅ Snap of Disintegration ✅ +TeamRocket ✅ ✅ ✅ ✅ T-Rex Attack ✅ TV Effect ✅ ✅ ✅ ✅ TV Glitch ✅ ✅ ✅ ✅ diff --git a/docs/pics/teamrocket.gif b/docs/pics/teamrocket.gif new file mode 100644 index 0000000..78ee982 Binary files /dev/null and b/docs/pics/teamrocket.gif differ diff --git a/extension.js b/extension.js index df9bdad..06776d9 100644 --- a/extension.js +++ b/extension.js @@ -42,6 +42,7 @@ import PixelWipe from './src/effects/PixelWipe.js'; import Portal from './src/effects/Portal.js'; import RGBWarp from './src/effects/RGBWarp.js'; import SnapOfDisintegration from './src/effects/SnapOfDisintegration.js'; +import TeamRocket from './src/effects/TeamRocket.js'; import TRexAttack from './src/effects/TRexAttack.js'; import TVEffect from './src/effects/TVEffect.js'; import TVGlitch from './src/effects/TVGlitch.js'; @@ -80,8 +81,8 @@ export default class BurnMyWindows extends Extension { new Glide(), new Glitch(), new Hexagon(), new Incinerate(), new Matrix(), new PaintBrush(), new Pixelate(), new PixelWheel(), new PixelWipe(), new Portal(), new RGBWarp(), new SnapOfDisintegration(), - new TRexAttack(), new TVEffect(), new TVGlitch(), new Wisps(), - new Mushroom(), + new TeamRocket(), new TRexAttack(), new TVEffect(), new TVGlitch(), + new Wisps(), new Mushroom(), ]; diff --git a/prefs.js b/prefs.js index 15d00b4..af81f62 100644 --- a/prefs.js +++ b/prefs.js @@ -44,6 +44,7 @@ import PixelWipe from './src/effects/PixelWipe.js'; import Portal from './src/effects/Portal.js'; import RGBWarp from './src/effects/RGBWarp.js'; import SnapOfDisintegration from './src/effects/SnapOfDisintegration.js'; +import TeamRocket from './src/effects/TeamRocket.js'; import TRexAttack from './src/effects/TRexAttack.js'; import TVEffect from './src/effects/TVEffect.js'; import TVGlitch from './src/effects/TVGlitch.js'; @@ -82,8 +83,8 @@ export default class BurnMyWindowsPreferences extends ExtensionPreferences { Matrix, Mushroom, PaintBrush, Pixelate, PixelWheel, PixelWipe, Portal, RGBWarp, SnapOfDisintegration, - TRexAttack, TVEffect, TVGlitch, - Wisps, + TeamRocket, TRexAttack, TVEffect, + TVGlitch, Wisps, ]; diff --git a/resources/shaders/rgbwarp.frag b/resources/shaders/rgbwarp.frag index 0892226..18885f4 100644 --- a/resources/shaders/rgbwarp.frag +++ b/resources/shaders/rgbwarp.frag @@ -45,8 +45,7 @@ float FadeInOut(float t, float power) } -// The width of the fading effect is loaded from the settings. -uniform float uFadeWidth; + void main() { @@ -89,4 +88,4 @@ void main() { setOutputColor(oColor); -} \ No newline at end of file +} diff --git a/resources/shaders/team-rocket.frag b/resources/shaders/team-rocket.frag new file mode 100644 index 0000000..f230228 --- /dev/null +++ b/resources/shaders/team-rocket.frag @@ -0,0 +1,207 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// ) ( // +// ( /( ( ( ) ( ( ( ( )\ ) ( ( // +// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( // +// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ // +// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) // +// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< // +// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ // +// |__/ // +////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: Justin Garza JGarza9788@gmail.com +// SPDX-License-Identifier: GPL-3.0-or-later + +// The content from common.glsl is automatically prepended to each shader effect. This +// provides the standard input: + +// vec2 iTexCoord: Texture coordinates for retrieving the window input color. +// bool uIsFullscreen: True if the window is maximized or in fullscreen mode. +// bool uForOpening: True if a window-open animation is ongoing, false otherwise. +// float uProgress: A value which transitions from 0 to 1 during the animation. +// float uDuration: The duration of the current animation in seconds. +// vec2 uSize: The size of uTexture in pixels. +// float uPadding: The empty area around the actual window (e.g. where the shadow +// is drawn). For now, this will only be set on GNOME. + +// Furthermore, there are two global methods for reading the window input color and +// setting the shader output color. Both methods assume straight alpha: + +// vec4 getInputColor(vec2 coords) +// void setOutputColor(vec4 outColor) + +// The width of the fading effect is loaded from the settings. +// uniform float uFadeWidth; + +uniform float uXpos; +uniform float uYpos; +uniform float uSparkleRot; +uniform float uSparkleSize; +uniform bool uWinRot; +uniform vec2 uSeed; + +//use to scale the window +vec2 scaleUV(vec2 uv, vec2 scale, vec2 centerOffset) +{ + // Put texture coordinate origin to center of window. + uv -= centerOffset; + uv = uv * 2.0 - 1.0; + + //scale + uv /= mix(vec2(1.0,1.0), vec2(0.0,0.0), scale); + + // scale from center + uv = uv * 0.5 + 0.5; + + + return uv; +} + + +//this returns the Spark +float getSpark(vec2 uv, vec2 center, float brightness, float size, float rotation) +{ + //the brightness of the spark + brightness = clamp(brightness,0.001,1.0); + //the size + size = clamp(size,0.001,1.0); + + float bn = mix(0.0,0.07,brightness); //recalculate size + + uv = (uv + vec2(0.5)) ; //set center + uv = (uv - center) ;//Center UV coordinates, then scale to fit the star size + uv = scaleUV(uv, vec2(1.0 - size), vec2(0.0)); + uv = rotate(uv, rotation, vec2(0.5)); //rotate the UV + + //this is basically the brightness + float p = mix(-1.0,1000.0,easeInExpo(bn)); + + float m = mix( + 0.0, + 1.0, + clamp( + pow(abs(uv.x-0.5)*2.0,p) + pow(abs(uv.y-0.5)*2.0,p),0.0,1.0 + ) + ); + + //calcuate and return this mask + float mask = easeInSine(1.0 - (m - bn)) - 0.004 ; + mask = clamp(mask,0.0,1.0); + return mask; + +} + + +//fades out at 0 and 1 ...based on the power +// 1| __________ +// | / \ +// | / \ +// | / \ +// |/ \ +// 0|0.................1 +/* +graph above ... where t is close to 0, or 1 the result will fade to zero +i.e. this is just the function of power(x,p) shifted +where x is time, and p is 2.0,4.0,8.0,10.0 ... or any positive even number +*/ +float FadeInOut(float t, float power) +{ + float s = -1.0 * pow((t-0.5)/(0.5),power)+1.0; + s = clamp(s,0.0,1.0); + return s; +} + +//2x pi ... don't think too much about it +float TAU = 6.28; + +void main() { + // Calculate the progression value based on the animation direction. + // If opening, use uProgress as-is; if closing, invert the progression. + float progress = uForOpening ? 1.0 - uProgress : uProgress ; + + // scale progress ... the first half of the animation + float scalep = remap( + progress, + 0.0,0.6, + 0.0,1.0 + ); + + scalep = easeInOutQuad(scalep); + + // sparkle progress ... the second half of the animation + float sparkp = remap( + progress, + 0.4,1.0, + 0.0,1.0 + ); + sparkp = easeInOutSine(sparkp); + + /* + the window will scale between 0.0 and 0.6 (of the progress) + the sparkle will bet between 0.4 and 1.0 (of the progress) + ... so there is a tab bit of over lap + */ + + // // this is the offset of the window... don't let them go too far each way + vec2 offset = vec2(uXpos,uYpos*-1.0) * 0.20; + vec2 scaleOffset = mix(vec2(0.0),offset,scalep); + + //the UV for this function + float aspect = uSize.x / uSize.y; + vec2 uv = iTexCoord.st * vec2(aspect,1.0); + + //get and adjust + vec2 uv2 = iTexCoord.st; + uv2 = uv2 * 2.0 - 1.0; + + //offset + uv2 -= ( scaleOffset/ vec2(aspect,1.0) ) *scalep; + + //scale + uv2 /= mix(1.0, 0.0, scalep); + + //rotation and if we are gonna rotate or not + vec3 rot = vec3(0.0); + if (uWinRot) + { + rot = hash32(uSeed); + rot *= 2.0; + rot -= 1.0; + rot *= 0.1; + } + + //rotate around x, y , and z + uv2.x /= mix(1.0, rot.x * TAU * uv2.y, scalep); + uv2.y /= mix(1.0, rot.y * TAU * uv2.x, scalep); + uv2 = rotate(uv2,rot.z*TAU*scalep); + + //re-center + uv2 = uv2 * 0.5 + 0.5; + + //gets the window + vec4 oColor = getInputColor( uv2) ; + + //the sparksize will bet between 25.0 and 50.0 + float size = mix(25.0,50.0,uSparkleSize); + + //get the sparkle + float sparkle = getSpark( + uv, + offset + vec2(0.5 * aspect,0.5), + FadeInOut(sparkp,2) * uSparkleSize, + FadeInOut(sparkp,2) * size, + sparkp * TAU * float(uSparkleRot) + ); + //fade out at the edges + sparkle *= FadeInOut(iTexCoord.t,8); + sparkle *= FadeInOut(iTexCoord.s,8); + + //set it to the results + oColor = alphaOver( + oColor, + vec4(1.0,1.0,1.0,sparkle) + ); + + //output the color + setOutputColor(oColor); +} \ No newline at end of file diff --git a/resources/ui/adw/aura-glow.ui b/resources/ui/adw/aura-glow.ui index 416d5e0..8336196 100644 --- a/resources/ui/adw/aura-glow.ui +++ b/resources/ui/adw/aura-glow.ui @@ -42,7 +42,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - + Color Offset Red - + center diff --git a/resources/ui/adw/team-rocket.ui b/resources/ui/adw/team-rocket.ui new file mode 100644 index 0000000..f381a2d --- /dev/null +++ b/resources/ui/adw/team-rocket.ui @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + Animation Time [ms] + + + + center + 1 + 0 + left + 300 + + + + 5000 + 100 + 10 + 100 + + + + + + + + edit-clear-symbolic + center + Reset to Default Value + + + + + + + + + + + X + + + + + center + 1 + 2 + left + 300 + + + + 1.0 + -1.0 + 0.01 + 0.1 + + + + + + + + edit-clear-symbolic + center + Reset to Default Value + + + + + + + + + + Y + + + + + center + 1 + 2 + left + 300 + + + + 1.0 + -1.0 + 0.01 + 0.1 + + + + + + + + edit-clear-symbolic + center + Reset to Default Value + + + + + + + + + Rotate Window + team-rocket-win-rot + + + center + + + + + edit-clear-symbolic + center + Reset to Default Value + + + + + + + + + + Sparkle Size + + + + + center + 1 + 2 + left + 300 + + + + 1.0 + 0.5 + 0.1 + 0.25 + + + + + + + + edit-clear-symbolic + center + Reset to Default Value + + + + + + + + + + Sparkle Rotation + + + + + center + 1 + 2 + left + 300 + + + + 1.0 + -1.0 + 0.1 + 0.25 + + + + + + + + edit-clear-symbolic + center + Reset to Default Value + + + + + + + + + + diff --git a/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml b/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml index c337b4b..ed19d0a 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml @@ -1080,7 +1080,51 @@ SPDX-License-Identifier: CC0-1.0 Blue offset of the effect. + + + + + false + Team Rocket Enable Effect + Use the Team Rocket effect. + + + + 1500 + Team Rocket Animation Time + The time the Team Rocket effect takes. + + + + 0.0 + Team Rocket X + X position + + + + 0.0 + Team Rocket Y + Y position + + + + false + Rotate the Window + Rotate the Window + + + + 0.33 + Sparkle Rotation + Sparkle Rotation + + + + 0.75 + Sparkle Size + Sparkle Size + diff --git a/src/effects/AuraGlow.js b/src/effects/AuraGlow.js index 11983a4..4383735 100644 --- a/src/effects/AuraGlow.js +++ b/src/effects/AuraGlow.js @@ -151,6 +151,8 @@ export default class Effect { .set_sensitive(!state); } + // if we use a checkbox instead of a switch + /* const randColor = dialog.getBuilder().get_object('aura-glow-random-color'); if (randColor) { // Connect to the "toggled" signal to update preferences dynamically @@ -168,9 +170,10 @@ export default class Effect { // Log an error if the switch widget is not found in the UI log('Error: \'aura-glow-random-color\' switch widget not found.'); } + */ // if we use a switch instead of a checkbox - /* + const switchWidget = dialog.getBuilder().get_object('aura-glow-random-color'); if (switchWidget) { // Connect to the "state-set" signal to update preferences dynamically based on @@ -188,7 +191,7 @@ export default class Effect { // Log an error if the switch widget is not found in the UI. log('Error: \'aura-glow-random-color\' switch widget not found.'); } - */ + // Retrieve the necessary objects const colorOffset = dialog.getBuilder().get_object('aura-glow-color-offset-scale'); diff --git a/src/effects/TeamRocket.js b/src/effects/TeamRocket.js new file mode 100644 index 0000000..a8485b0 --- /dev/null +++ b/src/effects/TeamRocket.js @@ -0,0 +1,125 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// ) ( // +// ( /( ( ( ) ( ( ( ( )\ ) ( ( // +// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( // +// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ // +// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) // +// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< // +// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ // +// |__/ // +////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: Justin Garza JGarza9788@gmail.com +// SPDX-License-Identifier: GPL-3.0-or-later + +'use strict'; + +import * as utils from '../utils.js'; + +// We import the ShaderFactory only in the Shell process as it is not required in the +// preferences process. The preferences process does not create any shader instances, it +// only uses the static metadata of the effect. +const ShaderFactory = await utils.importInShellOnly('./ShaderFactory.js'); + +const _ = await utils.importGettext(); + +////////////////////////////////////////////////////////////////////////////////////////// +// This effect was inspired by Team Rocket Blasting Off again! // +// https://c.tenor.com/0ag0MVXUaQEAAAAd/tenor.gif // +////////////////////////////////////////////////////////////////////////////////////////// + +// The effect class can be used to get some metadata (like the effect's name or supported +// GNOME Shell versions), to initialize the respective page of the settings dialog, as +// well as to create the actual shader for the effect. +export default class Effect { + // The constructor creates a ShaderFactory which will be used by extension.js to create + // shader instances for this effect. The shaders will be automagically created using the + // GLSL file in resources/shaders/.glsl. The callback will be called for each + // newly created shader instance. + constructor() { + this.shaderFactory = new ShaderFactory(Effect.getNick(), (shader) => { + // Store uniform locations of newly created shaders. + shader._uXpos = shader.get_uniform_location('uXpos'); + shader._uYpos = shader.get_uniform_location('uYpos'); + shader._uWinRot = shader.get_uniform_location('uWinRot'); + shader._uSparkleRot = shader.get_uniform_location('uSparkleRot'); + shader._uSparkleSize = shader.get_uniform_location('uSparkleSize'); + + shader._uSeed = shader.get_uniform_location('uSeed'); + + // Write all uniform values at the start of each animation. + shader.connect('begin-animation', (shader, settings) => { + shader.set_uniform_float(shader._uXpos, 1, [ + settings.get_double('team-rocket-x'), + ]); + + shader.set_uniform_float(shader._uYpos, 1, [ + settings.get_double('team-rocket-y'), + ]); + + shader.set_uniform_float(shader._uWinRot, 1, + [settings.get_boolean('team-rocket-win-rot')]); + + shader.set_uniform_float(shader._uSparkleRot, 1, [ + settings.get_double('team-rocket-sparkle-rot'), + ]); + + shader.set_uniform_float(shader._uSparkleSize, 1, [ + settings.get_double('team-rocket-sparkle-size'), + ]); + + // this will be used with a has function to get a random number + // clang-format off + shader.set_uniform_float(shader._uSeed, 2, [Math.random(), Math.random()]); + }); + }); + } + + // ---------------------------------------------------------------------------- metadata + + // The effect is available on all GNOME Shell versions supported by this extension. + static getMinShellVersion() { + return [3, 36]; + } + + // This will be called in various places where a unique identifier for this effect is + // required. It should match the prefix of the settings keys which store whether the + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time + // (e.g. '*-animation-time'). Also, the shader file and the settings UI files should be + // named likes this. + static getNick() { + return 'team-rocket'; + } + + // This will be shown in the sidebar of the preferences dialog as well as in the + // drop-down menus where the user can choose the effect. + static getLabel() { + return _('TeamRocket'); + } + + // -------------------------------------------------------------------- API for prefs.js + + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + static bindPreferences(dialog) { + // Empty for now... Code is added here later in the tutorial! + + dialog.bindAdjustment('team-rocket-animation-time'); + dialog.bindAdjustment('team-rocket-x'); + dialog.bindAdjustment('team-rocket-y'); + + dialog.bindSwitch('team-rocket-win-rot'); + + dialog.bindAdjustment('team-rocket-sparkle-rot'); + dialog.bindAdjustment('team-rocket-sparkle-size'); + } + + // ---------------------------------------------------------------- API for extension.js + + // The getActorScale() is called from extension.js to adjust the actor's size during the + // animation. This is useful if the effect requires drawing something beyond the usual + // bounds of the actor. This only works for GNOME 3.38+. + static getActorScale(settings, forOpening, actor) { + return {x: 1.0, y: 1.0}; + } +} \ No newline at end of file