mirror of
https://github.com/7PH/powerglitch.git
synced 2026-06-16 12:34:00 +02:00
Fix default options merge & Add transition customization option to playground & Fix README typo & Update website
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<img src="./assets/intro.gif">
|
||||
|
||||
PowerGlitch is a standalone library with no external dependencies. It leverages CSS animations to create a glitch effect on any image. No canvas or DOM manipulations are needed to create the glitch effect.
|
||||
PowerGlitch is a standalone library with no external dependencies. It leverages CSS animations to create a glitch effect on images. No canvas or DOM manipulations are needed.
|
||||
|
||||
Want to try it out? Check out the [demo](https://7ph.github.io/powerglitch/#/playground) 😊
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/logo.png" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 525 B |
@@ -5,6 +5,7 @@ import { PowerGlitch, getDefaultOptions } from '../../../src/index.ts';
|
||||
import logo from '@/assets/logo.png';
|
||||
import ToggleGroupOption from '@/components/ToggleGroupOption.vue';
|
||||
import StringOption from '@/components/StringOption.vue';
|
||||
import SelectOption from '@/components/SelectOption.vue';
|
||||
import BooleanOption from '@/components/BooleanOption.vue';
|
||||
import NumberOption from '@/components/NumberOption.vue';
|
||||
|
||||
@@ -79,8 +80,23 @@ onMounted(() => {
|
||||
:step="1"
|
||||
/>
|
||||
</template>
|
||||
<ToggleGroupOption
|
||||
class="mt-1"
|
||||
:modelValue="!! appStore.powerGlitchOptions.timing.easing"
|
||||
@update:modelValue="easing => appStore.powerGlitchOptions.timing.easing = easing"
|
||||
:title="'Smooth transition'"
|
||||
:getDefaultValue="v => v ? 'ease-in-out' : undefined"
|
||||
/>
|
||||
<template v-if="!! appStore.powerGlitchOptions.timing.easing">
|
||||
<SelectOption
|
||||
class="mt-1"
|
||||
v-model="appStore.powerGlitchOptions.timing.easing"
|
||||
:title="'Easing'"
|
||||
:values="['ease-in-out', 'ease-in', 'ease-out', 'linear']"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<div class="font-bold mt-6 mb-2 pl-2">Glitch Time Span</div>
|
||||
<div class="font-bold mt-6 mb-2 pl-2">Restrict glitch time span</div>
|
||||
<ToggleGroupOption
|
||||
v-model="appStore.powerGlitchOptions.glitchTimeSpan"
|
||||
:title="'Enabled'"
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { useAppStore } from '@/stores/app';
|
||||
|
||||
const appStore = useAppStore();
|
||||
|
||||
defineProps({
|
||||
modelValue: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
values: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
defineEmits(['update:modelValue']);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="pl-4 text-sm grid grid-cols-12">
|
||||
<div class="col-span-4 flex flex-col justify-center whitespace-nowrap overflow-x-hidden text-ellipsis min-w-0">
|
||||
{{ title }}
|
||||
</div>
|
||||
<div class="col-span-8 flex gap-4 overflow-x-hidden">
|
||||
<select
|
||||
class="w-full"
|
||||
:value="modelValue"
|
||||
@input="$emit('update:modelValue', $event.target.value)"
|
||||
>
|
||||
<option v-for="value in values" :key="value" :value="value">{{ value }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -30,8 +30,8 @@ onMounted(() => {
|
||||
</p>
|
||||
<div class="mt-2 flex justify-center gap-4">
|
||||
<RouterLink to="/" class="underline">home</RouterLink>
|
||||
<RouterLink to="/playground" class="underline">playground</RouterLink>
|
||||
<RouterLink to="/api" class="">api</RouterLink>
|
||||
<RouterLink to="/playground" class="underline">playground</RouterLink>
|
||||
<a target="_blank" href="https://github.com/7PH/powerglitch" class="underline">github</a>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -31,9 +31,6 @@ onMounted(() => {
|
||||
slice: {
|
||||
count: 3,
|
||||
velocity: 4,
|
||||
minHeight: 0.01,
|
||||
maxHeight: 0.15,
|
||||
hueRotate: true,
|
||||
},
|
||||
});
|
||||
PowerGlitch.glitch(frog3Glitch.value, {
|
||||
@@ -42,8 +39,8 @@ onMounted(() => {
|
||||
PowerGlitch.glitch(frog4Glitch.value, {
|
||||
imageUrl: exampleFrog,
|
||||
glitchTimeSpan: {
|
||||
start: 0,
|
||||
end: 1,
|
||||
start: 0.2,
|
||||
end: 0.8,
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -51,7 +48,9 @@ onMounted(() => {
|
||||
// Usage example
|
||||
const usageExample = `
|
||||
import { PowerGlitch } from 'powerglitch';
|
||||
PowerGlitch.glitch('#my-image', { imageUrl: logo });
|
||||
PowerGlitch.glitch('#my-image', {
|
||||
imageUrl: 'https://.../image.png'
|
||||
});
|
||||
`.trim();
|
||||
|
||||
// Install
|
||||
@@ -63,7 +62,7 @@ or
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="app w-full mx-auto my-8">
|
||||
<div class="app w-full mx-auto mb-8 mt-16 md:mt-8 px-4">
|
||||
|
||||
<!-- GitHub -->
|
||||
<p class="fixed right-0 top-0 mx-6 my-4 text-4xl">
|
||||
@@ -82,19 +81,19 @@ or
|
||||
</p>
|
||||
<div class="mt-2 flex justify-center gap-4">
|
||||
<RouterLink to="/" class="">home</RouterLink>
|
||||
<RouterLink to="/playground" class="underline">playground</RouterLink>
|
||||
<RouterLink to="/api" class="underline">api</RouterLink>
|
||||
<RouterLink to="/playground" class="underline">playground</RouterLink>
|
||||
<a target="_blank" href="https://github.com/7PH/powerglitch" class="underline">github</a>
|
||||
</div>
|
||||
|
||||
<!-- Usage -->
|
||||
<h1 class="font-bold mt-8">🔨 Usage</h1>
|
||||
<pre class="border border-gray-400 rounded-xl p-4 mt-4 bg-gray-300" v-html="usageExample"></pre>
|
||||
<pre class="border border-gray-400 overflow-x-auto rounded-xl p-4 mt-4 bg-gray-300" v-html="usageExample"></pre>
|
||||
|
||||
<!-- Introduction -->
|
||||
<h1 class="font-bold mt-8">❓ Introduction</h1>
|
||||
<p class="mt-4">
|
||||
PowerGlitch is a standalone library with no external dependencies. It leverages CSS animations to create a glitch effect on any image. No canvas or DOM manipulations are needed to create the glitch effect.<br>
|
||||
PowerGlitch is a standalone library with no external dependencies. It leverages CSS animations to create a glitch effect on images. No canvas or DOM manipulations are needed.<br>
|
||||
<br>
|
||||
What are you waiting for? <RouterLink to="playground" class="underline">Try glitching stuff now ⚡!</RouterLink>
|
||||
</p>
|
||||
|
||||
@@ -4,17 +4,32 @@ import ImagePreview from '@/components/ImagePreview.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="app h-full grid grid-cols-12">
|
||||
<div class="app h-full flex flex-row w-full">
|
||||
<p class="fixed right-0 top-0 mx-6 my-4 text-4xl">
|
||||
<RouterLink to="/">🔙</RouterLink>
|
||||
</p>
|
||||
<div class="col-span-4 border p-4 overflow-y-auto">
|
||||
<div class="option-panel border p-4 overflow-y-auto">
|
||||
<OptionPanel />
|
||||
</div>
|
||||
<div class="col-span-8 flex flex-col bg-white">
|
||||
<div class="grow flex flex-col bg-white">
|
||||
<div class="grow flex flex-col justify-center">
|
||||
<ImagePreview class="mx-auto" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.option-panel {
|
||||
width: 500px;
|
||||
}
|
||||
@media screen and (max-width: 1060px) {
|
||||
.app {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
.option-panel {
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 525 B |
+3
-3
@@ -2,10 +2,10 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/logo.png" />
|
||||
<link rel="icon" type="image/svg+xml" href="/powerglitch/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<script type="module" crossorigin src="/powerglitch/assets/index.5e4d40d4.js"></script>
|
||||
<link rel="stylesheet" href="/powerglitch/assets/index.5df389e9.css">
|
||||
<script type="module" crossorigin src="/powerglitch/assets/index.b75ba5f8.js"></script>
|
||||
<link rel="stylesheet" href="/powerglitch/assets/index.add05156.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "powerglitch",
|
||||
"version": "0.1.1",
|
||||
"version": "0.2.0",
|
||||
"main": "./lib/index.js",
|
||||
"types": "./lib/index.d.ts",
|
||||
"scripts": {
|
||||
|
||||
+38
-5
@@ -113,7 +113,7 @@ export type PowerGlitchOptions = {
|
||||
*/
|
||||
export type LayerDefinition = {
|
||||
steps: { [cssPropertyName: string]: string }[],
|
||||
timing: any,
|
||||
timing: EffectTiming,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -140,13 +140,13 @@ export const getDefaultOptions = (): Partial<PowerGlitchOptions> => ({
|
||||
end: 0.7,
|
||||
},
|
||||
shake: {
|
||||
velocity: 20,
|
||||
velocity: 15,
|
||||
amplitudeX: 0.4,
|
||||
amplitudeY: 0.4,
|
||||
},
|
||||
slice: {
|
||||
count: 10,
|
||||
velocity: 25,
|
||||
count: 6,
|
||||
velocity: 15,
|
||||
minHeight: 0.02,
|
||||
maxHeight: 0.15,
|
||||
hueRotate: true,
|
||||
@@ -220,6 +220,7 @@ const getRectanglePolygonCss = ({ top, left, height, width }: Rectangle) => {
|
||||
*/
|
||||
const getDefaultTimingCss = (stepCount: number) => {
|
||||
return {
|
||||
...getDefaultOptions().timing,
|
||||
easing: `steps(${stepCount}, jump-start)`,
|
||||
};
|
||||
};
|
||||
@@ -290,6 +291,38 @@ const generateLayers = (options: PowerGlitchOptions): LayerDefinition[] => {
|
||||
return layers;
|
||||
};
|
||||
|
||||
/**
|
||||
* Performs a deep merge of objects and returns new object. Does not modify
|
||||
* objects (immutable) and merges arrays via concatenation.
|
||||
* @param objects - Objects to merge
|
||||
* @returns New object with merged key/values
|
||||
*/
|
||||
function mergeDeep(...objects: any[]): any {
|
||||
const isObject = (obj: any) => obj && typeof obj === 'object';
|
||||
return objects.reduce((prev, obj) => {
|
||||
Object.keys(obj)
|
||||
.forEach(key => {
|
||||
const pVal = prev[key];
|
||||
const oVal = obj[key];
|
||||
|
||||
if (Array.isArray(pVal) && Array.isArray(oVal)) {
|
||||
prev[key] = pVal.concat(...oVal);
|
||||
return;
|
||||
}
|
||||
if (isObject(pVal) && isObject(oVal)) {
|
||||
prev[key] = mergeDeep(pVal, oVal);
|
||||
return;
|
||||
}
|
||||
if (oVal !== undefined) {
|
||||
prev[key] = oVal;
|
||||
}
|
||||
});
|
||||
|
||||
return prev;
|
||||
}, {});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make a single element glitch.
|
||||
* @param elOrSelector Element or selector to glitch.
|
||||
@@ -297,7 +330,7 @@ const generateLayers = (options: PowerGlitchOptions): LayerDefinition[] => {
|
||||
*/
|
||||
const glitch = (elOrSelector: string | HTMLDivElement, options: PowerGlitchOptions) => {
|
||||
// Fix options with defaults
|
||||
options = { ...getDefaultOptions(), ...options };
|
||||
options = mergeDeep(getDefaultOptions(), options);
|
||||
|
||||
// Find element
|
||||
if (typeof elOrSelector === 'string') {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"declaration": true,
|
||||
"noImplicitAny": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user