flutter_flutter/framework/sky-scrollable.sky
Adam Barth d05380e397 sky-scrollable should use a reasonable fling curve
This CL uses the aura fling curve to ease flings. Also, I've made Event#timeStamp
use consistent units and timebase with the requestAnimationFrame timestamp. Now
both are doubles of milliseconds since the epoch.

R=esprehn@chromium.org

Review URL: https://codereview.chromium.org/880473003
2015-01-26 17:34:28 -08:00

95 lines
2.3 KiB
Plaintext

<!--
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-->
<import src="/sky/framework/sky-element/sky-element.sky" as="SkyElement" />
<import src="/sky/framework/fling-curve.sky" as="FlingCurve" />
<sky-element
name="sky-scrollable"
on-gesturescrollstart="handleScrollStart_"
on-gesturescrollend="handleScrollEnd_"
on-gesturescrollupdate="handleScrollUpdate_"
on-gestureflingstart="handleFlingStart_"
on-gestureflingcancel="handleFlingCancel_">
<template>
<style>
:host {
overflow: hidden;
}
#scrollable {
transform: translateY(0);
}
</style>
<div id="scrollable">
<content />
</div>
</template>
<script>
module.exports = class extends SkyElement {
created() {
this.scrollable_ = null;
this.scrollOffset_ = 0;
this.flingCurve_ = null;
this.flingAnimationId_ = null;
}
shadowRootReady() {
this.scrollable_ = this.shadowRoot.getElementById('scrollable');
}
scrollBy(scrollDelta) {
var scrollHeight = this.scrollable_.clientHeight - this.clientHeight;
var offset = Math.max(0, Math.min(scrollHeight, this.scrollOffset_ + scrollDelta));
if (offset == this.scrollOffset_)
return false;
this.scrollOffset_ = offset;
this.applyScrollOffset_();
return true;
}
applyScrollOffset_() {
var transform = 'translateY(' + -this.scrollOffset_.toFixed(2) + 'px)';
this.scrollable_.style.transform = transform;
}
scheduleFlingUpdate_() {
this.flingAnimationId_ = requestAnimationFrame(this.updateFling_.bind(this));
}
stopFling_() {
cancelAnimationFrame(this.flingAnimationId_);
this.flingCurve_ = null;
this.flingAnimationId_ = null;
}
updateFling_(timeStamp) {
var scrollDelta = this.flingCurve_.update(timeStamp);
if (!scrollDelta || !this.scrollBy(scrollDelta))
return this.stopFling_();
this.scheduleFlingUpdate_();
}
handleScrollStart_(event) {
}
handleScrollEnd_(event) {
}
handleScrollUpdate_(event) {
this.scrollBy(-event.dy);
}
handleFlingStart_(event) {
this.flingCurve_ = new FlingCurve(-event.velocityY, event.timeStamp);
this.scheduleFlingUpdate_();
}
handleFlingCancel_(event) {
this.stopFling_();
}
}.register();
</script>
</sky-element>