Добавлен эффект листания - Протаивание

This commit is contained in:
Book Pauk
2019-02-15 21:36:06 +07:00
parent 0805353a9e
commit daaf9ac70b
4 changed files with 90 additions and 29 deletions

View File

@@ -218,11 +218,19 @@
<div class="partHeader">Анимация</div> <div class="partHeader">Анимация</div>
<el-form-item label="Вид"> <el-form-item label="Вид">
не готово <el-col :span="11">
<el-select v-model="pageChangeAnimation">
<el-option label="Нет" value=""></el-option>
<el-option label="Снизу вверх" value="downShift"></el-option>
<el-option label="Слева направо" value="rightShift"></el-option>
<el-option label="Протаивание" value="thaw"></el-option>
<el-option label="Мерцание" value="blink"></el-option>
</el-select>
</el-col>
</el-form-item> </el-form-item>
<el-form-item label="Скорость"> <el-form-item label="Скорость">
не готово <el-input-number v-model="pageChangeAnimationSpeed" :min="0" :max="100" :disabled="pageChangeAnimation == ''"></el-input-number>
</el-form-item> </el-form-item>
</el-form> </el-form>

View File

@@ -1,3 +1,5 @@
//import {sleep} from '../../../share/utils';
export default class DrawHelper { export default class DrawHelper {
fontBySize(size) { fontBySize(size) {
return `${size}px ${this.fontName}`; return `${size}px ${this.fontName}`;
@@ -213,4 +215,10 @@ export default class DrawHelper {
return `<div style="position: absolute; left: ${x}px; top: ${y}px; ` + return `<div style="position: absolute; left: ${x}px; top: ${y}px; ` +
`width: ${w}px; height: ${h}px; box-sizing: border-box; border: 1px solid ${color}"></div>`; `width: ${w}px; height: ${h}px; box-sizing: border-box; border: 1px solid ${color}"></div>`;
} }
async doPageAnimationThaw(page1, page2, duration, isDown, animationFinish) {
page1.style.animation = `page1-animation-thaw ${duration}ms ease-in 1`;
page2.style.animation = `page2-animation-thaw ${duration}ms ease-in 1`;
await animationFinish(duration + 201);
}
} }

View File

@@ -5,12 +5,12 @@
<!-- img --> <!-- img -->
</div> </div>
<div ref="scrollBox1" class="layout" style="overflow: hidden" @wheel.prevent.stop="onMouseWheel"> <div ref="scrollBox1" class="layout" style="overflow: hidden" @wheel.prevent.stop="onMouseWheel">
<div ref="scrollingPage1" class="layout" @transitionend="onScrollingTransitionEnd"> <div ref="scrollingPage1" class="layout" @transitionend="onScrollingTransitionEnd" @animationend="onPageAnimationEnd">
<div v-html="page1"></div> <div v-html="page1"></div>
</div> </div>
</div> </div>
<div ref="scrollBox2" class="layout" style="overflow: hidden" @wheel.prevent.stop="onMouseWheel"> <div ref="scrollBox2" class="layout" style="overflow: hidden" @wheel.prevent.stop="onMouseWheel">
<div ref="scrollingPage2" class="layout" @transitionend="onScrollingTransitionEnd"> <div ref="scrollingPage2" class="layout">
<div v-html="page2"></div> <div v-html="page2"></div>
</div> </div>
</div> </div>
@@ -62,7 +62,7 @@ export default @Component({
toggleLayout: function() { toggleLayout: function() {
this.updateLayout(); this.updateLayout();
}, },
inTransition: function() { inAnimation: function() {
this.updateLayout(); this.updateLayout();
}, },
}, },
@@ -88,7 +88,7 @@ class TextPage extends Vue {
fontName = null; fontName = null;
fontWeight = null; fontWeight = null;
inTransition = false; inAnimation = false;
meta = null; meta = null;
@@ -116,15 +116,16 @@ class TextPage extends Vue {
this.loadSettings(); this.loadSettings();
}, 50); }, 50);
this.debouncedUpdatePage = _.debounce((lines) => { this.debouncedUpdatePage = _.debounce(async(lines) => {
this.toggleLayout = !this.toggleLayout; if (!this.toggleLayout)
if (this.toggleLayout)
this.page1 = this.drawHelper.drawPage(lines); this.page1 = this.drawHelper.drawPage(lines);
else else
this.page2 = this.drawHelper.drawPage(lines); this.page2 = this.drawHelper.drawPage(lines);
this.doPageTransition(); await this.doPageAnimation();
if (!this.inAnimation)
this.toggleLayout = !this.toggleLayout;
}, 10); }, 10);
this.$root.$on('resize', () => {this.$nextTick(this.onResize)}); this.$root.$on('resize', () => {this.$nextTick(this.onResize)});
@@ -157,7 +158,7 @@ class TextPage extends Vue {
this.pageLineCount = 1 + Math.floor((this.h - this.fontSize)/this.lineHeight); this.pageLineCount = 1 + Math.floor((this.h - this.fontSize)/this.lineHeight);
//stuff //stuff
this.currentTransition = ''; this.currentAnimation = '';
this.pageChangeDirectionDown = true; this.pageChangeDirectionDown = true;
this.fontShift = this.fontVertShift/100; this.fontShift = this.fontVertShift/100;
this.textShift = this.textVertShift/100 + this.fontShift; this.textShift = this.textVertShift/100 + this.fontShift;
@@ -386,7 +387,7 @@ class TextPage extends Vue {
} }
updateLayout() { updateLayout() {
if (this.inTransition) { if (this.inAnimation) {
this.$refs.scrollBox1.style.visibility = 'visible'; this.$refs.scrollBox1.style.visibility = 'visible';
this.$refs.scrollBox2.style.visibility = 'visible'; this.$refs.scrollBox2.style.visibility = 'visible';
} else if (this.toggleLayout) { } else if (this.toggleLayout) {
@@ -552,11 +553,11 @@ class TextPage extends Vue {
} }
//fast draw prepared //fast draw prepared
if (this.pageChangeDirectionDown && this.pagePrepared && this.bookPos == this.bookPosPrepared) { if (!this.currentAnimation && this.pageChangeDirectionDown && this.pagePrepared && this.bookPos == this.bookPosPrepared) {
this.toggleLayout = !this.toggleLayout; this.toggleLayout = !this.toggleLayout;
this.linesDown = this.linesDownNext; this.linesDown = this.linesDownNext;
this.linesUp = this.linesUpNext; this.linesUp = this.linesUpNext;
this.doPageTransition(); this.doPageAnimation();
} else {//normal debounced draw } else {//normal debounced draw
const lines = this.getLines(this.bookPos); const lines = this.getLines(this.bookPos);
this.linesDown = lines.linesDown; this.linesDown = lines.linesDown;
@@ -565,7 +566,8 @@ class TextPage extends Vue {
} }
this.pagePrepared = false; this.pagePrepared = false;
this.debouncedPrepareNextPage(); if (!this.currentAnimation)
this.debouncedPrepareNextPage();
this.debouncedDrawStatusBar(); this.debouncedDrawStatusBar();
if (this.book && this.linesDown && this.linesDown.length < this.pageLineCount) { if (this.book && this.linesDown && this.linesDown.length < this.pageLineCount) {
@@ -574,18 +576,48 @@ class TextPage extends Vue {
} }
} }
async doPageTransition() { onPageAnimationEnd() {
if (this.currentTransition) { if (this.resolveAnimationFinish)
this.inTransition = true; this.resolveAnimationFinish();
//switch () }
//this.currentTransition
//this.pageChangeTransitionSpeed
//this.pageChangeDirectionDown
this.inTransition = false; async doPageAnimation() {
if (this.currentAnimation && !this.inAnimation) {
this.inAnimation = true;
const animationFinish = (timeout) => {
return new Promise(async(resolve) => {
this.resolveAnimationFinish = resolve;
let wait = timeout/100;
while (wait > 0 && !this.stopAnimation) {
wait--;
await sleep(100);
}
resolve();
});
};
const duration = Math.round(3000*(1 - this.pageChangeAnimationSpeed/100));
let page1 = this.$refs.scrollingPage2;
let page2 = this.$refs.scrollingPage1;
if (!this.toggleLayout)
[page1, page2] = [page2, page1];
switch (this.currentAnimation) {
case 'thaw':
await this.drawHelper.doPageAnimationThaw(page1, page2,
duration, this.pageChangeDirectionDown, animationFinish);
break;
}
page1.style.animation = '';
page2.style.animation = '';
this.resolveAnimationFinish = null;
this.inAnimation = false;
this.stopAnimation = false;
} }
this.currentTransition = ''; this.currentAnimation = '';
this.pageChangeDirectionDown = false;//true только если PgDown this.pageChangeDirectionDown = false;//true только если PgDown
} }
@@ -721,7 +753,7 @@ class TextPage extends Vue {
if (this.keepLastToFirst) if (this.keepLastToFirst)
i--; i--;
if (i >= 0 && this.linesDown.length >= 2*i) { if (i >= 0 && this.linesDown.length >= 2*i) {
this.currentTransition = this.pageChangeTransition; this.currentAnimation = this.pageChangeAnimation;
this.pageChangeDirectionDown = true; this.pageChangeDirectionDown = true;
this.bookPos = this.linesDown[i].begin; this.bookPos = this.linesDown[i].begin;
} else } else
@@ -736,7 +768,7 @@ class TextPage extends Vue {
i--; i--;
i = (i > this.linesUp.length - 1 ? this.linesUp.length - 1 : i); i = (i > this.linesUp.length - 1 ? this.linesUp.length - 1 : i);
if (i >= 0 && this.linesUp.length > i) { if (i >= 0 && this.linesUp.length > i) {
this.currentTransition = this.pageChangeTransition; this.currentAnimation = this.pageChangeAnimation;
this.pageChangeDirectionDown = false; this.pageChangeDirectionDown = false;
this.bookPos = this.linesUp[i].begin; this.bookPos = this.linesUp[i].begin;
} }
@@ -744,6 +776,8 @@ class TextPage extends Vue {
} }
doHome() { doHome() {
this.currentAnimation = this.pageChangeAnimation;
this.pageChangeDirectionDown = false;
this.bookPos = 0; this.bookPos = 0;
} }
@@ -755,6 +789,8 @@ class TextPage extends Vue {
if (lines) { if (lines) {
i = this.pageLineCount - 1; i = this.pageLineCount - 1;
i = (i > lines.length - 1 ? lines.length - 1 : i); i = (i > lines.length - 1 ? lines.length - 1 : i);
this.currentAnimation = this.pageChangeAnimation;
this.pageChangeDirectionDown = true;
this.bookPos = lines[i].begin; this.bookPos = lines[i].begin;
} }
} }
@@ -1075,4 +1111,13 @@ class TextPage extends Vue {
background: url("images/paper9.jpg"); background: url("images/paper9.jpg");
} }
@keyframes page1-animation-thaw {
0% { opacity: 0; }
100% { opacity: 1; }
}
@keyframes page2-animation-thaw {
0% { opacity: 1; }
100% { opacity: 0; }
}
</style> </style>

View File

@@ -152,8 +152,8 @@ const settingDefaults = {
scrollingDelay: 3000,// замедление, ms scrollingDelay: 3000,// замедление, ms
scrollingType: 'ease-in-out', //linear, ease, ease-in, ease-out, ease-in-out scrollingType: 'ease-in-out', //linear, ease, ease-in, ease-out, ease-in-out
pageChangeTransition: '',// '' - нет, downShift, rightShift, thaw - протаивание, blink - мерцание pageChangeAnimation: 'thaw',// '' - нет, downShift, rightShift, thaw - протаивание, blink - мерцание
pageChangeTransitionSpeed: 50, //0-100% pageChangeAnimationSpeed: 80, //0-100%
allowUrlParamBookPos: false, allowUrlParamBookPos: false,
lazyParseEnabled: false, lazyParseEnabled: false,