blob: 47f2231908ae6393193cf382c59343da88c90051 [file] [log] [blame]
// Copyright 2019 Google LLC.
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "tools/skottie_ios_app/SkottieUIView.h"
#include "tools/skottie_ios_app/SkAnimationDraw.h"
#include "tools/skottie_ios_app/SkTimeKeeper.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkPaint.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTime.h"
#include "include/utils/mac/SkCGUtils.h"
#include "modules/skottie/include/Skottie.h"
@implementation SkottieUIView {
SkAnimationDraw fDraw;
SkTimeKeeper fClock;
SkBitmap fBackBuffer;
}
- (void)drawRect:(CGRect)rect {
double next = fClock.paused() ? 0 : (1.0 / 30.0) + SkTime::GetNSecs() * 1e-9;
[super drawRect:rect];
// TODO(halcanary): Use the rect and the InvalidationController to speed up rendering.
if (rect.size.width > 0 && rect.size.height > 0 && fDraw) {
CGSize size = [self bounds].size;
SkISize iSize = {(int)size.width, (int)size.height};
if (fBackBuffer.drawsNothing() || iSize != fBackBuffer.dimensions()) {
fBackBuffer.allocN32Pixels(iSize.fWidth, iSize.fHeight);
}
fBackBuffer.eraseColor(SK_ColorTRANSPARENT);
{
SkCanvas canvas(fBackBuffer);
if (!fClock.paused()) {
fDraw.seek(fClock.currentTime());
}
fDraw.draw({(float)size.width, (float)size.height}, &canvas);
}
SkCGDrawBitmap(UIGraphicsGetCurrentContext(), fBackBuffer, 0, 0);
}
if (next) {
[NSTimer scheduledTimerWithTimeInterval:std::max(0.0, next - SkTime::GetNSecs() * 1e-9)
target:self
selector:@selector(setNeedsDisplay)
userInfo:nil
repeats:NO];
}
}
- (BOOL)loadAnimation:(NSData*) data {
fDraw.load((const void*)[data bytes], (size_t)[data length]);
fClock.setDuration(fDraw.duration());
[self setNeedsDisplay];
return (bool)fDraw;
}
- (void)setStopAtEnd:(BOOL)stop{ fClock.setStopAtEnd(stop); }
- (float)animationDurationSeconds { return fClock.duration(); }
- (float)currentTime { return fDraw ? fClock.currentTime() : 0; }
- (void)seek:(float)seconds {
if (fDraw) {
fClock.seek(seconds);
[self setNeedsDisplay];
}
}
- (CGSize)size { return {(CGFloat)fDraw.size().width(), (CGFloat)fDraw.size().height()}; }
- (BOOL)togglePaused {
fClock.togglePaused();
[self setNeedsDisplay];
return fClock.paused();
}
- (BOOL)isPaused { return fClock.paused(); }
@end