@studio-kit/utils-browser 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/package.json +3 -2
- package/src/DOM.js +5 -0
- package/src/Effect.js +8 -0
- package/src/Num.js +2 -0
- package/src/Style.js +21 -0
- package/src/UserInput.js +91 -0
- package/src/cta.js +189 -0
package/CHANGELOG.md
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@studio-kit/utils-browser",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
"author": "",
|
|
12
12
|
"license": "ISC",
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@studio-kit/utils-common": "^
|
|
14
|
+
"@studio-kit/utils-common": "^2.0.1",
|
|
15
15
|
"axios": "^1.7.9",
|
|
16
|
+
"chroma-js": "^3.1.2",
|
|
16
17
|
"nanoid": "^5.1.2"
|
|
17
18
|
},
|
|
18
19
|
"exports": {
|
package/src/DOM.js
CHANGED
package/src/Effect.js
ADDED
package/src/Num.js
ADDED
package/src/Style.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import chroma from 'chroma-js';
|
|
2
|
+
export default class Style {
|
|
3
|
+
static getCssVar({ varKey }) {
|
|
4
|
+
const root = document.documentElement;
|
|
5
|
+
const computedStyle = window.getComputedStyle(root);
|
|
6
|
+
// 获取CSS变量的值
|
|
7
|
+
const varValue = computedStyle.getPropertyValue(varKey);
|
|
8
|
+
return varValue
|
|
9
|
+
}
|
|
10
|
+
static getThemeImageFilter({ themeColor, imageColor = '#000000' }) {
|
|
11
|
+
const hue2 = this.createColor(themeColor).hsl()[0]
|
|
12
|
+
let hue1 = this.createColor(imageColor).hsl()[0]
|
|
13
|
+
if (!hue1) hue1 = 0
|
|
14
|
+
const hueRotation = (hue2 - hue1 + 360) % 360
|
|
15
|
+
return `hue-rotate(${hueRotation}deg)`
|
|
16
|
+
}
|
|
17
|
+
static createColor(cssColorString) {
|
|
18
|
+
cssColorString = cssColorString.replace(/\s/g, '')
|
|
19
|
+
return chroma(cssColorString)
|
|
20
|
+
}
|
|
21
|
+
}
|
package/src/UserInput.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
const defaultWindow = window
|
|
2
|
+
const useEventListener = (target, type, listener, options) => {
|
|
3
|
+
target = target || defaultWindow
|
|
4
|
+
console.log('target', target)
|
|
5
|
+
target.addEventListener(type, listener, options)
|
|
6
|
+
return () => target.removeEventListener(type, listener, options)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function createKeyPredicate(keyFilter) {
|
|
10
|
+
if (typeof keyFilter === "function") return keyFilter
|
|
11
|
+
else if (typeof keyFilter === "string")
|
|
12
|
+
return event => event.key === keyFilter
|
|
13
|
+
else if (Array.isArray(keyFilter))
|
|
14
|
+
return event => keyFilter.includes(event.key)
|
|
15
|
+
|
|
16
|
+
return () => true
|
|
17
|
+
}
|
|
18
|
+
export default class UserInput {
|
|
19
|
+
static onKeyStroke(...args) {
|
|
20
|
+
let key
|
|
21
|
+
let handler
|
|
22
|
+
let options = {}
|
|
23
|
+
|
|
24
|
+
if (args.length === 3) {
|
|
25
|
+
key = args[0]
|
|
26
|
+
handler = args[1]
|
|
27
|
+
options = args[2]
|
|
28
|
+
} else if (args.length === 2) {
|
|
29
|
+
if (typeof args[1] === "object") {
|
|
30
|
+
key = true
|
|
31
|
+
handler = args[0]
|
|
32
|
+
options = args[1]
|
|
33
|
+
} else {
|
|
34
|
+
key = args[0]
|
|
35
|
+
handler = args[1]
|
|
36
|
+
}
|
|
37
|
+
} else {
|
|
38
|
+
key = true
|
|
39
|
+
handler = args[0]
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const {
|
|
43
|
+
target = defaultWindow,
|
|
44
|
+
eventName = "keydown",
|
|
45
|
+
passive = false,
|
|
46
|
+
dedupe = false
|
|
47
|
+
} = options
|
|
48
|
+
const predicate = createKeyPredicate(key)
|
|
49
|
+
const listener = e => {
|
|
50
|
+
if (e.repeat && dedupe) return
|
|
51
|
+
if (predicate(e)) handler(e)
|
|
52
|
+
}
|
|
53
|
+
return useEventListener(target, eventName, listener, passive)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Listen to the keydown event of the given key.
|
|
59
|
+
*
|
|
60
|
+
* @see https://vueuse.org/onKeyStroke
|
|
61
|
+
* @param key
|
|
62
|
+
* @param handler
|
|
63
|
+
* @param options
|
|
64
|
+
*/
|
|
65
|
+
export function onKeyDown(key, handler, options = {}) {
|
|
66
|
+
return onKeyStroke(key, handler, { ...options, eventName: "keydown" })
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Listen to the keypress event of the given key.
|
|
71
|
+
*
|
|
72
|
+
* @see https://vueuse.org/onKeyStroke
|
|
73
|
+
* @param key
|
|
74
|
+
* @param handler
|
|
75
|
+
* @param options
|
|
76
|
+
*/
|
|
77
|
+
export function onKeyPressed(key, handler, options = {}) {
|
|
78
|
+
return onKeyStroke(key, handler, { ...options, eventName: "keypress" })
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Listen to the keyup event of the given key.
|
|
83
|
+
*
|
|
84
|
+
* @see https://vueuse.org/onKeyStroke
|
|
85
|
+
* @param key
|
|
86
|
+
* @param handler
|
|
87
|
+
* @param options
|
|
88
|
+
*/
|
|
89
|
+
export function onKeyUp(key, handler, options = {}) {
|
|
90
|
+
return onKeyStroke(key, handler, { ...options, eventName: "keyup" })
|
|
91
|
+
}
|
package/src/cta.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
var isSupportedBrowser = (function () {
|
|
2
|
+
// Firefox doesn't have `ontransitionend` on window. Hence we check for `transition`
|
|
3
|
+
// key in style object to check for unprefixed transition support.
|
|
4
|
+
return window.ontransitionend !== undefined || document.documentElement.style.transition !== undefined;
|
|
5
|
+
})();
|
|
6
|
+
|
|
7
|
+
// Credits to angular-animate for the nice animation duration detection code.
|
|
8
|
+
// Detect proper transitionend/animationend event names.
|
|
9
|
+
var TRANSITION_PROP, ANIMATION_PROP;
|
|
10
|
+
var DURATION_KEY = 'Duration';
|
|
11
|
+
var PROPERTY_KEY = 'Property';
|
|
12
|
+
var DELAY_KEY = 'Delay';
|
|
13
|
+
var ANIMATION_ITERATION_COUNT_KEY = 'IterationCount';
|
|
14
|
+
var ONE_SECOND = 1000;
|
|
15
|
+
|
|
16
|
+
if (window.ontransitionend === undefined && window.onwebkittransitionend !== undefined) {
|
|
17
|
+
TRANSITION_PROP = 'WebkitTransition';
|
|
18
|
+
} else {
|
|
19
|
+
TRANSITION_PROP = 'transition';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (window.onanimationend === undefined && window.onwebkitanimationend !== undefined) {
|
|
23
|
+
ANIMATION_PROP = 'WebkitAnimation';
|
|
24
|
+
} else {
|
|
25
|
+
ANIMATION_PROP = 'animation';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function parseMaxTime(str) {
|
|
29
|
+
var maxValue = 0, value;
|
|
30
|
+
var values = typeof (str) === 'string' ?
|
|
31
|
+
str.split(/\s*,\s*/) :
|
|
32
|
+
[];
|
|
33
|
+
for (var i = values.length; i--;) {
|
|
34
|
+
value = values[i];
|
|
35
|
+
maxValue = Math.max(parseFloat(value) || 0, maxValue);
|
|
36
|
+
}
|
|
37
|
+
return maxValue;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function getAnimationTime(element) {
|
|
41
|
+
var transitionDuration = 0;
|
|
42
|
+
var transitionDelay = 0;
|
|
43
|
+
var animationDuration = 0;
|
|
44
|
+
var animationDelay = 0;
|
|
45
|
+
var elementStyles = window.getComputedStyle(element) || {};
|
|
46
|
+
|
|
47
|
+
var transitionDurationStyle = elementStyles[TRANSITION_PROP + DURATION_KEY];
|
|
48
|
+
transitionDuration = Math.max(parseMaxTime(transitionDurationStyle), transitionDuration);
|
|
49
|
+
|
|
50
|
+
var transitionDelayStyle = elementStyles[TRANSITION_PROP + DELAY_KEY];
|
|
51
|
+
transitionDelay = Math.max(parseMaxTime(transitionDelayStyle), transitionDelay);
|
|
52
|
+
|
|
53
|
+
var animationDelayStyle = elementStyles[ANIMATION_PROP + DELAY_KEY];
|
|
54
|
+
animationDelay = Math.max(parseMaxTime(elementStyles[ANIMATION_PROP + DELAY_KEY]), animationDelay);
|
|
55
|
+
|
|
56
|
+
var aDuration = parseMaxTime(elementStyles[ANIMATION_PROP + DURATION_KEY]);
|
|
57
|
+
|
|
58
|
+
if (aDuration > 0) {
|
|
59
|
+
aDuration *= parseInt(elementStyles[ANIMATION_PROP + ANIMATION_ITERATION_COUNT_KEY], 10) || 1;
|
|
60
|
+
}
|
|
61
|
+
animationDuration = Math.max(aDuration, animationDuration);
|
|
62
|
+
|
|
63
|
+
return animationDuration || transitionDuration;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function getBackgroundStyle(element) {
|
|
67
|
+
var computedStyle = window.getComputedStyle(element);
|
|
68
|
+
// Need to fallback to `backgroundColor` as `background` return nothing in Firefox.
|
|
69
|
+
return computedStyle.background || computedStyle.backgroundColor;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
var defaults = {
|
|
73
|
+
duration: 0.3, // Duration for the animation to happen (seconds)
|
|
74
|
+
|
|
75
|
+
// Duration in which the target will become visible, (seconds)
|
|
76
|
+
targetShowDuration: 0,
|
|
77
|
+
|
|
78
|
+
// Extra time just to ensure continuity between dummy element and target (seconds)
|
|
79
|
+
extraTransitionDuration: 1,
|
|
80
|
+
|
|
81
|
+
// Whether to position the dummy animating element relative to window (fixed positioned) or not.
|
|
82
|
+
relativeToWindow: false
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
function cta(trigger, target, options, callback) {
|
|
86
|
+
// Support optional arguments
|
|
87
|
+
if (typeof options === 'function') {
|
|
88
|
+
callback = options;
|
|
89
|
+
options = {};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (!isSupportedBrowser) {
|
|
93
|
+
if (callback) {
|
|
94
|
+
callback(target);
|
|
95
|
+
}
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
var targetBackground,
|
|
100
|
+
triggerBackground,
|
|
101
|
+
targetBounds,
|
|
102
|
+
triggerBounds,
|
|
103
|
+
scaleXRatio,
|
|
104
|
+
scaleYRatio,
|
|
105
|
+
diffX,
|
|
106
|
+
diffY,
|
|
107
|
+
dummy;
|
|
108
|
+
|
|
109
|
+
options = options || {};
|
|
110
|
+
options.duration = options.duration || defaults.duration;
|
|
111
|
+
options.targetShowDuration = options.targetShowDuration || getAnimationTime(target) || defaults.targetShowDuration;
|
|
112
|
+
options.relativeToWindow = options.relativeToWindow || defaults.relativeToWindow;
|
|
113
|
+
options.extraTransitionDuration = options.extraTransitionDuration || defaults.extraTransitionDuration;
|
|
114
|
+
|
|
115
|
+
// Set some properties to make the target visible so we can get its dimensions.
|
|
116
|
+
// Set `display` to `block` only when its already hidden. Otherwise changing an already visible
|
|
117
|
+
// element's `display` property can lead to its position getting changed.
|
|
118
|
+
if (window.getComputedStyle(target).display === 'none') {
|
|
119
|
+
target.style.setProperty('display', 'block', 'important');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Calculate some property differences to animate.
|
|
123
|
+
targetBackground = getBackgroundStyle(target);
|
|
124
|
+
triggerBackground = getBackgroundStyle(trigger);
|
|
125
|
+
targetBounds = target.getBoundingClientRect();
|
|
126
|
+
triggerBounds = trigger.getBoundingClientRect();
|
|
127
|
+
scaleXRatio = triggerBounds.width / targetBounds.width;
|
|
128
|
+
scaleYRatio = triggerBounds.height / targetBounds.height;
|
|
129
|
+
diffX = triggerBounds.left - targetBounds.left;
|
|
130
|
+
diffY = triggerBounds.top - targetBounds.top;
|
|
131
|
+
|
|
132
|
+
// Remove the props we put earlier.
|
|
133
|
+
target.style.removeProperty('display');
|
|
134
|
+
|
|
135
|
+
// Create a dummy element for transition.
|
|
136
|
+
dummy = document.createElement('div');
|
|
137
|
+
dummy.style.setProperty('pointer-events', 'none', 'important');
|
|
138
|
+
dummy.style.setProperty('position', (options.relativeToWindow ? 'fixed' : 'absolute'), 'important');
|
|
139
|
+
dummy.style.setProperty('-webkit-transform-origin', 'top left', 'important');
|
|
140
|
+
dummy.style.setProperty('transform-origin', 'top left', 'important');
|
|
141
|
+
dummy.style.setProperty('transition', options.duration + 's ease');
|
|
142
|
+
|
|
143
|
+
// Set dummy element's dimensions to final state.
|
|
144
|
+
dummy.style.setProperty('width', targetBounds.width + 'px', 'important');
|
|
145
|
+
dummy.style.setProperty('height', targetBounds.height + 'px', 'important');
|
|
146
|
+
dummy.style.setProperty('left', (targetBounds.left + (options.relativeToWindow ? 0 : window.pageXOffset)) + 'px', 'important');
|
|
147
|
+
dummy.style.setProperty('top', (targetBounds.top + (options.relativeToWindow ? 0 : window.pageYOffset)) + 'px', 'important');
|
|
148
|
+
dummy.style.setProperty('background', triggerBackground, 'important');
|
|
149
|
+
dummy.style.setProperty('z-index', 1, 'important');
|
|
150
|
+
|
|
151
|
+
// Apply a reverse transform to bring back dummy element to the dimensions of the trigger/starting element.
|
|
152
|
+
// Credits: This technique is inspired by Paul Lewis: http://aerotwist.com/blog/flip-your-animations/ He is amazing!
|
|
153
|
+
dummy.style.setProperty('-webkit-transform', 'translate(' + diffX + 'px, ' + diffY + 'px) scale(' + scaleXRatio + ', ' + scaleYRatio + ')', 'important');
|
|
154
|
+
dummy.style.setProperty('transform', 'translate(' + diffX + 'px, ' + diffY + 'px) scale(' + scaleXRatio + ', ' + scaleYRatio + ')', 'important');
|
|
155
|
+
document.body.appendChild(dummy);
|
|
156
|
+
|
|
157
|
+
// Trigger a layout to let styles apply.
|
|
158
|
+
var justReadIt = dummy.offsetTop;
|
|
159
|
+
|
|
160
|
+
// Change properties to let things animate.
|
|
161
|
+
dummy.style.setProperty('background', targetBackground, 'important');
|
|
162
|
+
|
|
163
|
+
// Remove the reverse transforms to get the dummy transition back to its normal/final state.
|
|
164
|
+
dummy.style.removeProperty('-webkit-transform');
|
|
165
|
+
dummy.style.removeProperty('transform');
|
|
166
|
+
|
|
167
|
+
dummy.addEventListener('transitionend', function transitionEndCallback() {
|
|
168
|
+
dummy.removeEventListener('transitionend', transitionEndCallback);
|
|
169
|
+
|
|
170
|
+
if (callback) {
|
|
171
|
+
callback(target);
|
|
172
|
+
}
|
|
173
|
+
// Animate the dummy element to zero opacity while the target is getting rendered.
|
|
174
|
+
dummy.style.transitionDuration = (options.targetShowDuration + options.extraTransitionDuration) + 's';
|
|
175
|
+
dummy.style.opacity = 0;
|
|
176
|
+
setTimeout(function () {
|
|
177
|
+
dummy.parentNode.removeChild(dummy);
|
|
178
|
+
}, (options.targetShowDuration + options.extraTransitionDuration) * 1000);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Return a reverse animation function for the called animation.
|
|
182
|
+
return function (options, callback) {
|
|
183
|
+
cta(target, trigger, options, callback);
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
cta.isSupported = isSupportedBrowser;
|
|
188
|
+
|
|
189
|
+
export default cta;
|