flutter_flutter/framework/sky-scrollable.sky
Adam Barth 7ded81cc4f Add a basic sky-scrollable element that scrolls
We still need to polish sky-scrollable, but it basically works.

R=esprehn@chromium.org

Review URL: https://codereview.chromium.org/875953004
2015-01-26 13:29:38 -08:00

102 lines
2.4 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" />
<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>
// TODO(abarth): Move the fling curve to a separate module.
var kFlingFriction = 0.9;
var kFlingVelocityMin = 1;
module.exports = class extends SkyElement {
created() {
this.scrollable_ = null;
this.scrollOffset_ = 0;
this.flingVelocity_ = 0;
this.flingAnimationId_ = null;
}
shadowRootReady() {
this.scrollable_ = this.shadowRoot.getElementById('scrollable');
}
scrollBy(scrollDelta) {
var offset = Math.max(0, Math.min(this.scrollable_.offsetHeight, 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;
}
scheduleFlingTick_() {
this.flingAnimationId_ = requestAnimationFrame(this.tickFling_.bind(this));
}
tickFling_() {
this.flingAnimationId_ = null;
if (!this.scrollBy(this.flingVelocity_)) {
this.flingVelocity_ = 0;
return;
}
var velocity = this.flingVelocity_ * kFlingFriction;
if (velocity < kFlingVelocityMin)
velocity = 0;
this.flingVelocity_ = velocity;
if (velocity)
this.scheduleFlingTick_();
}
handleScrollStart_(event) {
}
handleScrollEnd_(event) {
}
handleScrollUpdate_(event) {
this.scrollBy(-event.dy);
}
handleFlingStart_(event) {
this.flingVelocity_ = -event.velocityY;
this.scheduleFlingTick_();
}
handleFlingCancel_(event) {
if (!this.flingAnimationId_)
return;
cancelAnimationFrame(this.flingAnimationId_);
this.flingVelocity_ = 0;
this.flingAnimationId_ = null;
}
}.register();
</script>
</sky-element>