|
@@ -1,5 +1,5 @@
|
|
|
import { isMobile } from "./isMoblie";
|
|
|
-import { throttle, debounce } from "./fn";
|
|
|
+import { throttle, debounce, clamp } from "./fn";
|
|
|
import gsap from "gsap";
|
|
|
import mitt from "mitt";
|
|
|
class Mitt {
|
|
@@ -19,12 +19,13 @@ export class CanvasPlayer extends Mitt {
|
|
|
this.imageH = null;
|
|
|
this.setting = setting;
|
|
|
this.currentFrame = 0;
|
|
|
+ this.scrollFrame = 0;
|
|
|
this.movingFrame = 0;
|
|
|
+ this.lastScroll = 0;
|
|
|
+ this.isRendering = false;
|
|
|
this.currentType = 0;
|
|
|
this.frames = [];
|
|
|
this.clips = [];
|
|
|
- this.tmpDisArr = [];
|
|
|
- this.tmpDis = "";
|
|
|
this.canScroll = false;
|
|
|
this.resize = this.resize.bind(this);
|
|
|
this.watchScroll = this.watchScroll.bind(this);
|
|
@@ -128,32 +129,78 @@ export class CanvasPlayer extends Mitt {
|
|
|
this.enableScroll(type);
|
|
|
this.initFirstFrame();
|
|
|
}
|
|
|
- let lastKnownScrollPosition = 0;
|
|
|
- let deltaY = 0;
|
|
|
const scrollY = event.target.scrollTop;
|
|
|
|
|
|
- deltaY = scrollY - lastKnownScrollPosition;
|
|
|
+ if (scrollY > 0 && this.lastScroll <= scrollY) {
|
|
|
+ this.lastScroll = scrollY;
|
|
|
+ // console.log("Scrolling DOWN");
|
|
|
+ this.toScroll(scrollY, true, event);
|
|
|
+ } else {
|
|
|
+ this.lastScroll = scrollY;
|
|
|
+ // console.log("Scrolling UP");
|
|
|
+ this.toScroll(scrollY, false, event);
|
|
|
+ }
|
|
|
|
|
|
+ // deltaY = scrollY - lastKnownScrollPosition;
|
|
|
+ // const deltaHeight = clip.total * 100 - window.innerHeight;
|
|
|
+ // const prcess = scrollY / deltaHeight;
|
|
|
+ // const frame = Math.round(clip.total * prcess);
|
|
|
+ }
|
|
|
+ toScroll(scrollY, na, event) {
|
|
|
+ let timer, completeTimer;
|
|
|
const clip = Array.from(this.clips).find(
|
|
|
(item) => item.id === this.currentType
|
|
|
);
|
|
|
- const deltaHeight = clip.total * 100 - window.innerHeight;
|
|
|
- const prcess = scrollY / deltaHeight;
|
|
|
- const frame = Math.round(clip.total * prcess);
|
|
|
- this.currentFrame = frame;
|
|
|
- // if (frame === 0) {
|
|
|
- // const toPrev = debounce(() => {
|
|
|
- // console.log("frame", frame);
|
|
|
- // this.emit("scroll-prev");
|
|
|
- // this.resetClipScrollTop();
|
|
|
- // }, 3000);
|
|
|
- // toPrev();
|
|
|
- // }
|
|
|
- // if (frame === clip.total) {
|
|
|
- // this.emit("scroll-next");
|
|
|
- // }
|
|
|
- this.reDraw(this.currentFrame, this.currentType);
|
|
|
- // this.watchScroll(event);
|
|
|
+ // const deltaHeight = clip.total * 100 + window.innerHeight;
|
|
|
+ // const prcess = scrollY / deltaHeight;
|
|
|
+ // const startFrame = Math.floor(clip.total * prcess);
|
|
|
+ const startFrame = this.getframeByHeight(scrollY);
|
|
|
+
|
|
|
+ if (timer) {
|
|
|
+ clearTimeout(timer);
|
|
|
+ timer = null;
|
|
|
+ }
|
|
|
+ if (completeTimer) {
|
|
|
+ clearTimeout(completeTimer);
|
|
|
+ completeTimer = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.scrollAni) {
|
|
|
+ this.scrollAni.kill();
|
|
|
+ this.scrollAni = null;
|
|
|
+ }
|
|
|
+ if (startFrame > 0) {
|
|
|
+ this.isRendering = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ const dynamicDistance = na
|
|
|
+ ? this.currentFrame + 10
|
|
|
+ : this.currentFrame - 10;
|
|
|
+ const dis = clamp(dynamicDistance, 0, clip.total);
|
|
|
+ console.log("startFrame", startFrame, this.currentFrame, dis, scrollY);
|
|
|
+ timer = setTimeout(() => {
|
|
|
+ this.scrollAni = gsap.timeline();
|
|
|
+ this.isRendering = true;
|
|
|
+ this.scrollAni.to(this, {
|
|
|
+ movingFrame: dis,
|
|
|
+ ease: "none",
|
|
|
+ yoyo: true,
|
|
|
+ onUpdate: () => {
|
|
|
+ this.isRendering = true;
|
|
|
+ const mFrame = Math.floor(this.movingFrame);
|
|
|
+ this.currentFrame = mFrame;
|
|
|
+ this.reDraw(mFrame, this.currentType);
|
|
|
+ },
|
|
|
+ onComplete: () => {
|
|
|
+ this.scrollAni && this.scrollAni.pause();
|
|
|
+ // const actualHeight = this.currentFrame * 100 + window.innerHeight;
|
|
|
+ // event.target.scrollTop =
|
|
|
+ // actualHeight > window.innerHeight ? actualHeight : 0;
|
|
|
+ this.isRendering = false;
|
|
|
+ this.toRunPatch(event);
|
|
|
+ },
|
|
|
+ });
|
|
|
+ }, 40);
|
|
|
}
|
|
|
watchScroll(event) {
|
|
|
if (this.canScroll) {
|
|
@@ -168,13 +215,44 @@ export class CanvasPlayer extends Mitt {
|
|
|
}
|
|
|
this.initClipScrollheight();
|
|
|
}
|
|
|
- easeOutCubic(x) {
|
|
|
- return 1 - Math.pow(1 - x, 3);
|
|
|
+
|
|
|
+ getframeByHeight(height) {
|
|
|
+ if (this.currentType) {
|
|
|
+ const clip = Array.from(this.clips).find(
|
|
|
+ (item) => item.id === this.currentType
|
|
|
+ );
|
|
|
+ const deltaHeight = clip.total * 100 - window.innerHeight;
|
|
|
+ const prcess = height / deltaHeight;
|
|
|
+ const frame = Math.floor(clip.total * prcess);
|
|
|
+ return clamp(frame, 0, clip.total);
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
}
|
|
|
- currentScollSafeDistance() {}
|
|
|
- initClipScrollheight() {
|
|
|
+
|
|
|
+ getFrameScrollTop(frame) {
|
|
|
+ if (this.currentType) {
|
|
|
+ const clip = Array.from(this.clips).find(
|
|
|
+ (item) => item.id === this.currentType
|
|
|
+ );
|
|
|
+ const updateHeight = clamp(frame * 100, 0, clip.total * 100);
|
|
|
+ return updateHeight;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ updateScrollTop(frame) {
|
|
|
if (this.currentType) {
|
|
|
const bar = document.querySelector(`.scroll-bar-${this.currentType}`);
|
|
|
+ const updateHeight = frame * 100 + window.innerHeight;
|
|
|
+ console.log("updateScrollTop", updateHeight);
|
|
|
+ bar.style.scrollTop = updateHeight;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ initClipScrollheight() {
|
|
|
+ if (this.currentType) {
|
|
|
+ const bar = document.querySelector(
|
|
|
+ `.scroll-bar-${this.currentType}-placeholder`
|
|
|
+ );
|
|
|
const clip = Array.from(this.clips).find(
|
|
|
(item) => item.id === this.currentType
|
|
|
);
|
|
@@ -189,40 +267,29 @@ export class CanvasPlayer extends Mitt {
|
|
|
bar.style.scrollTop = 0;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- autoIncrement(na = true) {
|
|
|
- if (this.currentFrame >= 0) {
|
|
|
- const clip = Array.from(this.clips).find(
|
|
|
- (item) => item.id === this.currentType
|
|
|
- );
|
|
|
- if (this.currentFrame > clip.total) {
|
|
|
- this.currentFrame = clip.total;
|
|
|
- return;
|
|
|
- }
|
|
|
- if (na) {
|
|
|
- this.currentFrame += 1;
|
|
|
- // console.log("111", this.currentFrame);
|
|
|
- if (this.currentFrame === clip.total) {
|
|
|
- this.emit("scroll-next");
|
|
|
- }
|
|
|
- this.reDraw(this.currentFrame, this.currentType);
|
|
|
- } else {
|
|
|
- this.currentFrame -= 1;
|
|
|
- // console.log("222", this.currentFrame);
|
|
|
- if (this.currentFrame === 0) {
|
|
|
- this.emit("scroll-prev");
|
|
|
- }
|
|
|
- this.reDraw(this.currentFrame, this.currentType);
|
|
|
- }
|
|
|
- const process = Number(this.currentFrame / clip.total) * 100;
|
|
|
- this.emit("process", process);
|
|
|
- } else {
|
|
|
- }
|
|
|
+ noticeProcess() {
|
|
|
+ const clip = Array.from(this.clips).find(
|
|
|
+ (item) => item.id === this.currentType
|
|
|
+ );
|
|
|
+ const process = Number(this.currentFrame / clip.total) * 100;
|
|
|
+ this.emit("process", {
|
|
|
+ process,
|
|
|
+ type: this.currentType,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ test() {
|
|
|
+ const height = this.getFrameScrollTop(this.currentFrame);
|
|
|
+ console.log("target-height", height);
|
|
|
+ document.querySelector(".scroll-bar-3").scrollTop = height;
|
|
|
}
|
|
|
|
|
|
- play() {
|
|
|
- // this.currentType = type;
|
|
|
- // this.reDraw(frame, type);
|
|
|
+ play(frame) {
|
|
|
+ console.log("play", frame);
|
|
|
+ const height = this.getFrameScrollTop(frame);
|
|
|
+ console.log("target-height", height);
|
|
|
+ this.lastScroll = height;
|
|
|
+ this.currentFrame = frame;
|
|
|
+ document.querySelector(".scroll-bar-3").scrollTo({ top: height, left: 0 });
|
|
|
}
|
|
|
initClipAnimate() {
|
|
|
Array.from(this.clips).forEach((item, key) => {
|
|
@@ -251,12 +318,20 @@ export class CanvasPlayer extends Mitt {
|
|
|
}
|
|
|
initFirstFrame() {
|
|
|
if (this.currentType) {
|
|
|
- console.log("initFirstFrame");
|
|
|
const frameItem = this.frames.find(
|
|
|
(item) => item.id == this.currentType && item.index == 1
|
|
|
);
|
|
|
this.context.clearRect(0, 0, this.vw, this.vh);
|
|
|
this.context.drawImage(frameItem.image, 0, 0, this.vw, this.vh);
|
|
|
+ this.scrollAni = gsap.timeline();
|
|
|
+ let doneScroll = (event) => {
|
|
|
+ const height = this.getFrameScrollTop(this.currentFrame);
|
|
|
+ // event.target.scrollTop = height;
|
|
|
+ console.warn("scroll done", this.currentFrame, height);
|
|
|
+ document.querySelector(".scroll-bar-3").scroll();
|
|
|
+ };
|
|
|
+ this.toRunPatch = debounce(doneScroll, 500);
|
|
|
+ console.log("initFirstFrame");
|
|
|
}
|
|
|
}
|
|
|
reDraw(frame, type) {
|