|
1 | 1 | #!/usr/bin/env python3 |
2 | 2 |
|
3 | 3 | from videocode import * |
| 4 | +from videocode.template.effect.other.highlight import highlight |
| 5 | +from videocode.template.input.YStack import Paragraphe |
| 6 | +from videocode.template.input._inputs import * |
| 7 | +from videocode.utils.bezier import _exponential, _exponentialDecay, _rushFrom, _smooth |
4 | 8 |
|
5 | | -BG = LinearGradient(rgba(10, 12, 20), rgba(30, 10, 18)) |
| 9 | +PAUSE_DELAY = 0.4 |
6 | 10 |
|
7 | | -Text("Latest Feature", fontSize=0.3, fillColor=WHITE | 0.65).position(0, 3.2).fadeIn(duration=0.4) |
| 11 | +# Splitted Screen |
| 12 | +sv = SplitView(ratio=3 / 4) |
8 | 13 |
|
9 | | -title = Text("FIRE", fontSize=2.8, fillColor=fire(speed=2.2, quality=0.9)).position(0, 1.0) |
10 | | -title.fadeIn(duration=0.8) |
| 14 | +# Left side as a Paragraph |
| 15 | +para = Paragraphe(gap=0.18).position(x=sv.a.left, y=sv.a.top) |
11 | 16 |
|
12 | | -bar = Rectangle(width=8.8, height=0.34, cornerRadius=20, fillColor=WHITE | 0.12).position(0, -1.35) |
13 | | -bar.apply(lightSweep(width=24, intensity=0.9, angle=18), duration=5.4) |
| 17 | +timestamp("code: create rectangle") |
| 18 | +para.add(Code("from videocode import *")).newline() |
| 19 | +para.add(textRect := Code("r = Rectangle(width=1.5, height=1)")) |
14 | 20 |
|
15 | | -caption = Text("shader fills + selective clock pausing", fontSize=0.22, fillColor=WHITE | 0.72).position(0, -2.2) |
16 | | -caption.fadeIn(duration=0.4) |
| 21 | +timestamp("show: rectangle") |
| 22 | +rect = Rectangle(width=1.5, height=1, cornerRadius=15, fillColor=BLUE_C, strokeColor=WHITE) |
| 23 | +dims = RectangleDimensions(rect).opacity(0) |
| 24 | +rect.position(sv.b.cx, sv.b.cy).opacity(0).waitFor(para).wait(PAUSE_DELAY).fadeIn() |
17 | 25 |
|
18 | | -phase1 = Text("wait(1.2) -> flames keep moving", fontSize=0.2, fillColor=WHITE).position(0, -3.0) |
19 | | -phase1.fadeIn(duration=0.25) |
20 | | -wait(1.2) |
| 26 | +timestamp("show: rectangle dimensions") |
| 27 | +dims.waitFor(rect).wait(PAUSE_DELAY).fadeIn().flush() |
| 28 | +rect.waitFor(dims).wait(PAUSE_DELAY) |
21 | 29 |
|
22 | | -phase1.fadeOut(duration=0.2) |
23 | | -phase2 = Text("wait(1.2, stop=Clock.PAINTS) -> fire freezes, sweep keeps moving", fontSize=0.18, fillColor=WHITE).position(0, -3.0) |
24 | | -phase2.fadeIn(duration=0.2) |
25 | | -wait(1.2, stop=Clock.PAINTS) |
| 30 | +timestamp("code: scale up rectangle") |
| 31 | +para.waitFor(rect).add(textScale := Code("r.scaleTo(factor=2, duration=0.6)")) |
26 | 32 |
|
27 | | -phase2.fadeOut(duration=0.2) |
28 | | -phase3 = Text("freeze(1.2) -> paints and effects pause together", fontSize=0.18, fillColor=WHITE).position(0, -3.0) |
29 | | -phase3.fadeIn(duration=0.2) |
30 | | -freeze(1.2) |
| 33 | +timestamp("show: scale up rectangle") |
| 34 | +rect.waitFor(para).wait(PAUSE_DELAY).easeTogether( |
| 35 | + (rect.ref.width, rect.width * 2), |
| 36 | + (rect.ref.height, rect.height * 2), |
| 37 | + duration=0.6, |
| 38 | +) |
31 | 39 |
|
32 | | -phase3.fadeOut(duration=0.3) |
33 | | -Text("fire(), silk(), starNest(), mathShader(...)", fontSize=0.2, fillColor=WHITE | 0.85).position(0, -3.0).fadeIn(duration=0.3) |
34 | | -wait(1.8) |
| 40 | +timestamp("show: hide dimensions") |
| 41 | +dims.waitFor(rect).wait(PAUSE_DELAY).fadeOut() |
| 42 | + |
| 43 | +timestamp("code: change rect fillcolor to red") |
| 44 | +para.waitFor(dims).wait(PAUSE_DELAY).newline() |
| 45 | +para.add(textFill1 := Code("r.fill(LinearGradient(RED, BLUE))")) |
| 46 | +para.add(textFill2 := Code("r.fill(LinearGradient(RED, GREEN))")) |
| 47 | + |
| 48 | +timestamp("show: rect fillcolor to red") |
| 49 | +rect.waitFor(para).wait(PAUSE_DELAY) |
| 50 | +for p in Easing.ExponentialDecay.range(0, 100, duration=2.4): |
| 51 | + rect.fillColor = LinearGradient((RED_B, p), BLUE_C) |
| 52 | + rect.flush() |
| 53 | +for p in Easing.ExponentialDecay.range(0, 50, duration=1.2): |
| 54 | + rect.fillColor = LinearGradient((RED_B, 100 - p), GREEN_A) |
| 55 | + rect.flush() |
| 56 | + |
| 57 | + |
| 58 | +timestamp("show: cleanup") |
| 59 | +pts = Group(textRect, textScale, textFill1, textFill2, rect).waitForOthers().fadeOut() |
| 60 | +para.curY = 0 |
| 61 | +para.newline().newline() |
| 62 | + |
| 63 | +# wait() |
| 64 | +timestamp("text: balls") |
| 65 | +para.waitFor(pts) |
| 66 | +para.add(textp1 := Code("p1 = Circle(radius=0.25)")) |
| 67 | +para.add(textp2 := Code("p2 = Circle(radius=0.25)")) |
| 68 | +para.add(textp3 := Code("p3 = Circle(radius=0.25)")) |
| 69 | +para.add(textBalls := Code("balls = XAlign(1.75, p1, p2, p3)")) |
| 70 | +para.newline() |
| 71 | + |
| 72 | + |
| 73 | +timestamp("show: balls") |
| 74 | +rad = 0.25 |
| 75 | +gap = 1.75 |
| 76 | +w = rad + gap |
| 77 | +p1 = Circle(radius=rad, fillColor=BLUE_C, strokeWidth=0.03) |
| 78 | +p2 = Circle(radius=rad, fillColor=BLUE_C, strokeWidth=0.03) |
| 79 | +p3 = Circle(radius=rad, fillColor=BLUE_C, strokeWidth=0.03) |
| 80 | +ltop = DashedLine(x1=sv.b.cx - w, y1=sv.b.cy + 2.5 + rad, x2=sv.b.cx + w, y2=sv.b.cy + 2.5 + rad, strokeWidth=0.04, color=WHITE | 0.5) |
| 81 | +lbot = DashedLine(x1=sv.b.cx - w, y1=sv.b.cy + 1 - rad, x2=sv.b.cx + w, y2=sv.b.cy + 1 - rad, strokeWidth=0.04, color=WHITE | 0.5) |
| 82 | +t1 = Text("InOut", fontSize=0.2) |
| 83 | +t2 = Text("ExpoDecay", fontSize=0.2) |
| 84 | +t3 = Text("Expo", fontSize=0.2) |
| 85 | + |
| 86 | +g1 = FunctionGraph(_smooth, (0, 1)) |
| 87 | +g2 = FunctionGraph(_exponentialDecay, (0, 1)) |
| 88 | +g3 = FunctionGraph(_exponential, (0, 1)) |
| 89 | + |
| 90 | +pts = XAlign[Circle](gap, p1, p2, p3).position(sv.b.cx, sv.b.cy + 1) |
| 91 | +txt = XAlign(gap, t1, t2, t3).position(sv.b.cx, sv.b.cy) |
| 92 | +grs = XAlign(gap, g1, g2, g3).position(sv.b.cx - 0.5, sv.b.cy - 1.5) |
| 93 | +g = Group(ltop, lbot, pts, txt, grs).opacity(0).waitFor(para).wait(PAUSE_DELAY).fadeIn().wait(PAUSE_DELAY * 2) |
| 94 | + |
| 95 | +timestamp("text: move balls") |
| 96 | +para.waitFor(g).wait(PAUSE_DELAY) |
| 97 | +para.add(textb1 := Code("for i, input in enumerate(balls):")) |
| 98 | +para.add(textb2 := Code(" ease = [Smooth, ExpoDecay, Expo][i]")) |
| 99 | +para.add(textb3 := Code(" input.moveBy(y=+1.5, easing=ease).flush()")) |
| 100 | +para.add(textb4 := Code(" input.moveBy(y=-1.5, easing=ease).flush()")) |
| 101 | + |
| 102 | + |
| 103 | +timestamp("show: move balls") |
| 104 | +pts.waitFor(para).wait(PAUSE_DELAY * 2) |
| 105 | +for i, input in enumerate(pts): |
| 106 | + ease = [Easing.Smooth, Easing.ExponentialDecay, Easing.Exponential][i] |
| 107 | + input.moveBy(y=1.5, easing=ease, duration=2).wait(PAUSE_DELAY).moveBy(y=-1.5, easing=ease, duration=2).flush() |
| 108 | + |
| 109 | +timestamp("show: cleanup2") |
| 110 | +g = Group(textp1, textp2, textp3, textBalls, textb1, textb2, textb3, textb4, g).waitForOthers().wait(PAUSE_DELAY * 2).fadeOut() |
| 111 | +para.curY = 0 |
| 112 | +para.newline().newline() |
| 113 | + |
| 114 | +timestamp("text: text") |
| 115 | +para.add(textnbr1 := Code('nbr = Text("125376890123")')).newline() |
| 116 | + |
| 117 | +timestamp("show: text") |
| 118 | +nbr = Text("125376890123", fontSize=0.25).position(sv.b.x, sv.b.y).opacity(0).waitFor(para).fadeIn().flush() |
| 119 | + |
| 120 | +timestamp("text: highlight") |
| 121 | +para.waitFor(nbr).add(textnbr2 := Code('twelve = nbr.find("12")')) |
| 122 | +para.add(textnbr3 := Code("twelve.apply(highlight()).flush()")) |
| 123 | + |
| 124 | +timestamp("show: highlight text") |
| 125 | +nbr.waitFor(para).wait(PAUSE_DELAY * 2).find("12").apply(highlight()) |
| 126 | +nbr.waitForOthers().wait(PAUSE_DELAY) |
| 127 | + |
| 128 | +timestamp("text: highlight2") |
| 129 | +para.waitFor(nbr).add(textnbr4 := Code("twelve.apply(highlight(scale=2, color=RED))")).newline() |
| 130 | + |
| 131 | +timestamp("show: highlight text2") |
| 132 | +nbr.waitFor(para).wait(PAUSE_DELAY).find("12").apply(highlight(scale=2, color=RED_B)) |
| 133 | + |
| 134 | +timestamp("text: radiant text") |
| 135 | +para.waitFor(nbr).add(textnbr5 := Code("nbr.fill(LinearGradient(BLUE, RED)")) |
| 136 | + |
| 137 | +timestamp("show: radiant text") |
| 138 | +nbr.waitFor(para).wait(PAUSE_DELAY).fill(LinearGradient(BLUE_C, RED_B)) |
| 139 | + |
| 140 | +timestamp("show: cleanup3") |
| 141 | +g = Group(nbr, textnbr1, textnbr2, textnbr3, textnbr4, textnbr5).waitForOthers().wait(PAUSE_DELAY * 2).fadeOut() |
| 142 | +para.curY = 0 |
| 143 | +para.newline().newline() |
| 144 | + |
| 145 | +timestamp("text: image") |
| 146 | +para.waitFor(g).add(textImg1 := Code('img = Image("wb.png").fadeIn().scaleTo(2)')).newline() |
| 147 | + |
| 148 | +timestamp("show: image") |
| 149 | +img = Image("wb.png").position(sv.b.x, sv.b.y).opacity(0).waitFor(para).wait(PAUSE_DELAY).fadeIn().scaleTo(2).flush() |
| 150 | + |
| 151 | +timestamp("text: image lightsweep") |
| 152 | +para.waitFor(img).wait(PAUSE_DELAY).add(textImg2 := Code("img.apply(lightSweep(width=10), duration=2)")).newline() |
| 153 | + |
| 154 | +timestamp("show: image lightsweep") |
| 155 | +img.waitFor(para).wait(PAUSE_DELAY).apply(lightSweep(width=10), duration=1.6).flush() |
| 156 | + |
| 157 | +timestamp("text: image blur") |
| 158 | +para.waitFor(img).wait(PAUSE_DELAY).add(textImg3 := Code("img.apply(blur(5), duration=2)")) |
| 159 | + |
| 160 | +timestamp("show: image blur") |
| 161 | +img.waitFor(para).wait(PAUSE_DELAY).apply(blur(5), duration=2) |
| 162 | + |
| 163 | +timestamp("show: cleanup4") |
| 164 | +g = Group(textImg1, textImg2, textImg3, img).waitForOthers().wait(PAUSE_DELAY).fadeOut() |
| 165 | + |
| 166 | +timestamp("show: square") |
| 167 | +para.waitFor(g) |
| 168 | +para.curY = 0 |
| 169 | +para.newline().newline().wait(PAUSE_DELAY).add(textG1 := Code("s = Square()")) |
| 170 | +s = Square(side=1, cornerRadius=15, fillColor=BLUE_C, strokeColor=WHITE).opacity(0).waitFor(para).position(sv.b.x, sv.b.y).fadeIn() |
| 171 | +timestamp("text: move square") |
| 172 | +para.waitFor(s).wait(PAUSE_DELAY).add(textG2 := Code("s.moveBy(x=-1)")) |
| 173 | +timestamp("show: move square") |
| 174 | +s.waitFor(para).moveBy(x=-1.25) |
| 175 | + |
| 176 | +timestamp("text: circle") |
| 177 | +para.waitFor(s).wait(PAUSE_DELAY).add(textG3 := Code("c = Circle()")) |
| 178 | +c = Circle(radius=0.5, fillColor=RED_B, strokeColor=WHITE).opacity(0).waitFor(para).position(sv.b.x, sv.b.y).fadeIn() |
| 179 | +timestamp("text: move circle") |
| 180 | +para.waitFor(c).wait(PAUSE_DELAY).add(textG4 := Code("c.moveBy(x=1)")) |
| 181 | +timestamp("show: move circle") |
| 182 | +c.waitFor(para).moveBy(x=1.25) |
| 183 | + |
| 184 | +timestamp("text: group") |
| 185 | +para.newline().waitFor(c).wait(PAUSE_DELAY).add(textG5 := Code("g = Group(s, c)")) |
| 186 | +timestamp("text: group rotation") |
| 187 | +para.add(textG6 := Code("g.rotateBy(180).flush()")) |
| 188 | +timestamp("show: group rotation") |
| 189 | +g = Group(s, c).waitFor(para).wait(PAUSE_DELAY).rotateBy(180, duration=1.2).flush() |
| 190 | + |
| 191 | +timestamp("text: group scale down and rotate") |
| 192 | +para.waitFor(g).wait(PAUSE_DELAY).add(textG7 := Code("g.scaleTo(0.5).rotateBy(180)")) |
| 193 | +timestamp("show: group scale down") |
| 194 | +g.waitFor(para).wait(PAUSE_DELAY).scaleTo(0.5, duration=1.2).rotateBy(180, duration=1.2) |
| 195 | + |
| 196 | + |
| 197 | +# timestamp("show: cleanup5") |
| 198 | +# g = Group(textG1, textG2, textG3, textG4, textG5, textG6, textG7, s, c).waitForOthers().wait(PAUSE_DELAY).fadeOut() |
| 199 | +# para.curY = 0 |
| 200 | +# para.newline().newline() |
| 201 | + |
| 202 | +# timestamp("show: text fire") |
| 203 | +# title = Text("FIREPLACE", fontSize=1, fillColor=fire(speed=1)).position(sv.b.x, sv.b.y).opacity(0).waitFor(g).wait(PAUSE_DELAY).fadeIn() |
| 204 | + |
| 205 | + |
| 206 | +# bg — created last so drift() starts at the end of existing content |
| 207 | +para = Plane().drift() |
0 commit comments