skia2/samplecode/SampleGlyphTransform.cpp
Ben Wagner 14884cd86c Beautify GlyphTransform sample.
The glyph transform sample often looks empty when seen in Viewer since
it doesn't loop and the drawing is often out of range by the time the
sample is seen. Make the sample loop, correct 't' to be in milliseconds,
correct 'sq' to sqrt, move the origin to the draw, make the text draw
centered at the origin, and update the animation based on the size of
the sample.

Change-Id: Ia87817db6981ee73a50793b39696ef393ff26df8
Reviewed-on: https://skia-review.googlesource.com/147283
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
2018-08-16 14:17:46 +00:00

88 lines
2.4 KiB
C++

/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "Sample.h"
#include "sk_tool_utils.h"
#include "SkAnimTimer.h"
#include "SkCanvas.h"
#include "SkPath.h"
#include "SkRandom.h"
#include "SkRRect.h"
#include "SkTypeface.h"
#include <cmath>
// Implementation in C++ of Animated Emoji
// See https://t.d3fc.io/status/705212795936247808
// See https://crbug.com/848616
class GlyphTransformView : public Sample {
public:
GlyphTransformView() {}
protected:
void onOnceBeforeDraw() override {
fEmojiFont.fTypeface = sk_tool_utils::emoji_typeface();
fEmojiFont.fText = sk_tool_utils::emoji_sample_text();
}
bool onQuery(Sample::Event* evt) override {
if (Sample::TitleQ(*evt)) {
Sample::TitleR(evt, "Glyph Transform");
return true;
}
return this->INHERITED::onQuery(evt);
}
void onDrawContent(SkCanvas* canvas) override {
SkPaint paint;
paint.setTypeface(fEmojiFont.fTypeface);
const char* text = fEmojiFont.fText;
double baseline = this->height() / 2;
canvas->drawLine(0, baseline, this->width(), baseline, paint);
SkMatrix ctm;
ctm.setRotate(fRotate); // d3 rotate takes degrees
ctm.postScale(fScale * 4, fScale * 4);
ctm.postTranslate(fTranslate.fX + this->width() * 0.8, fTranslate.fY + baseline);
canvas->concat(ctm);
// d3 by default anchors text around the middle
SkRect bounds;
paint.measureText(text, strlen(text), &bounds);
canvas->drawString(text, -bounds.centerX(), -bounds.centerY(), paint);
}
bool onAnimate(const SkAnimTimer& timer) override {
constexpr SkScalar maxt = 100000;
double t = timer.pingPong(20, 0, 0, maxt); // d3 t is in milliseconds
fTranslate.set(sin(t / 3000) - t * this->width() * 0.7 / maxt, sin(t / 999) / t);
fScale = 4.5 - std::sqrt(t) / 99;
fRotate = sin(t / 734);
return true;
}
private:
struct EmojiFont {
sk_sp<SkTypeface> fTypeface;
const char* fText;
} fEmojiFont;
SkVector fTranslate;
SkScalar fScale;
SkScalar fRotate;
typedef Sample INHERITED;
};
//////////////////////////////////////////////////////////////////////////////
DEF_SAMPLE( return new GlyphTransformView(); )