26 constexpr static int kNumPaths = 1500;
34 glyph.reset(
fRand, fSize.width(), fSize.height());
46 for (
int i = 0; i < 52; ++i) {
48 char c =
"aQCDEFGH7JKLMNOPBRZTUVWXYSAbcdefghijk1mnopqrstuvwxyz"[i];
50 const SkGlyph* glyph = pathMaker.glyph(
id);
52 glyphPaths[i] = *glyph->
path();
56 for (
int i = 0; i < kNumPaths; ++i) {
57 const SkPath& p = glyphPaths[i % 52];
71 return fGlyphAnimator->animate(nanos, fSize.width(), fSize.height());
104 virtual bool animate(
double nanos,
int screenWidth,
int screenHeight) {
return false; }
106 for (
int i = 0; i < kNumPaths; ++i) {
139 int screensize = std::max(
w,
h);
144 t = pow(rand.
nextF(), 100);
145 fZoom = ((1 - t) * screensize / 50 + t * screensize / 3) /
146 std::max(bounds.width(), bounds.height());
147 fSpin = rand.
nextF() * 360;
148 fMidpt = {bounds.centerX(), bounds.centerY()};
166 const SkScalar screensize =
static_cast<SkScalar>(std::max(screenWidth, screenHeight));
171 *
d = ((1 - t) / 60 + t / 10) * (rand->
nextBool() ? screensize : -screensize);
175 v.fDSpin = ((1 - t) * 360 / 7.5 + t * 360 / 1.5) * (rand->
nextBool() ? 1 : -1);
185 bool animate(
double nanos,
int screenWidth,
int screenHeight)
final {
189 const double tsec = 1e-9 * nanos;
192 dt, screenWidth, screenHeight));
201 for (
int idx = 0; idx < kNumPaths; ++idx) {
238 for (
int i = 0; i < kNumPaths; ++i) {
265 , fFrontPaths(new
SkPath[kNumPaths])
266 , fBackPaths(new
SkPath[kNumPaths]) {
274 fWaves.reset(*rand, screenWidth, screenHeight);
276 std::copy(fBackPaths.get(), fBackPaths.get() + kNumPaths, fFrontPaths.get());
283 const float tsec =
static_cast<float>(t);
286 for (
int i = 0; i < kNumPaths; ++i) {
296 SkPath* backpath = &fBackPaths[i];
303 SkPoint pt = fWaves.apply(tsec, matrix, pts[0]);
308 SkPoint endpt = fWaves.apply(tsec, matrix, pts[1]);
309 backpath->
lineTo(endpt.
x(), endpt.
y());
313 SkPoint controlPt = fWaves.apply(tsec, matrix, pts[1]);
314 SkPoint endpt = fWaves.apply(tsec, matrix, pts[2]);
315 backpath->
quadTo(controlPt.
x(), controlPt.
y(), endpt.
x(), endpt.
y());
333 std::swap(fFrontPaths, fBackPaths);
337 for (
int i = 0; i < kNumPaths; ++i) {
352 constexpr static double kAverageAngle =
SK_ScalarPI / 8.0;
353 constexpr static double kMaxOffsetAngle =
SK_ScalarPI / 3.0;
355 float fAmplitudes[4];
356 float fFrequencies[4];
363 std::unique_ptr<SkPath[]> fFrontPaths;
364 std::unique_ptr<SkPath[]> fBackPaths;
368void PathTextSlide::WavyGlyphAnimator::Waves::reset(
SkRandom& rand,
int w,
int h) {
369 const double pixelsPerMeter = 0.06 * std::max(
w,
h);
370 const double medianWavelength = 8 * pixelsPerMeter;
371 const double medianWaveAmplitude = 0.05 * 4 * pixelsPerMeter;
372 const double gravity = 9.8 * pixelsPerMeter;
374 for (
int i = 0; i < 4; ++i) {
375 const double offsetAngle = (rand.
nextF() * 2 - 1) * kMaxOffsetAngle;
376 const double intensity = pow(2, rand.
nextF() * 2 - 1);
377 const double wavelength = intensity * medianWavelength;
379 fAmplitudes[i] = intensity * medianWaveAmplitude;
381 fDirsX[i] = cosf(kAverageAngle + offsetAngle);
382 fDirsY[i] = sinf(kAverageAngle + offsetAngle);
388SkPoint PathTextSlide::WavyGlyphAnimator::Waves::apply(
float tsec,
const skvx::float2 matrix[3],
390 constexpr static int kTablePeriod = 1 << 12;
391 static float sin2table[kTablePeriod + 1];
394 for (
int i = 0; i <= kTablePeriod; ++i) {
395 const double sintheta = sin(i * (
SK_ScalarPI / kTablePeriod));
396 sin2table[i] =
static_cast<float>(sintheta * sintheta - 0.5);
410 const skvx::float4 t =
abs(frequencies * (dirsX * devicePt[0] + dirsY * devicePt[1]) +
413 const skvx::int4 ipart = skvx::cast<int32_t>(t);
414 const skvx::float4 fpart = t - skvx::cast<float>(ipart);
417 (ipart & (kTablePeriod-1)).store(indices);
420 sin2table[indices[2]], sin2table[indices[3]]);
422 sin2table[indices[2] + 1], sin2table[indices[3] + 1]);
423 const auto height = amplitudes * (
left * (1.f - fpart) +
right * fpart);
#define SK_ABORT(message,...)
constexpr SkColor SK_ColorBLACK
@ kClose
SkPath::RawIter returns 0 points.
@ kCubic
SkPath::RawIter returns 4 points.
@ kConic
SkPath::RawIter returns 3 points + 1 weight.
@ kQuad
SkPath::RawIter returns 3 points.
@ kMove
SkPath::RawIter returns 1 point.
@ kLine
SkPath::RawIter returns 2 points.
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
virtual void draw(SkCanvas *canvas)
virtual void reset(SkRandom *, int screenWidth, int screenHeight)
virtual bool animate(double nanos, int screenWidth, int screenHeight)
GlyphAnimator(Glyph *glyphs)
void reset(SkRandom *rand, int screenWidth, int screenHeight) override
virtual void swapAnimationBuffers()
std::unique_ptr< SkMatrix[]> fFrontMatrices
virtual void runAnimationTask(double t, double dt, int w, int h)
SkTaskGroup fBackgroundAnimationTask
void draw(SkCanvas *canvas) override
bool animate(double nanos, int screenWidth, int screenHeight) final
~MovingGlyphAnimator() override
std::unique_ptr< SkMatrix[]> fBackMatrices
MovingGlyphAnimator(Glyph *glyphs)
Velocity fVelocities[kNumPaths]
WavyGlyphAnimator(Glyph *glyphs)
void draw(SkCanvas *canvas) override
~WavyGlyphAnimator() override
void reset(SkRandom *rand, int screenWidth, int screenHeight) override
void swapAnimationBuffers() override
void runAnimationTask(double t, double dt, int width, int height) override
void load(SkScalar w, SkScalar h) final
void draw(SkCanvas *canvas) override
std::unique_ptr< GlyphAnimator > fGlyphAnimator
bool onChar(SkUnichar) override
void resize(SkScalar w, SkScalar h) final
bool animate(double nanos) final
void translate(SkScalar dx, SkScalar dy)
void clear(SkColor color)
void rotate(SkScalar degrees)
void clipPath(const SkPath &path, SkClipOp op, bool doAntiAlias)
void drawPath(const SkPath &path, const SkPaint &paint)
void scale(SkScalar sx, SkScalar sy)
void concat(const SkMatrix &matrix)
SkGlyphID unicharToGlyph(SkUnichar uni) const
const SkPath * path() const
static SkMatrix Scale(SkScalar sx, SkScalar sy)
SkScalar getSkewY() const
SkScalar getTranslateY() const
SkMatrix & setTranslate(SkScalar dx, SkScalar dy)
SkScalar getSkewX() const
SkScalar getScaleX() const
SkMatrix & preTranslate(SkScalar dx, SkScalar dy)
SkMatrix & preRotate(SkScalar degrees, SkScalar px, SkScalar py)
SkScalar getScaleY() const
SkMatrix & preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
SkScalar getTranslateX() const
void setColor(SkColor color)
void setAntiAlias(bool aa)
SkPath & moveTo(SkScalar x, SkScalar y)
void setFillType(SkPathFillType ft)
SkPath & lineTo(SkScalar x, SkScalar y)
SkPath & quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2)
const SkRect & getBounds() const
void transform(const SkMatrix &matrix, SkPath *dst, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
static SkStrikeSpec MakeWithNoDevice(const SkFont &font, const SkPaint *paint=nullptr)
void add(std::function< void(void)> fn)
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
unsigned useCenter Optional< SkMatrix > matrix
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
SIN Vec< N, float > abs(const Vec< N, float > &x)
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
void reset(SkRandom &rand, int w, int h)
void init(SkRandom &rand, const SkPath &path)
constexpr float y() const
constexpr float x() const
static SKVX_ALWAYS_INLINE Vec Load(const void *ptr)