web: finish develop Slider

This commit is contained in:
pengfei.zhou 2021-04-20 18:03:26 +08:00 committed by osborn
parent 11f004d974
commit 93293b099f
10 changed files with 2979 additions and 2245 deletions

View File

@ -4403,6 +4403,452 @@ var doric_web = (function (exports, axios, sandbox) {
var axios__default = /*#__PURE__*/_interopDefaultLegacy(axios); var axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
function createCommonjsModule(fn, basedir, module) {
return module = {
path: basedir,
exports: {},
require: function (path, base) {
return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
}
}, fn(module, module.exports), module.exports;
}
function commonjsRequire () {
throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
}
var smoothscroll = createCommonjsModule(function (module, exports) {
/* smoothscroll v0.4.4 - 2019 - Dustan Kasten, Jeremias Menichelli - MIT License */
(function () {
// polyfill
function polyfill() {
// aliases
var w = window;
var d = document;
// return if scroll behavior is supported and polyfill is not forced
if (
'scrollBehavior' in d.documentElement.style &&
w.__forceSmoothScrollPolyfill__ !== true
) {
return;
}
// globals
var Element = w.HTMLElement || w.Element;
var SCROLL_TIME = 468;
// object gathering original scroll methods
var original = {
scroll: w.scroll || w.scrollTo,
scrollBy: w.scrollBy,
elementScroll: Element.prototype.scroll || scrollElement,
scrollIntoView: Element.prototype.scrollIntoView
};
// define timing method
var now =
w.performance && w.performance.now
? w.performance.now.bind(w.performance)
: Date.now;
/**
* indicates if a the current browser is made by Microsoft
* @method isMicrosoftBrowser
* @param {String} userAgent
* @returns {Boolean}
*/
function isMicrosoftBrowser(userAgent) {
var userAgentPatterns = ['MSIE ', 'Trident/', 'Edge/'];
return new RegExp(userAgentPatterns.join('|')).test(userAgent);
}
/*
* IE has rounding bug rounding down clientHeight and clientWidth and
* rounding up scrollHeight and scrollWidth causing false positives
* on hasScrollableSpace
*/
var ROUNDING_TOLERANCE = isMicrosoftBrowser(w.navigator.userAgent) ? 1 : 0;
/**
* changes scroll position inside an element
* @method scrollElement
* @param {Number} x
* @param {Number} y
* @returns {undefined}
*/
function scrollElement(x, y) {
this.scrollLeft = x;
this.scrollTop = y;
}
/**
* returns result of applying ease math function to a number
* @method ease
* @param {Number} k
* @returns {Number}
*/
function ease(k) {
return 0.5 * (1 - Math.cos(Math.PI * k));
}
/**
* indicates if a smooth behavior should be applied
* @method shouldBailOut
* @param {Number|Object} firstArg
* @returns {Boolean}
*/
function shouldBailOut(firstArg) {
if (
firstArg === null ||
typeof firstArg !== 'object' ||
firstArg.behavior === undefined ||
firstArg.behavior === 'auto' ||
firstArg.behavior === 'instant'
) {
// first argument is not an object/null
// or behavior is auto, instant or undefined
return true;
}
if (typeof firstArg === 'object' && firstArg.behavior === 'smooth') {
// first argument is an object and behavior is smooth
return false;
}
// throw error when behavior is not supported
throw new TypeError(
'behavior member of ScrollOptions ' +
firstArg.behavior +
' is not a valid value for enumeration ScrollBehavior.'
);
}
/**
* indicates if an element has scrollable space in the provided axis
* @method hasScrollableSpace
* @param {Node} el
* @param {String} axis
* @returns {Boolean}
*/
function hasScrollableSpace(el, axis) {
if (axis === 'Y') {
return el.clientHeight + ROUNDING_TOLERANCE < el.scrollHeight;
}
if (axis === 'X') {
return el.clientWidth + ROUNDING_TOLERANCE < el.scrollWidth;
}
}
/**
* indicates if an element has a scrollable overflow property in the axis
* @method canOverflow
* @param {Node} el
* @param {String} axis
* @returns {Boolean}
*/
function canOverflow(el, axis) {
var overflowValue = w.getComputedStyle(el, null)['overflow' + axis];
return overflowValue === 'auto' || overflowValue === 'scroll';
}
/**
* indicates if an element can be scrolled in either axis
* @method isScrollable
* @param {Node} el
* @param {String} axis
* @returns {Boolean}
*/
function isScrollable(el) {
var isScrollableY = hasScrollableSpace(el, 'Y') && canOverflow(el, 'Y');
var isScrollableX = hasScrollableSpace(el, 'X') && canOverflow(el, 'X');
return isScrollableY || isScrollableX;
}
/**
* finds scrollable parent of an element
* @method findScrollableParent
* @param {Node} el
* @returns {Node} el
*/
function findScrollableParent(el) {
while (el !== d.body && isScrollable(el) === false) {
el = el.parentNode || el.host;
}
return el;
}
/**
* self invoked function that, given a context, steps through scrolling
* @method step
* @param {Object} context
* @returns {undefined}
*/
function step(context) {
var time = now();
var value;
var currentX;
var currentY;
var elapsed = (time - context.startTime) / SCROLL_TIME;
// avoid elapsed times higher than one
elapsed = elapsed > 1 ? 1 : elapsed;
// apply easing to elapsed time
value = ease(elapsed);
currentX = context.startX + (context.x - context.startX) * value;
currentY = context.startY + (context.y - context.startY) * value;
context.method.call(context.scrollable, currentX, currentY);
// scroll more if we have not reached our destination
if (currentX !== context.x || currentY !== context.y) {
w.requestAnimationFrame(step.bind(w, context));
}
}
/**
* scrolls window or element with a smooth behavior
* @method smoothScroll
* @param {Object|Node} el
* @param {Number} x
* @param {Number} y
* @returns {undefined}
*/
function smoothScroll(el, x, y) {
var scrollable;
var startX;
var startY;
var method;
var startTime = now();
// define scroll context
if (el === d.body) {
scrollable = w;
startX = w.scrollX || w.pageXOffset;
startY = w.scrollY || w.pageYOffset;
method = original.scroll;
} else {
scrollable = el;
startX = el.scrollLeft;
startY = el.scrollTop;
method = scrollElement;
}
// scroll looping over a frame
step({
scrollable: scrollable,
method: method,
startTime: startTime,
startX: startX,
startY: startY,
x: x,
y: y
});
}
// ORIGINAL METHODS OVERRIDES
// w.scroll and w.scrollTo
w.scroll = w.scrollTo = function() {
// avoid action when no arguments are passed
if (arguments[0] === undefined) {
return;
}
// avoid smooth behavior if not required
if (shouldBailOut(arguments[0]) === true) {
original.scroll.call(
w,
arguments[0].left !== undefined
? arguments[0].left
: typeof arguments[0] !== 'object'
? arguments[0]
: w.scrollX || w.pageXOffset,
// use top prop, second argument if present or fallback to scrollY
arguments[0].top !== undefined
? arguments[0].top
: arguments[1] !== undefined
? arguments[1]
: w.scrollY || w.pageYOffset
);
return;
}
// LET THE SMOOTHNESS BEGIN!
smoothScroll.call(
w,
d.body,
arguments[0].left !== undefined
? ~~arguments[0].left
: w.scrollX || w.pageXOffset,
arguments[0].top !== undefined
? ~~arguments[0].top
: w.scrollY || w.pageYOffset
);
};
// w.scrollBy
w.scrollBy = function() {
// avoid action when no arguments are passed
if (arguments[0] === undefined) {
return;
}
// avoid smooth behavior if not required
if (shouldBailOut(arguments[0])) {
original.scrollBy.call(
w,
arguments[0].left !== undefined
? arguments[0].left
: typeof arguments[0] !== 'object' ? arguments[0] : 0,
arguments[0].top !== undefined
? arguments[0].top
: arguments[1] !== undefined ? arguments[1] : 0
);
return;
}
// LET THE SMOOTHNESS BEGIN!
smoothScroll.call(
w,
d.body,
~~arguments[0].left + (w.scrollX || w.pageXOffset),
~~arguments[0].top + (w.scrollY || w.pageYOffset)
);
};
// Element.prototype.scroll and Element.prototype.scrollTo
Element.prototype.scroll = Element.prototype.scrollTo = function() {
// avoid action when no arguments are passed
if (arguments[0] === undefined) {
return;
}
// avoid smooth behavior if not required
if (shouldBailOut(arguments[0]) === true) {
// if one number is passed, throw error to match Firefox implementation
if (typeof arguments[0] === 'number' && arguments[1] === undefined) {
throw new SyntaxError('Value could not be converted');
}
original.elementScroll.call(
this,
// use left prop, first number argument or fallback to scrollLeft
arguments[0].left !== undefined
? ~~arguments[0].left
: typeof arguments[0] !== 'object' ? ~~arguments[0] : this.scrollLeft,
// use top prop, second argument or fallback to scrollTop
arguments[0].top !== undefined
? ~~arguments[0].top
: arguments[1] !== undefined ? ~~arguments[1] : this.scrollTop
);
return;
}
var left = arguments[0].left;
var top = arguments[0].top;
// LET THE SMOOTHNESS BEGIN!
smoothScroll.call(
this,
this,
typeof left === 'undefined' ? this.scrollLeft : ~~left,
typeof top === 'undefined' ? this.scrollTop : ~~top
);
};
// Element.prototype.scrollBy
Element.prototype.scrollBy = function() {
// avoid action when no arguments are passed
if (arguments[0] === undefined) {
return;
}
// avoid smooth behavior if not required
if (shouldBailOut(arguments[0]) === true) {
original.elementScroll.call(
this,
arguments[0].left !== undefined
? ~~arguments[0].left + this.scrollLeft
: ~~arguments[0] + this.scrollLeft,
arguments[0].top !== undefined
? ~~arguments[0].top + this.scrollTop
: ~~arguments[1] + this.scrollTop
);
return;
}
this.scroll({
left: ~~arguments[0].left + this.scrollLeft,
top: ~~arguments[0].top + this.scrollTop,
behavior: arguments[0].behavior
});
};
// Element.prototype.scrollIntoView
Element.prototype.scrollIntoView = function() {
// avoid smooth behavior if not required
if (shouldBailOut(arguments[0]) === true) {
original.scrollIntoView.call(
this,
arguments[0] === undefined ? true : arguments[0]
);
return;
}
// LET THE SMOOTHNESS BEGIN!
var scrollableParent = findScrollableParent(this);
var parentRects = scrollableParent.getBoundingClientRect();
var clientRects = this.getBoundingClientRect();
if (scrollableParent !== d.body) {
// reveal element inside parent
smoothScroll.call(
this,
scrollableParent,
scrollableParent.scrollLeft + clientRects.left - parentRects.left,
scrollableParent.scrollTop + clientRects.top - parentRects.top
);
// reveal parent in viewport unless is fixed
if (w.getComputedStyle(scrollableParent).position !== 'fixed') {
w.scrollBy({
left: parentRects.left,
top: parentRects.top,
behavior: 'smooth'
});
}
} else {
// reveal element in viewport
w.scrollBy({
left: clientRects.left,
top: clientRects.top,
behavior: 'smooth'
});
}
};
}
{
// commonjs
module.exports = { polyfill: polyfill };
}
}());
});
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) { return new (P || (P = Promise))(function (resolve, reject) {
@ -4468,16 +4914,11 @@ var doric_web = (function (exports, axios, sandbox) {
function toRGBAString(color) { function toRGBAString(color) {
let strs = []; let strs = [];
for (let i = 0; i < 32; i += 8) { for (let i = 0; i < 32; i += 8) {
strs.push(((color >> i) & 0xff).toString(16)); strs.push(((color >> i) & 0xff));
} }
strs = strs.map(e => { strs = strs.reverse();
if (e.length === 1) { /// RGBAd
return '0' + e; return `rgba(${strs[1]},${strs[2]},${strs[3]},${strs[0] / 255})`;
}
return e;
}).reverse();
/// RGBA
return `#${strs[1]}${strs[2]}${strs[3]}${strs[0]}`;
} }
class DoricViewNode { class DoricViewNode {
constructor(context) { constructor(context) {
@ -5756,6 +6197,10 @@ var doric_web = (function (exports, axios, sandbox) {
PopoverPlugin.TYPE = "popover"; PopoverPlugin.TYPE = "popover";
class DoricListItemNode extends DoricStackNode { class DoricListItemNode extends DoricStackNode {
constructor(context) {
super(context);
this.reusable = true;
}
} }
class DoricListNode extends DoricSuperNode { class DoricListNode extends DoricSuperNode {
@ -5836,10 +6281,11 @@ var doric_web = (function (exports, axios, sandbox) {
(_a = this.getSubNodeById(model.id)) === null || _a === void 0 ? void 0 : _a.blend(model.props); (_a = this.getSubNodeById(model.id)) === null || _a === void 0 ? void 0 : _a.blend(model.props);
} }
getSubNodeById(viewId) { getSubNodeById(viewId) {
var _a;
if (viewId === this.loadMoreViewId) { if (viewId === this.loadMoreViewId) {
return this.loadMoreViewNode; return this.loadMoreViewNode;
} }
return this.childNodes.filter(e => e.viewId === viewId)[0]; return (_a = this.childNodes.filter(e => e.viewId === viewId)) === null || _a === void 0 ? void 0 : _a[0];
} }
onScrollToEnd() { onScrollToEnd() {
if (this.loadMore && this.onLoadMoreFuncId) { if (this.loadMore && this.onLoadMoreFuncId) {
@ -6150,13 +6596,40 @@ var doric_web = (function (exports, axios, sandbox) {
var _a; var _a;
Promise.all(((_a = this.context.animationSet) === null || _a === void 0 ? void 0 : _a.map(e => { Promise.all(((_a = this.context.animationSet) === null || _a === void 0 ? void 0 : _a.map(e => {
return new Promise(resolve => { return new Promise(resolve => {
const animation = e.viewNode.view.animate([e.keyFrame], { const keyFrame = {};
const ensureNonString = (key, value) => {
if (!!value && value !== "") {
return value;
}
switch ((key)) {
case "backgroundColor":
return "transparent";
case "transform":
return "none";
default:
return "none";
}
};
for (let k in e.keyFrame) {
keyFrame[k] = ensureNonString(k, e.viewNode.view.style[k]);
e.keyFrame[k] = ensureNonString(k, e.keyFrame[k]);
}
try {
const animation = e.viewNode.view.animate([keyFrame, e.keyFrame], {
duration: args.duration, duration: args.duration,
fill: "forwards" fill: "forwards"
}); });
animation.onfinish = () => { animation.onfinish = () => {
Object.entries(e.keyFrame).forEach(entry => {
Reflect.set(e.viewNode.view.style, entry[0], entry[1]);
});
resolve(true); resolve(true);
}; };
}
catch (e) {
console.error(e);
alert(e.stack);
}
}); });
})) || []) })) || [])
.then(() => { .then(() => {
@ -6200,23 +6673,24 @@ var doric_web = (function (exports, axios, sandbox) {
ret.appendChild(input); ret.appendChild(input);
ret.appendChild(box); ret.appendChild(box);
ret.onclick = () => { ret.onclick = () => {
try {
if (input.checked === false) { if (input.checked === false) {
span.animate([{ transform: "translateX(30px)" }], { span.animate([{ transform: "translateX(0px)" }, { transform: "translateX(30px)" }], {
duration: 200, duration: 200,
fill: "forwards" fill: "forwards"
}); });
box.animate([{ backgroundColor: this.onTintColor }], { box.animate([{ backgroundColor: this.offTintColor }, { backgroundColor: this.onTintColor }], {
duration: 200, duration: 200,
fill: "forwards" fill: "forwards"
}); });
input.checked = true; input.checked = true;
} }
else { else {
span.animate([{ transform: "translateX(0px)" }], { span.animate([{ transform: "translateX(30px)" }, { transform: "translateX(0px)" }], {
duration: 200, duration: 200,
fill: "forwards" fill: "forwards"
}); });
box.animate([{ backgroundColor: this.offTintColor }], { box.animate([{ backgroundColor: this.onTintColor }, { backgroundColor: this.offTintColor }], {
duration: 200, duration: 200,
fill: "forwards" fill: "forwards"
}); });
@ -6225,6 +6699,10 @@ var doric_web = (function (exports, axios, sandbox) {
if (this.onSwitchFuncId) { if (this.onSwitchFuncId) {
this.callJSResponse(this.onSwitchFuncId, input.checked); this.callJSResponse(this.onSwitchFuncId, input.checked);
} }
}
catch (e) {
alert(e);
}
}; };
this.input = input; this.input = input;
this.span = span; this.span = span;
@ -6278,6 +6756,122 @@ var doric_web = (function (exports, axios, sandbox) {
} }
} }
class DoricSliderNode extends DoricSuperNode {
constructor() {
super(...arguments);
this.itemCount = 0;
this.renderPageFuncId = "";
this.batchCount = 15;
this.onPageSelectedFuncId = "";
this.loop = false;
this.childNodes = [];
}
blendProps(v, propName, prop) {
if (propName === 'itemCount') {
this.itemCount = prop;
}
else if (propName === 'renderPage') {
if (prop !== this.renderPageFuncId) {
this.childNodes = [];
this.renderPageFuncId = prop;
}
}
else if (propName === 'batchCount') {
this.batchCount = prop;
}
else if (propName === 'onPageSlided') {
this.onPageSelectedFuncId = prop;
}
else if (propName === 'loop') {
this.loop = prop;
}
else {
super.blendProps(v, propName, prop);
}
}
blendSubNode(model) {
var _a;
(_a = this.getSubNodeById(model.id)) === null || _a === void 0 ? void 0 : _a.blend(model.props);
}
getSubNodeById(viewId) {
var _a;
return (_a = this.childNodes.filter(e => e.viewId === viewId)) === null || _a === void 0 ? void 0 : _a[0];
}
onBlending() {
super.onBlending();
if (this.childNodes.length !== this.itemCount) {
const ret = this.pureCallJSResponse("renderBunchedItems", this.childNodes.length, this.itemCount);
this.childNodes = this.childNodes.concat(ret.map(e => {
const viewNode = DoricViewNode.create(this.context, e.type);
viewNode.viewId = e.id;
viewNode.init(this);
viewNode.blend(e.props);
this.view.appendChild(viewNode.view);
return viewNode;
}));
}
}
build() {
const ret = document.createElement('div');
ret.style.overflow = "hidden";
ret.style.display = "inline";
ret.style.whiteSpace = "nowrap";
let touchStartX = 0;
let currentIndex = 0;
ret.ontouchstart = (ev) => {
currentIndex = Math.round(ret.scrollLeft / ret.offsetWidth);
touchStartX = ev.touches[0].pageX;
};
ret.ontouchmove = (ev) => {
const offsetX = (touchStartX - ev.touches[0].pageX) * 3;
ret.scrollTo({
left: currentIndex * ret.offsetWidth + offsetX
});
};
ret.ontouchcancel = ret.ontouchend = () => {
currentIndex = Math.round(ret.scrollLeft / ret.offsetWidth);
ret.scrollTo({
left: currentIndex * ret.offsetWidth,
behavior: "smooth"
});
};
return ret;
}
getSlidedPage() {
return Math.round(this.view.scrollLeft / this.view.offsetWidth);
}
slidePage(params) {
if (params.smooth) {
this.view.scrollTo({
left: this.view.offsetWidth * params.page,
behavior: "smooth"
});
}
else {
this.view.scrollTo({
left: this.view.offsetWidth * params.page
});
}
if (this.onPageSelectedFuncId.length > 0) {
this.callJSResponse(this.onPageSelectedFuncId, params.page);
}
}
}
class DoricSlideItemNode extends DoricStackNode {
constructor(context) {
super(context);
this.reusable = true;
}
build() {
const ret = super.build();
ret.style.display = "inline-block";
ret.style.width = "100%";
ret.style.height = "100%";
return ret;
}
}
const bundles = new Map; const bundles = new Map;
const plugins = new Map; const plugins = new Map;
const nodes = new Map; const nodes = new Map;
@ -6316,6 +6910,8 @@ var doric_web = (function (exports, axios, sandbox) {
registerViewNode('Draggable', DoricDraggableNode); registerViewNode('Draggable', DoricDraggableNode);
registerViewNode('Refreshable', DoricRefreshableNode); registerViewNode('Refreshable', DoricRefreshableNode);
registerViewNode('Switch', DoricSwitchNode); registerViewNode('Switch', DoricSwitchNode);
registerViewNode('Slider', DoricSliderNode);
registerViewNode('SlideItem', DoricSlideItemNode);
function getScriptId(contextId) { function getScriptId(contextId) {
return `__doric_script_${contextId}`; return `__doric_script_${contextId}`;
@ -6520,7 +7116,7 @@ ${content}
var _a; var _a;
(_a = this.animationSet) === null || _a === void 0 ? void 0 : _a.push({ (_a = this.animationSet) === null || _a === void 0 ? void 0 : _a.push({
viewNode, viewNode,
keyFrame keyFrame,
}); });
} }
teardown() { teardown() {
@ -6635,6 +7231,7 @@ ${content}
}; };
window.customElements.define('doric-div', DoricElement); window.customElements.define('doric-div', DoricElement);
window.customElements.define('doric-navigation', NavigationElement); window.customElements.define('doric-navigation', NavigationElement);
smoothscroll.polyfill();
registerDoricJSLoader({ registerDoricJSLoader({
filter: (source) => source.startsWith("assets://"), filter: (source) => source.startsWith("assets://"),
request: (source) => __awaiter$1(void 0, void 0, void 0, function* () { request: (source) => __awaiter$1(void 0, void 0, void 0, function* () {

File diff suppressed because one or more lines are too long

View File

@ -42,5 +42,10 @@
width: 100%; width: 100%;
} }
</style> </style>
<script src="https://cdn.bootcdn.net/ajax/libs/vConsole/3.4.1/vconsole.min.js"></script>
<script>
// 初始化
var vConsole = new VConsole();
console.log('Hello world');
</script>
</html> </html>

View File

@ -1,9 +1,8 @@
import axios from 'axios'; import axios from 'axios';
import smoothscroll from 'smoothscroll-polyfill';
import { registerDoricJSLoader } from './src/DoricBundleLoader'; import { registerDoricJSLoader } from './src/DoricBundleLoader';
import { DoricElement } from './src/DoricElement' import { DoricElement } from './src/DoricElement'
import { NavigationElement } from './src/navigate/NavigationElement' import { NavigationElement } from './src/navigate/NavigationElement'
window.customElements.define('doric-div', DoricElement);
window.customElements.define('doric-navigation', NavigationElement);
export * from './src/DoricElement' export * from './src/DoricElement'
export * from './src/navigate/NavigationElement' export * from './src/navigate/NavigationElement'
export * from './src/DoricPlugin' export * from './src/DoricPlugin'
@ -11,6 +10,11 @@ export * from './src/DoricRegistry'
export * from './src/DoricDriver' export * from './src/DoricDriver'
export * from './src/shader/DoricViewNode' export * from './src/shader/DoricViewNode'
window.customElements.define('doric-div', DoricElement);
window.customElements.define('doric-navigation', NavigationElement);
smoothscroll.polyfill();
registerDoricJSLoader({ registerDoricJSLoader({
filter: (source) => source.startsWith("assets://"), filter: (source) => source.startsWith("assets://"),
request: async (source) => { request: async (source) => {

View File

@ -25,9 +25,13 @@
"axios": ">=0.21.1", "axios": ">=0.21.1",
"doric": "file:../doric-js", "doric": "file:../doric-js",
"rollup": "^2.24.0", "rollup": "^2.24.0",
"smoothscroll-polyfill": "^0.4.4",
"typescript": "^4.2.2" "typescript": "^4.2.2"
}, },
"publishConfig": { "publishConfig": {
"registry": "https://registry.npmjs.org" "registry": "https://registry.npmjs.org"
},
"devDependencies": {
"@types/smoothscroll-polyfill": "^0.3.1"
} }
} }

View File

@ -17,6 +17,8 @@ import { DoricDraggableNode } from "./shader/DoricDraggableNode"
import { DoricRefreshableNode } from "./shader/DoricRefreshableNode" import { DoricRefreshableNode } from "./shader/DoricRefreshableNode"
import { AnimatePlugin } from "./plugins/AnimatePlugin" import { AnimatePlugin } from "./plugins/AnimatePlugin"
import { DoricSwitchNode } from "./shader/DoricSwitchNode" import { DoricSwitchNode } from "./shader/DoricSwitchNode"
import { DoricSliderNode } from "./shader/DoricSliderNode"
import { DoricSlideItemNode } from "./shader/DoricSlideItemNode"
const bundles: Map<string, string> = new Map const bundles: Map<string, string> = new Map
@ -69,3 +71,5 @@ registerViewNode('List', DoricListNode)
registerViewNode('Draggable', DoricDraggableNode) registerViewNode('Draggable', DoricDraggableNode)
registerViewNode('Refreshable', DoricRefreshableNode) registerViewNode('Refreshable', DoricRefreshableNode)
registerViewNode('Switch', DoricSwitchNode) registerViewNode('Switch', DoricSwitchNode)
registerViewNode('Slider', DoricSliderNode)
registerViewNode('SlideItem', DoricSlideItemNode)

View File

@ -1,5 +1,9 @@
import { DoricContext } from "../DoricContext";
import { DoricStackNode } from "./DoricStackNode"; import { DoricStackNode } from "./DoricStackNode";
export class DoricListItemNode extends DoricStackNode { export class DoricListItemNode extends DoricStackNode {
constructor(context: DoricContext) {
super(context)
this.reusable = true
}
} }

View File

@ -85,7 +85,7 @@ export class DoricListNode extends DoricSuperNode {
if (viewId === this.loadMoreViewId) { if (viewId === this.loadMoreViewId) {
return this.loadMoreViewNode return this.loadMoreViewNode
} }
return this.childNodes.filter(e => e.viewId === viewId)[0] return this.childNodes.filter(e => e.viewId === viewId)?.[0]
} }
onScrollToEnd() { onScrollToEnd() {

View File

@ -0,0 +1,16 @@
import { DoricContext } from "../DoricContext";
import { DoricStackNode } from "./DoricStackNode";
export class DoricSlideItemNode extends DoricStackNode {
constructor(context: DoricContext) {
super(context)
this.reusable = true
}
build() {
const ret = super.build()
ret.style.display = "inline-block"
ret.style.width = "100%"
ret.style.height = "100%"
return ret
}
}

View File

@ -0,0 +1,100 @@
import { DoricSlideItemNode } from "./DoricSlideItemNode";
import { DoricStackNode } from "./DoricStackNode";
import { DoricSuperNode, DoricViewNode, DVModel } from "./DoricViewNode";
export class DoricSliderNode extends DoricSuperNode {
itemCount = 0
renderPageFuncId = ""
batchCount = 15
onPageSelectedFuncId = ""
loop = false
childNodes: DoricSlideItemNode[] = []
blendProps(v: HTMLElement, propName: string, prop: any) {
if (propName === 'itemCount') {
this.itemCount = prop
} else if (propName === 'renderPage') {
if (prop !== this.renderPageFuncId) {
this.childNodes = []
this.renderPageFuncId = prop
}
} else if (propName === 'batchCount') {
this.batchCount = prop
} else if (propName === 'onPageSlided') {
this.onPageSelectedFuncId = prop
} else if (propName === 'loop') {
this.loop = prop
} else {
super.blendProps(v, propName, prop)
}
}
blendSubNode(model: DVModel) {
this.getSubNodeById(model.id)?.blend(model.props)
}
getSubNodeById(viewId: string) {
return this.childNodes.filter(e => e.viewId === viewId)?.[0]
}
onBlending() {
super.onBlending()
if (this.childNodes.length !== this.itemCount) {
const ret = this.pureCallJSResponse("renderBunchedItems", this.childNodes.length, this.itemCount) as DVModel[]
this.childNodes = this.childNodes.concat(ret.map(e => {
const viewNode = DoricViewNode.create(this.context, e.type) as DoricStackNode
viewNode.viewId = e.id
viewNode.init(this)
viewNode.blend(e.props)
this.view.appendChild(viewNode.view)
return viewNode
}))
}
}
build() {
const ret = document.createElement('div')
ret.style.overflow = "hidden"
ret.style.display = "inline"
ret.style.whiteSpace = "nowrap"
let touchStartX = 0
let currentIndex = 0
ret.ontouchstart = (ev) => {
currentIndex = Math.round(ret.scrollLeft / ret.offsetWidth)
touchStartX = ev.touches[0].pageX
}
ret.ontouchmove = (ev) => {
const offsetX = (touchStartX - ev.touches[0].pageX) * 3
ret.scrollTo({
left: currentIndex * ret.offsetWidth + offsetX
})
}
ret.ontouchcancel = ret.ontouchend = () => {
currentIndex = Math.round(ret.scrollLeft / ret.offsetWidth)
ret.scrollTo({
left: currentIndex * ret.offsetWidth,
behavior: "smooth"
})
}
return ret
}
getSlidedPage() {
return Math.round(this.view.scrollLeft / this.view.offsetWidth)
}
slidePage(params: { page: number, smooth: boolean }) {
if (params.smooth) {
this.view.scrollTo({
left: this.view.offsetWidth * params.page,
behavior: "smooth"
})
} else {
this.view.scrollTo({
left: this.view.offsetWidth * params.page
})
}
if (this.onPageSelectedFuncId.length > 0) {
this.callJSResponse(this.onPageSelectedFuncId, params.page)
}
}
}