Skip to content

Commit

Permalink
Merge pull request #2691 from framer/fix/mix-immediate-invalid-color
Browse files Browse the repository at this point in the history
Updating interpolation for invalid colors
  • Loading branch information
mergetron[bot] authored May 31, 2024
2 parents a58d3e7 + d3248d2 commit 565f4f3
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,9 @@ test("mixColor rgba with slash (without slash spaces) to rgba without", () => {
test("doesn't return NaN", () => {
expect(mixLinearColor(255, 0, 2)).not.toBeNaN()
})

test("mixColor mixes immediately with unknown color", () => {
expect(mixColor("red", "rgba(0, 0, 0, 0)")(0)).toBe("red")
expect(mixColor("red", "rgba(0, 0, 0, 0)")(0.5)).toBe("rgba(0, 0, 0, 0)")
expect(mixColor("red", "rgba(0, 0, 0, 0)")(1)).toBe("rgba(0, 0, 0, 0)")
})
11 changes: 9 additions & 2 deletions packages/framer-motion/src/utils/mix/color.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { mixNumber } from "./number"
import { invariant } from "../errors"
import { warning } from "../errors"
import { hslaToRgba } from "../hsla-to-rgba"
import { hex } from "../../value/types/color/hex"
import { rgba } from "../../value/types/color/rgba"
import { hsla } from "../../value/types/color/hsla"
import { Color, HSLA, RGBA } from "../../value/types/types"
import { mixImmediate } from "./immediate"

// Linear color space blending
// Explained https://www.youtube.com/watch?v=LKnqECcg6Gw
Expand All @@ -22,11 +23,13 @@ const getColorType = (v: Color | string) =>
function asRGBA(color: Color | string) {
const type = getColorType(color)

invariant(
warning(
Boolean(type),
`'${color}' is not an animatable color. Use the equivalent color code instead.`
)

if (!Boolean(type)) return false

let model = type!.parse(color)

if (type === hsla) {
Expand All @@ -41,6 +44,10 @@ export const mixColor = (from: Color | string, to: Color | string) => {
const fromRGBA = asRGBA(from)
const toRGBA = asRGBA(to)

if (!fromRGBA || !toRGBA) {
return mixImmediate(from, to)
}

const blended = { ...fromRGBA }

return (v: number) => {
Expand Down
5 changes: 1 addition & 4 deletions packages/framer-motion/src/utils/mix/complex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,13 @@ import {
} from "../../value/types/complex"
import { isCSSVariableToken } from "../../render/dom/utils/is-css-variable"
import { invisibleValues, mixVisibility } from "./visibility"
import { mixImmediate } from "./immediate"

type MixableArray = Array<number | RGBA | HSLA | string>
type MixableObject = {
[key: string]: string | number | RGBA | HSLA
}

function mixImmediate<T>(a: T, b: T) {
return (p: number) => (p > 0 ? b : a)
}

function mixNumber(a: number, b: number) {
return (p: number) => mixNumberImmediate(a, b, p)
}
Expand Down
3 changes: 3 additions & 0 deletions packages/framer-motion/src/utils/mix/immediate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function mixImmediate<T>(a: T, b: T) {
return (p: number) => (p > 0 ? b : a)
}

0 comments on commit 565f4f3

Please sign in to comment.