fetta 1.4.3 → 1.4.4
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/dist/{chunk-24TCJGUM.js → chunk-Y4GCLM4K.js} +38 -73
- package/dist/index.js +1 -1
- package/dist/react.js +1 -1
- package/package.json +11 -2
|
@@ -122,58 +122,9 @@ function copyKerningStyles(target, styles) {
|
|
|
122
122
|
if (value) target.style.setProperty(prop, value);
|
|
123
123
|
});
|
|
124
124
|
}
|
|
125
|
-
function buildCanvasFontString(styles) {
|
|
126
|
-
const fontStyle = styles.fontStyle || "normal";
|
|
127
|
-
const fontWeight = styles.fontWeight || "normal";
|
|
128
|
-
const fontSize = styles.fontSize || "16px";
|
|
129
|
-
const fontFamily = styles.fontFamily || "sans-serif";
|
|
130
|
-
return [fontStyle, fontWeight, fontSize, fontFamily].filter(Boolean).join(" ");
|
|
131
|
-
}
|
|
132
|
-
function applyKerningStylesToCanvas(ctx, styles) {
|
|
133
|
-
ctx.font = buildCanvasFontString(styles);
|
|
134
|
-
const ctxAny = ctx;
|
|
135
|
-
const setIfExists = (prop, value) => {
|
|
136
|
-
if (!value || value === "normal") return;
|
|
137
|
-
if (prop in ctxAny) ctxAny[prop] = value;
|
|
138
|
-
};
|
|
139
|
-
setIfExists("fontKerning", styles.getPropertyValue("font-kerning"));
|
|
140
|
-
setIfExists("fontVariantLigatures", styles.getPropertyValue("font-variant-ligatures"));
|
|
141
|
-
setIfExists("fontFeatureSettings", styles.getPropertyValue("font-feature-settings"));
|
|
142
|
-
setIfExists("fontVariationSettings", styles.getPropertyValue("font-variation-settings"));
|
|
143
|
-
setIfExists("fontOpticalSizing", styles.getPropertyValue("font-optical-sizing"));
|
|
144
|
-
setIfExists("fontSizeAdjust", styles.getPropertyValue("font-size-adjust"));
|
|
145
|
-
setIfExists("fontStretch", styles.getPropertyValue("font-stretch"));
|
|
146
|
-
setIfExists("fontVariantCaps", styles.getPropertyValue("font-variant-caps"));
|
|
147
|
-
setIfExists("fontVariantNumeric", styles.getPropertyValue("font-variant-numeric"));
|
|
148
|
-
setIfExists("fontVariantEastAsian", styles.getPropertyValue("font-variant-east-asian"));
|
|
149
|
-
setIfExists("fontSynthesis", styles.getPropertyValue("font-synthesis"));
|
|
150
|
-
setIfExists("fontSynthesisWeight", styles.getPropertyValue("font-synthesis-weight"));
|
|
151
|
-
setIfExists("fontSynthesisStyle", styles.getPropertyValue("font-synthesis-style"));
|
|
152
|
-
setIfExists("letterSpacing", styles.getPropertyValue("letter-spacing"));
|
|
153
|
-
setIfExists("wordSpacing", styles.getPropertyValue("word-spacing"));
|
|
154
|
-
setIfExists("textRendering", styles.getPropertyValue("text-rendering"));
|
|
155
|
-
setIfExists("direction", styles.getPropertyValue("direction"));
|
|
156
|
-
}
|
|
157
125
|
function buildKerningStyleKey(styles) {
|
|
158
126
|
return KERNING_STYLE_PROPS.map((prop) => styles.getPropertyValue(prop)).join("|");
|
|
159
127
|
}
|
|
160
|
-
function shouldUseDomKerning(styles) {
|
|
161
|
-
const textTransform = styles.getPropertyValue("text-transform");
|
|
162
|
-
if (textTransform && textTransform !== "none") return true;
|
|
163
|
-
const fontVariant = styles.getPropertyValue("font-variant");
|
|
164
|
-
if (fontVariant && fontVariant !== "normal") return true;
|
|
165
|
-
const fontStretch = styles.getPropertyValue("font-stretch");
|
|
166
|
-
if (fontStretch && fontStretch !== "normal" && fontStretch !== "100%") return true;
|
|
167
|
-
const fontFeatureSettings = styles.getPropertyValue("font-feature-settings");
|
|
168
|
-
if (fontFeatureSettings && fontFeatureSettings !== "normal") return true;
|
|
169
|
-
const fontVariationSettings = styles.getPropertyValue("font-variation-settings");
|
|
170
|
-
if (fontVariationSettings && fontVariationSettings !== "normal") return true;
|
|
171
|
-
const fontOpticalSizing = styles.getPropertyValue("font-optical-sizing");
|
|
172
|
-
if (fontOpticalSizing && fontOpticalSizing !== "auto") return true;
|
|
173
|
-
const fontSizeAdjust = styles.getPropertyValue("font-size-adjust");
|
|
174
|
-
if (fontSizeAdjust && fontSizeAdjust !== "none") return true;
|
|
175
|
-
return false;
|
|
176
|
-
}
|
|
177
128
|
var isSafariBrowser = null;
|
|
178
129
|
function isSafari() {
|
|
179
130
|
if (isSafariBrowser !== null) return isSafariBrowser;
|
|
@@ -181,29 +132,6 @@ function isSafari() {
|
|
|
181
132
|
isSafariBrowser = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
182
133
|
return isSafariBrowser;
|
|
183
134
|
}
|
|
184
|
-
function measureKerningCanvas(styleSource, chars, styles) {
|
|
185
|
-
const kerningMap = /* @__PURE__ */ new Map();
|
|
186
|
-
if (chars.length < 2) return kerningMap;
|
|
187
|
-
const canvas = document.createElement("canvas");
|
|
188
|
-
const ctx = canvas.getContext("2d");
|
|
189
|
-
if (!ctx) return kerningMap;
|
|
190
|
-
const computedStyles = styles != null ? styles : getComputedStyle(styleSource);
|
|
191
|
-
applyKerningStylesToCanvas(ctx, computedStyles);
|
|
192
|
-
const charWidths = /* @__PURE__ */ new Map();
|
|
193
|
-
for (const char of new Set(chars)) {
|
|
194
|
-
charWidths.set(char, ctx.measureText(char).width);
|
|
195
|
-
}
|
|
196
|
-
for (let i = 0; i < chars.length - 1; i++) {
|
|
197
|
-
const char1 = chars[i];
|
|
198
|
-
const char2 = chars[i + 1];
|
|
199
|
-
const pairWidth = ctx.measureText(char1 + char2).width;
|
|
200
|
-
const kerning = pairWidth - charWidths.get(char1) - charWidths.get(char2);
|
|
201
|
-
if (Math.abs(kerning) > 1e-3) {
|
|
202
|
-
kerningMap.set(i + 1, kerning);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
return kerningMap;
|
|
206
|
-
}
|
|
207
135
|
function measureKerningDOM(container, styleSource, chars, styles) {
|
|
208
136
|
const kerningMap = /* @__PURE__ */ new Map();
|
|
209
137
|
if (chars.length < 2) return kerningMap;
|
|
@@ -242,10 +170,47 @@ function measureKerningDOM(container, styleSource, chars, styles) {
|
|
|
242
170
|
container.removeChild(measurer);
|
|
243
171
|
return kerningMap;
|
|
244
172
|
}
|
|
173
|
+
function measureKerningRange(container, styleSource, chars, styles) {
|
|
174
|
+
const kerningMap = /* @__PURE__ */ new Map();
|
|
175
|
+
if (chars.length < 2) return kerningMap;
|
|
176
|
+
const measurer = document.createElement("span");
|
|
177
|
+
measurer.style.cssText = "position:absolute;visibility:hidden;white-space:pre;";
|
|
178
|
+
const computedStyles = styles != null ? styles : getComputedStyle(styleSource);
|
|
179
|
+
copyKerningStyles(measurer, computedStyles);
|
|
180
|
+
container.appendChild(measurer);
|
|
181
|
+
const range = document.createRange();
|
|
182
|
+
const measureWidth = () => {
|
|
183
|
+
const textNode = measurer.firstChild;
|
|
184
|
+
if (!textNode) return 0;
|
|
185
|
+
range.selectNodeContents(textNode);
|
|
186
|
+
return range.getBoundingClientRect().width;
|
|
187
|
+
};
|
|
188
|
+
const charWidths = /* @__PURE__ */ new Map();
|
|
189
|
+
for (const char of new Set(chars)) {
|
|
190
|
+
measurer.textContent = char;
|
|
191
|
+
charWidths.set(char, measureWidth());
|
|
192
|
+
}
|
|
193
|
+
for (let i = 0; i < chars.length - 1; i++) {
|
|
194
|
+
const char1 = chars[i];
|
|
195
|
+
const char2 = chars[i + 1];
|
|
196
|
+
measurer.textContent = char1 + char2;
|
|
197
|
+
const kerning = measureWidth() - charWidths.get(char1) - charWidths.get(char2);
|
|
198
|
+
if (Math.abs(kerning) > 1e-3) {
|
|
199
|
+
kerningMap.set(i + 1, kerning);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
range.detach();
|
|
203
|
+
container.removeChild(measurer);
|
|
204
|
+
return kerningMap;
|
|
205
|
+
}
|
|
245
206
|
function measureKerning(container, styleSource, chars, styles) {
|
|
246
207
|
if (chars.length < 2) return /* @__PURE__ */ new Map();
|
|
208
|
+
if (!container.isConnected) {
|
|
209
|
+
console.warn("splitText: kerning measurement requires a connected DOM element. Skipping kerning.");
|
|
210
|
+
return /* @__PURE__ */ new Map();
|
|
211
|
+
}
|
|
247
212
|
const computedStyles = styles != null ? styles : getComputedStyle(styleSource);
|
|
248
|
-
return isSafari()
|
|
213
|
+
return isSafari() ? measureKerningDOM(container, styleSource, chars, computedStyles) : measureKerningRange(container, styleSource, chars, computedStyles);
|
|
249
214
|
}
|
|
250
215
|
var srOnlyStylesInjected = false;
|
|
251
216
|
function injectSrOnlyStyles() {
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { splitText } from './chunk-
|
|
1
|
+
export { splitText } from './chunk-Y4GCLM4K.js';
|
package/dist/react.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { splitText, __spreadProps, __spreadValues, normalizeToPromise } from './chunk-
|
|
1
|
+
import { splitText, __spreadProps, __spreadValues, normalizeToPromise } from './chunk-Y4GCLM4K.js';
|
|
2
2
|
import { forwardRef, useRef, useCallback, useState, useLayoutEffect, useEffect, isValidElement, cloneElement } from 'react';
|
|
3
3
|
import { jsx } from 'react/jsx-runtime';
|
|
4
4
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fetta",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.4",
|
|
4
4
|
"description": "Text splitting library with kerning compensation for animations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -80,11 +80,20 @@
|
|
|
80
80
|
"keywords": [
|
|
81
81
|
"text",
|
|
82
82
|
"split",
|
|
83
|
+
"split-text",
|
|
84
|
+
"splittext",
|
|
85
|
+
"text-animation",
|
|
86
|
+
"text-effect",
|
|
83
87
|
"animation",
|
|
84
88
|
"motion",
|
|
85
89
|
"kerning",
|
|
86
90
|
"typography",
|
|
87
|
-
"gsap"
|
|
91
|
+
"gsap",
|
|
92
|
+
"javascript",
|
|
93
|
+
"typescript",
|
|
94
|
+
"react",
|
|
95
|
+
"web-animation",
|
|
96
|
+
"accessible"
|
|
88
97
|
],
|
|
89
98
|
"license": "MIT",
|
|
90
99
|
"author": "dimi",
|