Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

filter新增了平滑滚动的参数-’@‘ #28

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
341 changes: 340 additions & 1 deletion dist/bundle.js

Large diffs are not rendered by default.

20 changes: 16 additions & 4 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
font-family: Helvetica, sans-serif;
font-size: 20px;
--blur: 100;
--opacity: 0;
--opacity: 1;
--color: red;
}

body {
Expand All @@ -35,6 +36,7 @@
min-height: 100vh;
position: sticky;
top: 0;
color: var(--color);
font-size: calc(var(--size) * 1em);
}

Expand All @@ -48,11 +50,21 @@
class="container"
tg-name="size"
tg-edge="inset"
tg-from="14"
tg-from="10"
tg-to="20"
tg-bezier="0.23, 1.5, 0.32, 2"
tg-filter="10,15,28@"
tg-map="10: 5;15: 28;18: 20"
>
<div class="container" tg-name="opacity" tg-from="0" tg-to="1">
<div
class="container"
tg-name="color"
tg-edge="inset"
tg-steps="100"
tg-from="0"
tg-to="10"
tg-filter="0,5,10@"
tg-map="0: rgb(123, 234, 45);5: #ffd700;10: paleturquoise "
>
<div class="sticky">
<span>Hello.</span>
</div>
Expand Down
11 changes: 6 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"husky": "^7.0.0",
"lint-staged": "^11.2.5",
"prettier": "^2.4.1",
"rgb-color": "^2.1.2",
"typescript": "^4.4.4",
"webpack": "^5.59.0",
"webpack-cli": "^4.9.1"
Expand Down
53 changes: 53 additions & 0 deletions src/color.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// convert #hex notation to rgb array
const parseColor = function (hexStr: string): number[] {
return hexStr.length === 4
? hexStr
.substr(1)
.split('')
.map(function (s) {
return 0x11 * parseInt(s, 16);
})
: [hexStr.substr(1, 2), hexStr.substr(3, 2), hexStr.substr(5, 2)].map(
function (s) {
return parseInt(s, 16);
}
);
};

// zero-pad 1 digit to 2
const pad = function (s: string) {
return s.length === 1 ? '0' + s : s;
};

export const gradientColors = function (
startColor: string,
endColor: string,
steps: number,
gamma?: number
) {
let i,
j,
ms,
me,
output = [],
so = [];
gamma = gamma || 1;
let normalize = function (channel: number) {
return Math.pow(channel / 255, gamma as number);
};
const start = parseColor(startColor).map(normalize);
const end = parseColor(endColor).map(normalize);
for (i = 0; i < steps; i++) {
ms = i / (steps - 1);
me = 1 - ms;
for (j = 0; j < 3; j++) {
so[j] = pad(
Math.round(
Math.pow(start[j] * me + end[j] * ms, 1 / gamma) * 255
).toString(16)
);
}
output.push('#' + so.join(''));
}
return output;
};
5 changes: 4 additions & 1 deletion src/directives/tg-filter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export interface FilterValue {
mode: 'retain' | 'exact';
mode: 'retain' | 'exact' | 'smooth';
values: number[];
}

Expand All @@ -16,6 +16,9 @@ export function get(value?: string) {
if (value.substring(value.length - 1) === '!') {
filter.mode = 'exact';
value = value.substring(0, value.length - 1);
} else if (value.substring(value.length - 1) === '@') {
filter.mode = 'smooth';
value = value.substring(0, value.length - 1);
}

// Clean up all exclamation marks if added accidentally
Expand Down
34 changes: 34 additions & 0 deletions src/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import rgbcolor from 'rgb-color';

/**
* Calculate the length of decimal places for a number
* @param {number} number The number.
Expand All @@ -7,3 +9,35 @@ export function decimalsLength(number: number): number {
if (Math.floor(number) === number) return 0;
return number.toString().split('.')[1].length || 0;
}

// Judge the MapValue type
/***
* params: val
* return: {
* type: MapValue Type,
* val: Format Value
* }
*/
export function getMapTypeAndValue(val: string) {
// number
if (!isNaN(Number(val))) {
return {
type: 'number',
val: +val,
};
} else {
const color = rgbcolor(val);
// 'isValid()' is true when the parsing was a success
if (color.isValid()) {
return {
type: 'color',
val: color.hex(),
};
}
}
// unknown
return {
type: 'unknown',
val,
};
}
84 changes: 74 additions & 10 deletions src/parse.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { decimalsLength } from './helpers';
import { decimalsLength, getMapTypeAndValue } from './helpers';
import { extractValues } from './directives';
import { getPrefix } from './prefix';
import { FilterValue } from './directives/tg-filter';
import { EdgeOptions } from './directives/tg-edge';
import { TgElement } from './type';
import { easePercentage as ease } from './ease';
import { gradientColors } from './color';
import rgbcolor from 'rgb-color';

/**
* This function will be called in observe stage,
* caching those values into an object for ease of use in scroll event.
*/
export function parseAttributes(element: HTMLElement): TgElement {
const prefix = getPrefix()
const prefix = getPrefix();
const follow: HTMLElement = extractValues(element, `${prefix}follow`);

const actualElement = follow || element;
Expand Down Expand Up @@ -115,8 +117,6 @@ export function parseValues(elements: TgElement[]) {
)
: Math.min(Math.max((scrolled - top) / (height - clientHeight), 0), 1);



// Calculation result value of bezier
percentage = bezier ? ease(bezier, percentage) : percentage;

Expand All @@ -131,11 +131,22 @@ export function parseValues(elements: TgElement[]) {
if (filter.values.length > 0 && !filter.values.includes(value)) {
// If the mode is 'exact', remove the CSS property
// Setting the lastValue to null to ensure correct comparison below
if (filter.mode === 'exact') {
element.lastValue = null;
el.style.removeProperty(name);
if (filter.mode === 'smooth') {
let region = calcKeyFrameRegion(mapping, value);
// console.log(region);

if (region.length) {
value = calcKeyFrameValue(mapping, value, region);
} else {
return;
}
} else {
if (filter.mode === 'exact') {
element.lastValue = null;
el.style.removeProperty(name);
}
return;
}
return;
}

if (typeof mapping[value] !== 'undefined') {
Expand All @@ -155,7 +166,60 @@ export function parseValues(elements: TgElement[]) {
);

element.lastValue = value;
console.log('value', element, value);
}
});
}
}

// Calculate the result value of the keyframe corresponding to the current value
const calcKeyFrameValue = (
mapping: Record<string, string>,
value: number,
region: Array<any>
) => {
const [lkey, rkey] = region;
const lValue = getMapTypeAndValue(mapping[lkey]);
const rValue = getMapTypeAndValue(mapping[rkey]);
const curKeyRange = Math.abs(value - +lkey);
const percentage = curKeyRange / (rkey - lkey);
// If the value is a color value
if (rValue.type === 'color' && lValue.type === 'color') {
// TODO: Link the steps here with user settings……
const steps = 100;
const graColor = gradientColors(lValue.val, rValue.val, steps);
const key = (percentage * steps).toFixed(0);
return graColor[key];
} else {
const range = Math.abs(rValue.val - lValue.val);
const multiplier = lValue.val > rValue.val ? -1 : 1;
return lValue.val + range * percentage * multiplier;
}
};

// Calculate which range the current value is in the mapping
const calcKeyFrameRegion = (mapping: Record<string, string>, value: number) => {
if (Object.keys(mapping).length === 1) {
return [];
} else {
let lastKey = '',
currentKey = '';

for (const key of Object.getOwnPropertyNames(mapping).sort((a, b) => {
return +a - +b;
})) {
if (lastKey === null) {
lastKey = key;
continue;
} else {
currentKey = key;
if (
(value >= +lastKey && value <= +currentKey) ||
(value >= +currentKey && value <= +lastKey)
) {
return [lastKey, currentKey];
}
}
lastKey = key;
}
}
return [];
};
1 change: 1 addition & 0 deletions src/types/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
declare module 'rgb-color';