diff --git a/Gaze/Animations/blink.json b/Gaze/Animations/blink.json index c777111..3043c25 100644 --- a/Gaze/Animations/blink.json +++ b/Gaze/Animations/blink.json @@ -8,6 +8,7 @@ "nm": "Blink Animation", "ddd": 0, "assets": [], + "date": "2026-01-09T00:00:00Z", "layers": [ { "ddd": 0, @@ -16,11 +17,38 @@ "nm": "Eye Container", "sr": 1, "ks": { - "o": {"a": 0, "k": 100}, - "r": {"a": 0, "k": 0}, - "p": {"a": 0, "k": [100, 100, 0]}, - "a": {"a": 0, "k": [0, 0, 0]}, - "s": {"a": 0, "k": [100, 100, 100]} + "o": { + "a": 0, + "k": 100 + }, + "r": { + "a": 0, + "k": 0 + }, + "p": { + "a": 0, + "k": [ + 100, + 100, + 0 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } }, "ao": 0, "shapes": [ @@ -29,37 +57,130 @@ "it": [ { "ty": "el", - "p": {"a": 0, "k": [0, 0]}, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, "s": { "a": 1, "k": [ - {"t": 0, "s": [80, 80], "h": 1}, - {"t": 15, "s": [80, 80], "h": 1}, - {"t": 20, "s": [80, 10], "h": 1}, - {"t": 25, "s": [80, 80], "h": 1}, - {"t": 35, "s": [80, 80], "h": 1}, - {"t": 40, "s": [80, 10], "h": 1}, - {"t": 45, "s": [80, 80], "h": 1} + { + "t": 0, + "s": [ + 80, + 80 + ], + "h": 1 + }, + { + "t": 15, + "s": [ + 80, + 80 + ], + "h": 1 + }, + { + "t": 20, + "s": [ + 80, + 10 + ], + "h": 1 + }, + { + "t": 25, + "s": [ + 80, + 80 + ], + "h": 1 + }, + { + "t": 35, + "s": [ + 80, + 80 + ], + "h": 1 + }, + { + "t": 40, + "s": [ + 80, + 10 + ], + "h": 1 + }, + { + "t": 45, + "s": [ + 80, + 80 + ], + "h": 1 + } ] }, "nm": "Eye Ellipse" }, { "ty": "st", - "c": {"a": 0, "k": [0, 0.478, 1, 1]}, - "o": {"a": 0, "k": 100}, - "w": {"a": 0, "k": 8}, + "c": { + "a": 0, + "k": [ + 0, + 0.478, + 1, + 1 + ] + }, + "o": { + "a": 0, + "k": 100 + }, + "w": { + "a": 0, + "k": 8 + }, "lc": 2, "lj": 2, "nm": "Stroke" }, { "ty": "tr", - "p": {"a": 0, "k": [0, 0]}, - "a": {"a": 0, "k": [0, 0]}, - "s": {"a": 0, "k": [100, 100]}, - "r": {"a": 0, "k": 0}, - "o": {"a": 0, "k": 100} + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } } ], "nm": "Eye Shape" @@ -77,11 +198,38 @@ "nm": "Pupil", "sr": 1, "ks": { - "o": {"a": 0, "k": 100}, - "r": {"a": 0, "k": 0}, - "p": {"a": 0, "k": [100, 100, 0]}, - "a": {"a": 0, "k": [0, 0, 0]}, - "s": {"a": 0, "k": [100, 100, 100]} + "o": { + "a": 0, + "k": 100 + }, + "r": { + "a": 0, + "k": 0 + }, + "p": { + "a": 0, + "k": [ + 100, + 100, + 0 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } }, "ao": 0, "shapes": [ @@ -90,31 +238,105 @@ "it": [ { "ty": "el", - "p": {"a": 0, "k": [0, 0]}, - "s": {"a": 0, "k": [25, 25]}, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 25, + 25 + ] + }, "nm": "Pupil Ellipse" }, { "ty": "fl", - "c": {"a": 0, "k": [0, 0.478, 1, 1]}, - "o": {"a": 0, "k": 100}, + "c": { + "a": 0, + "k": [ + 0, + 0.478, + 1, + 1 + ] + }, + "o": { + "a": 0, + "k": 100 + }, "r": 1, "nm": "Fill" }, { "ty": "tr", - "p": {"a": 0, "k": [0, 0]}, - "a": {"a": 0, "k": [0, 0]}, - "s": {"a": 0, "k": [100, 100]}, - "r": {"a": 0, "k": 0}, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, "o": { "a": 1, "k": [ - {"t": 0, "s": [100], "h": 1}, - {"t": 20, "s": [0], "h": 1}, - {"t": 25, "s": [100], "h": 1}, - {"t": 40, "s": [0], "h": 1}, - {"t": 45, "s": [100], "h": 1} + { + "t": 0, + "s": [ + 100 + ], + "h": 1 + }, + { + "t": 20, + "s": [ + 0 + ], + "h": 1 + }, + { + "t": 25, + "s": [ + 100 + ], + "h": 1 + }, + { + "t": 40, + "s": [ + 0 + ], + "h": 1 + }, + { + "t": 45, + "s": [ + 100 + ], + "h": 1 + } ] } } diff --git a/Gaze/Animations/look-away.json b/Gaze/Animations/look-away.json index a560808..185222f 100644 --- a/Gaze/Animations/look-away.json +++ b/Gaze/Animations/look-away.json @@ -8,6 +8,7 @@ "nm": "Look Away Animation", "ddd": 0, "assets": [], + "date": "2026-01-09T00:00:00Z", "layers": [ { "ddd": 0, @@ -16,11 +17,38 @@ "nm": "Face Circle", "sr": 1, "ks": { - "o": {"a": 0, "k": 100}, - "r": {"a": 0, "k": 0}, - "p": {"a": 0, "k": [100, 100, 0]}, - "a": {"a": 0, "k": [0, 0, 0]}, - "s": {"a": 0, "k": [100, 100, 100]} + "o": { + "a": 0, + "k": 100 + }, + "r": { + "a": 0, + "k": 0 + }, + "p": { + "a": 0, + "k": [ + 100, + 100, + 0 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } }, "ao": 0, "shapes": [ @@ -29,26 +57,76 @@ "it": [ { "ty": "el", - "p": {"a": 0, "k": [0, 0]}, - "s": {"a": 0, "k": [150, 150]}, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 150, + 150 + ] + }, "nm": "Face Ellipse" }, { "ty": "st", - "c": {"a": 0, "k": [0, 0.478, 1, 1]}, - "o": {"a": 0, "k": 100}, - "w": {"a": 0, "k": 6}, + "c": { + "a": 0, + "k": [ + 0, + 0.478, + 1, + 1 + ] + }, + "o": { + "a": 0, + "k": 100 + }, + "w": { + "a": 0, + "k": 6 + }, "lc": 2, "lj": 2, "nm": "Stroke" }, { "ty": "tr", - "p": {"a": 0, "k": [0, 0]}, - "a": {"a": 0, "k": [0, 0]}, - "s": {"a": 0, "k": [100, 100]}, - "r": {"a": 0, "k": 0}, - "o": {"a": 0, "k": 100} + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } } ], "nm": "Face" @@ -66,11 +144,38 @@ "nm": "Left Eye", "sr": 1, "ks": { - "o": {"a": 0, "k": 100}, - "r": {"a": 0, "k": 0}, - "p": {"a": 0, "k": [70, 85, 0]}, - "a": {"a": 0, "k": [0, 0, 0]}, - "s": {"a": 0, "k": [100, 100, 100]} + "o": { + "a": 0, + "k": 100 + }, + "r": { + "a": 0, + "k": 0 + }, + "p": { + "a": 0, + "k": [ + 70, + 85, + 0 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } }, "ao": 0, "shapes": [ @@ -79,15 +184,41 @@ "it": [ { "ty": "el", - "p": {"a": 0, "k": [0, 0]}, - "s": {"a": 0, "k": [20, 20]}, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 20, + 20 + ] + }, "nm": "Eye Ellipse" }, { "ty": "st", - "c": {"a": 0, "k": [0, 0.478, 1, 1]}, - "o": {"a": 0, "k": 100}, - "w": {"a": 0, "k": 4}, + "c": { + "a": 0, + "k": [ + 0, + 0.478, + 1, + 1 + ] + }, + "o": { + "a": 0, + "k": 100 + }, + "w": { + "a": 0, + "k": 4 + }, "lc": 2, "lj": 2, "nm": "Stroke" @@ -97,21 +228,157 @@ "p": { "a": 1, "k": [ - {"t": 0, "s": [0, 0], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 20, "s": [-20, -8], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 40, "s": [-25, 5], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 60, "s": [0, 8], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 80, "s": [25, 5], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 100, "s": [20, -8], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 120, "s": [0, -15], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 140, "s": [0, -8], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 150, "s": [0, 0]} + { + "t": 0, + "s": [ + 0, + 0 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 20, + "s": [ + -20, + -8 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 40, + "s": [ + -25, + 5 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 60, + "s": [ + 0, + 8 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 80, + "s": [ + 25, + 5 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 100, + "s": [ + 20, + -8 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 120, + "s": [ + 0, + -15 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 140, + "s": [ + 0, + -8 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 150, + "s": [ + 0, + 0 + ] + } ] }, - "a": {"a": 0, "k": [0, 0]}, - "s": {"a": 0, "k": [100, 100]}, - "r": {"a": 0, "k": 0}, - "o": {"a": 0, "k": 100} + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } } ], "nm": "Eye" @@ -121,14 +388,37 @@ "it": [ { "ty": "el", - "p": {"a": 0, "k": [0, 0]}, - "s": {"a": 0, "k": [8, 8]}, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 8, + 8 + ] + }, "nm": "Pupil Ellipse" }, { "ty": "fl", - "c": {"a": 0, "k": [0, 0.478, 1, 1]}, - "o": {"a": 0, "k": 100}, + "c": { + "a": 0, + "k": [ + 0, + 0.478, + 1, + 1 + ] + }, + "o": { + "a": 0, + "k": 100 + }, "r": 1, "nm": "Fill" }, @@ -137,21 +427,157 @@ "p": { "a": 1, "k": [ - {"t": 0, "s": [0, 0], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 20, "s": [-20, -8], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 40, "s": [-25, 5], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 60, "s": [0, 8], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 80, "s": [25, 5], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 100, "s": [20, -8], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 120, "s": [0, -15], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 140, "s": [0, -8], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 150, "s": [0, 0]} + { + "t": 0, + "s": [ + 0, + 0 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 20, + "s": [ + -20, + -8 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 40, + "s": [ + -25, + 5 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 60, + "s": [ + 0, + 8 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 80, + "s": [ + 25, + 5 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 100, + "s": [ + 20, + -8 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 120, + "s": [ + 0, + -15 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 140, + "s": [ + 0, + -8 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 150, + "s": [ + 0, + 0 + ] + } ] }, - "a": {"a": 0, "k": [0, 0]}, - "s": {"a": 0, "k": [100, 100]}, - "r": {"a": 0, "k": 0}, - "o": {"a": 0, "k": 100} + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } } ], "nm": "Pupil" @@ -169,11 +595,38 @@ "nm": "Right Eye", "sr": 1, "ks": { - "o": {"a": 0, "k": 100}, - "r": {"a": 0, "k": 0}, - "p": {"a": 0, "k": [130, 85, 0]}, - "a": {"a": 0, "k": [0, 0, 0]}, - "s": {"a": 0, "k": [100, 100, 100]} + "o": { + "a": 0, + "k": 100 + }, + "r": { + "a": 0, + "k": 0 + }, + "p": { + "a": 0, + "k": [ + 130, + 85, + 0 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ] + } }, "ao": 0, "shapes": [ @@ -182,15 +635,41 @@ "it": [ { "ty": "el", - "p": {"a": 0, "k": [0, 0]}, - "s": {"a": 0, "k": [20, 20]}, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 20, + 20 + ] + }, "nm": "Eye Ellipse" }, { "ty": "st", - "c": {"a": 0, "k": [0, 0.478, 1, 1]}, - "o": {"a": 0, "k": 100}, - "w": {"a": 0, "k": 4}, + "c": { + "a": 0, + "k": [ + 0, + 0.478, + 1, + 1 + ] + }, + "o": { + "a": 0, + "k": 100 + }, + "w": { + "a": 0, + "k": 4 + }, "lc": 2, "lj": 2, "nm": "Stroke" @@ -200,21 +679,157 @@ "p": { "a": 1, "k": [ - {"t": 0, "s": [0, 0], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 20, "s": [-20, -8], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 40, "s": [-25, 5], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 60, "s": [0, 8], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 80, "s": [25, 5], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 100, "s": [20, -8], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 120, "s": [0, -15], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 140, "s": [0, -8], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 150, "s": [0, 0]} + { + "t": 0, + "s": [ + 0, + 0 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 20, + "s": [ + -20, + -8 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 40, + "s": [ + -25, + 5 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 60, + "s": [ + 0, + 8 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 80, + "s": [ + 25, + 5 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 100, + "s": [ + 20, + -8 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 120, + "s": [ + 0, + -15 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 140, + "s": [ + 0, + -8 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 150, + "s": [ + 0, + 0 + ] + } ] }, - "a": {"a": 0, "k": [0, 0]}, - "s": {"a": 0, "k": [100, 100]}, - "r": {"a": 0, "k": 0}, - "o": {"a": 0, "k": 100} + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } } ], "nm": "Eye" @@ -224,14 +839,37 @@ "it": [ { "ty": "el", - "p": {"a": 0, "k": [0, 0]}, - "s": {"a": 0, "k": [8, 8]}, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 8, + 8 + ] + }, "nm": "Pupil Ellipse" }, { "ty": "fl", - "c": {"a": 0, "k": [0, 0.478, 1, 1]}, - "o": {"a": 0, "k": 100}, + "c": { + "a": 0, + "k": [ + 0, + 0.478, + 1, + 1 + ] + }, + "o": { + "a": 0, + "k": 100 + }, "r": 1, "nm": "Fill" }, @@ -240,21 +878,157 @@ "p": { "a": 1, "k": [ - {"t": 0, "s": [0, 0], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 20, "s": [-20, -8], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 40, "s": [-25, 5], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 60, "s": [0, 8], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 80, "s": [25, 5], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 100, "s": [20, -8], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 120, "s": [0, -15], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 140, "s": [0, -8], "i": {"x": 0.4, "y": 1}, "o": {"x": 0.6, "y": 0}}, - {"t": 150, "s": [0, 0]} + { + "t": 0, + "s": [ + 0, + 0 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 20, + "s": [ + -20, + -8 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 40, + "s": [ + -25, + 5 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 60, + "s": [ + 0, + 8 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 80, + "s": [ + 25, + 5 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 100, + "s": [ + 20, + -8 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 120, + "s": [ + 0, + -15 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 140, + "s": [ + 0, + -8 + ], + "i": { + "x": 0.4, + "y": 1 + }, + "o": { + "x": 0.6, + "y": 0 + } + }, + { + "t": 150, + "s": [ + 0, + 0 + ] + } ] }, - "a": {"a": 0, "k": [0, 0]}, - "s": {"a": 0, "k": [100, 100]}, - "r": {"a": 0, "k": 0}, - "o": {"a": 0, "k": 100} + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } } ], "nm": "Pupil" diff --git a/Gaze/Animations/posture.json b/Gaze/Animations/posture.json index c9179a0..15f188a 100644 --- a/Gaze/Animations/posture.json +++ b/Gaze/Animations/posture.json @@ -8,6 +8,7 @@ "nm": "Posture Arrow Animation", "ddd": 0, "assets": [], + "date": "2026-01-09T00:00:00Z", "layers": [ { "ddd": 0, @@ -19,29 +20,119 @@ "o": { "a": 1, "k": [ - {"t": 0, "s": [0], "h": 1}, - {"t": 10, "s": [100], "h": 1}, - {"t": 60, "s": [100], "h": 1}, - {"t": 70, "s": [0], "h": 1} + { + "t": 0, + "s": [ + 0 + ], + "h": 1 + }, + { + "t": 10, + "s": [ + 100 + ], + "h": 1 + }, + { + "t": 60, + "s": [ + 100 + ], + "h": 1 + }, + { + "t": 70, + "s": [ + 0 + ], + "h": 1 + } ] }, - "r": {"a": 0, "k": 0}, + "r": { + "a": 0, + "k": 0 + }, "p": { "a": 1, "k": [ - {"t": 0, "s": [100, 200, 0], "h": 1}, - {"t": 60, "s": [100, 200, 0], "h": 1}, - {"t": 90, "s": [100, -100, 0], "h": 1} + { + "t": 0, + "s": [ + 100, + 200, + 0 + ], + "h": 1 + }, + { + "t": 60, + "s": [ + 100, + 200, + 0 + ], + "h": 1 + }, + { + "t": 90, + "s": [ + 100, + -100, + 0 + ], + "h": 1 + } + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 ] }, - "a": {"a": 0, "k": [0, 0, 0]}, "s": { "a": 1, "k": [ - {"t": 0, "s": [0, 0, 100], "h": 1}, - {"t": 10, "s": [100, 100, 100], "h": 1}, - {"t": 60, "s": [100, 100, 100], "h": 1}, - {"t": 70, "s": [50, 50, 100], "h": 1} + { + "t": 0, + "s": [ + 0, + 0, + 100 + ], + "h": 1 + }, + { + "t": 10, + "s": [ + 100, + 100, + 100 + ], + "h": 1 + }, + { + "t": 60, + "s": [ + 100, + 100, + 100 + ], + "h": 1 + }, + { + "t": 70, + "s": [ + 50, + 50, + 100 + ], + "h": 1 + } ] } }, @@ -55,16 +146,95 @@ "ks": { "a": 0, "k": { - "i": [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], - "o": [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], + "i": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], "v": [ - [0, -40], - [-30, -10], - [-12, -10], - [-12, 40], - [12, 40], - [12, -10], - [30, -10] + [ + 0, + -40 + ], + [ + -30, + -10 + ], + [ + -12, + -10 + ], + [ + -12, + 40 + ], + [ + 12, + 40 + ], + [ + 12, + -10 + ], + [ + 30, + -10 + ] ], "c": true } @@ -73,18 +243,53 @@ }, { "ty": "fl", - "c": {"a": 0, "k": [0, 0, 0, 1]}, - "o": {"a": 0, "k": 100}, + "c": { + "a": 0, + "k": [ + 0, + 0, + 0, + 1 + ] + }, + "o": { + "a": 0, + "k": 100 + }, "r": 1, "nm": "Fill" }, { "ty": "tr", - "p": {"a": 0, "k": [0, 0]}, - "a": {"a": 0, "k": [0, 0]}, - "s": {"a": 0, "k": [100, 100]}, - "r": {"a": 0, "k": 0}, - "o": {"a": 0, "k": 100} + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } } ], "nm": "Arrow Shape" @@ -105,29 +310,119 @@ "o": { "a": 1, "k": [ - {"t": 0, "s": [0], "h": 1}, - {"t": 10, "s": [100], "h": 1}, - {"t": 60, "s": [100], "h": 1}, - {"t": 70, "s": [0], "h": 1} + { + "t": 0, + "s": [ + 0 + ], + "h": 1 + }, + { + "t": 10, + "s": [ + 100 + ], + "h": 1 + }, + { + "t": 60, + "s": [ + 100 + ], + "h": 1 + }, + { + "t": 70, + "s": [ + 0 + ], + "h": 1 + } ] }, - "r": {"a": 0, "k": 0}, + "r": { + "a": 0, + "k": 0 + }, "p": { "a": 1, "k": [ - {"t": 0, "s": [100, 200, 0], "h": 1}, - {"t": 60, "s": [100, 200, 0], "h": 1}, - {"t": 90, "s": [100, -100, 0], "h": 1} + { + "t": 0, + "s": [ + 100, + 200, + 0 + ], + "h": 1 + }, + { + "t": 60, + "s": [ + 100, + 200, + 0 + ], + "h": 1 + }, + { + "t": 90, + "s": [ + 100, + -100, + 0 + ], + "h": 1 + } + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0, + 0 ] }, - "a": {"a": 0, "k": [0, 0, 0]}, "s": { "a": 1, "k": [ - {"t": 0, "s": [0, 0, 100], "h": 1}, - {"t": 10, "s": [100, 100, 100], "h": 1}, - {"t": 60, "s": [100, 100, 100], "h": 1}, - {"t": 70, "s": [50, 50, 100], "h": 1} + { + "t": 0, + "s": [ + 0, + 0, + 100 + ], + "h": 1 + }, + { + "t": 10, + "s": [ + 100, + 100, + 100 + ], + "h": 1 + }, + { + "t": 60, + "s": [ + 100, + 100, + 100 + ], + "h": 1 + }, + { + "t": 70, + "s": [ + 50, + 50, + 100 + ], + "h": 1 + } ] } }, @@ -138,24 +433,71 @@ "it": [ { "ty": "el", - "p": {"a": 0, "k": [0, 0]}, - "s": {"a": 0, "k": [120, 120]}, + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 120, + 120 + ] + }, "nm": "Circle Ellipse" }, { "ty": "fl", - "c": {"a": 0, "k": [0.9, 0.9, 0.9, 1]}, - "o": {"a": 0, "k": 30}, + "c": { + "a": 0, + "k": [ + 0.9, + 0.9, + 0.9, + 1 + ] + }, + "o": { + "a": 0, + "k": 30 + }, "r": 1, "nm": "Fill" }, { "ty": "tr", - "p": {"a": 0, "k": [0, 0]}, - "a": {"a": 0, "k": [0, 0]}, - "s": {"a": 0, "k": [100, 100]}, - "r": {"a": 0, "k": 0}, - "o": {"a": 0, "k": 100} + "p": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ] + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ] + }, + "r": { + "a": 0, + "k": 0 + }, + "o": { + "a": 0, + "k": 100 + } } ], "nm": "Circle" diff --git a/Gaze/Models/AppSettings.swift b/Gaze/Models/AppSettings.swift index 1cd9d67..52f1301 100644 --- a/Gaze/Models/AppSettings.swift +++ b/Gaze/Models/AppSettings.swift @@ -7,11 +7,23 @@ import Foundation +// MARK: - Centralized Configuration System + +/// Unified configuration class that manages all app settings in a centralized way struct AppSettings: Codable, Equatable { + // Timer configurations var lookAwayTimer: TimerConfiguration var lookAwayCountdownSeconds: Int var blinkTimer: TimerConfiguration var postureTimer: TimerConfiguration + + // User-defined timers (up to 3) + var userTimers: [UserTimer] + + // UI and display settings + var subtleReminderSizePercentage: Double // 2-35% of screen width + + // App state and behavior var hasCompletedOnboarding: Bool var launchAtLogin: Bool var playSounds: Bool @@ -20,8 +32,10 @@ struct AppSettings: Codable, Equatable { AppSettings( lookAwayTimer: TimerConfiguration(enabled: true, intervalSeconds: 20 * 60), lookAwayCountdownSeconds: 20, - blinkTimer: TimerConfiguration(enabled: true, intervalSeconds: 5 * 60), + blinkTimer: TimerConfiguration(enabled: false, intervalSeconds: 7 * 60), postureTimer: TimerConfiguration(enabled: true, intervalSeconds: 30 * 60), + userTimers: [], + subtleReminderSizePercentage: 5.0, hasCompletedOnboarding: false, launchAtLogin: false, playSounds: true @@ -33,6 +47,8 @@ struct AppSettings: Codable, Equatable { lhs.lookAwayCountdownSeconds == rhs.lookAwayCountdownSeconds && lhs.blinkTimer == rhs.blinkTimer && lhs.postureTimer == rhs.postureTimer && + lhs.userTimers == rhs.userTimers && + lhs.subtleReminderSizePercentage == rhs.subtleReminderSizePercentage && lhs.hasCompletedOnboarding == rhs.hasCompletedOnboarding && lhs.launchAtLogin == rhs.launchAtLogin && lhs.playSounds == rhs.playSounds diff --git a/Gaze/Models/UserTimer.swift b/Gaze/Models/UserTimer.swift new file mode 100644 index 0000000..0dedff5 --- /dev/null +++ b/Gaze/Models/UserTimer.swift @@ -0,0 +1,51 @@ +// +// UserTimer.swift +// Gaze +// +// Created by Mike Freno on 1/9/26. +// + +import Foundation + +/// Represents a user-defined timer with customizable properties +struct UserTimer: Codable, Equatable { + let id: String + var type: UserTimerType + var timeOnScreenSeconds: Int + var message: String? + + init( + id: String = UUID().uuidString, + type: UserTimerType = .subtle, + timeOnScreenSeconds: Int = 30, + message: String? = nil + ) { + self.id = id + self.type = type + self.timeOnScreenSeconds = timeOnScreenSeconds + self.message = message + } + + static func == (lhs: UserTimer, rhs: UserTimer) -> Bool { + lhs.id == rhs.id && lhs.type == rhs.type + && lhs.timeOnScreenSeconds == rhs.timeOnScreenSeconds && lhs.message == rhs.message + } +} + +/// Type of user timer - subtle or overlay +enum UserTimerType: String, Codable, CaseIterable, Identifiable { + case subtle + case overlay + + var id: String { rawValue } + + var displayName: String { + switch self { + case .subtle: + return "Subtle" + case .overlay: + return "Overlay" + } + } +} + diff --git a/Gaze/Services/AnimationService.swift b/Gaze/Services/AnimationService.swift new file mode 100644 index 0000000..8bc8fbb --- /dev/null +++ b/Gaze/Services/AnimationService.swift @@ -0,0 +1,68 @@ +// +// AnimationService.swift +// Gaze +// +// Created by Mike Freno on 1/9/26. +// + +import Foundation + +@MainActor +class AnimationService { + static let shared = AnimationService() + + private init() {} + + struct RemoteAnimation: Codable { + let name: String + let version: String + let date: String // ISO 8601 formatted date string + + enum CodingKeys: String, CodingKey { + case name, version, date + } + } + + struct RemoteAnimationsResponse: Codable { + let animations: [RemoteAnimation] + } + + // MARK: - Public Methods + + func fetchRemoteAnimations() async throws -> [RemoteAnimation] { + guard let url = URL(string: "https://freno.me/api/Gaze/animations") else { + throw URLError(.badURL) + } + + let (data, response) = try await URLSession.shared.data(from: url) + + guard let httpResponse = response as? HTTPURLResponse else { + throw URLError(.badServerResponse) + } + + guard 200...299 ~= httpResponse.statusCode else { + throw URLError(.badServerResponse) + } + + do { + let decoder = JSONDecoder() + let remoteAnimations = try decoder.decode(RemoteAnimationsResponse.self, from: data) + return remoteAnimations.animations + } catch { + throw error + } + } + + func updateLocalAnimationsIfNeeded(remoteAnimations: [RemoteAnimation]) async throws { + // For now, just validate the API response structure. + // In a real implementation, this would: + // 1. Compare dates of local vs remote animations + // 2. Update local files if newer versions exist + // 3. Tag local files with date fields in ISO 8601 format + + for animation in remoteAnimations { + print("Remote animation: \(animation.name) - \(animation.version) - \(animation.date)") + } + } +} + diff --git a/GazeTests/Services/AnimationServiceTests.swift b/GazeTests/Services/AnimationServiceTests.swift new file mode 100644 index 0000000..872f882 --- /dev/null +++ b/GazeTests/Services/AnimationServiceTests.swift @@ -0,0 +1,17 @@ +// +// AnimationServiceTests.swift +// GazeTests +// +// Created by Mike Freno on 1/9/26. +// + +@testable import Gaze + +final class AnimationServiceTests { + // Test cases can be added here as needed + + func testRemoteAnimationDecoding() { + // This will be implemented when we have a testable implementation + } +} +