avg-core-ts
Version:
Develop Adventure Game (or ADV, Visual Novel, Galgame, etc.) on your own!
201 lines (166 loc) • 6.58 kB
JSX
/**
* @file Scroller component
* @author MicroMatrix <yangpan.1985@bytedance.com>
* @copyright 2012-2020 bytedance
* @link git@code.byted.org:yangpan.1985/avg.git
*/
import React from 'react';
import PropTypes from 'prop-types';
import createComponent from 'components/createComponent';
import ContainerMixin from 'components/ContainerMixin';
import NodeMixin from 'components/NodeMixin';
const PIXI = require('pixi.js');
const RawScroller = createComponent('RawScroller', ContainerMixin, NodeMixin, {
createNode() {
// this.node = new PixiLayer();
this.node = new PIXI.Graphics();
const button = new PIXI.Graphics();
this.node.addChild(button);
},
mountNode(props) {
this.setProperties(props);
const layer = this.node;
const button = this.node.children[0];
layer.interactive = true;
button.interactive = true;
button.buttonMode = true;
const buttonMouseDown = e => {
button.cachedX = button.x;
button.cachedY = button.y;
button.clear();
button.beginFill(button.buttonColor, button.buttonAlpha);
if (layer.direction === 'vertical') {
const radius = layer.backgroundWidth / 2;
button.drawRoundedRect(0, 0, layer.backgroundWidth, button.buttonLength, radius);
button.x = 0;
} else {
const radius = layer.backgroundHeight / 2;
button.drawRoundedRect(0, 0, button.buttonLength, layer.backgroundHeight, radius);
button.y = 0;
}
button.endFill();
button.isPressDown = true;
button.startPointerGlobalX = e.data.global.x;
button.startPointerGlobalY = e.data.global.y;
// e.stopPropagation();
};
const buttonMouseUp = () => {
button.clear();
button.beginFill(button.buttonColor, button.buttonAlpha);
if (layer.direction === 'vertical') {
const radius = button.buttonWidth / 2;
button.drawRoundedRect(0, 0, button.buttonWidth, button.buttonLength, radius);
button.x = button.cachedX;
} else {
const radius = button.buttonWidth / 2;
button.drawRoundedRect(0, 0, button.buttonLength, button.buttonWidth, radius);
button.y = button.cachedY;
}
button.endFill();
button.isPressDown = false;
// e.stopPropagation();
};
button.on('mousedown', buttonMouseDown);
button.on('touchstart', buttonMouseDown);
button.on('mouseup', buttonMouseUp);
button.on('touchend', buttonMouseUp);
button.on('mouseupoutside', buttonMouseUp);
button.on('touchendoutside', buttonMouseUp);
/* set event */
layer._ongoto = props.onGoto;
button._ondrag = props.onDrag;
const layerMouseDown = e => {
if (!button.isPressDown) {
layer._ongoto && layer._ongoto(e);
}
e.stopPropagation();
};
layer.on('mousedown', layerMouseDown);
const buttonMouseMove = e => {
if (button.isPressDown) {
button._ondrag && button._ondrag({
deltaX: (e.data.global.x - button.startPointerGlobalX) / layer.backgroundWidth,
deltaY: (e.data.global.y - button.startPointerGlobalY) / layer.backgroundHeight,
});
button.startPointerGlobalX = e.data.global.x;
button.startPointerGlobalY = e.data.global.y;
e.stopPropagation();
}
};
button.on('mousemove', buttonMouseMove);
button.on('touchmove', buttonMouseMove);
return layer;
},
updateNode(prevProps, props) {
this.setProperties(props);
const layer = this.node;
const button = this.node.children[0];
layer._ongoto = props.onGoto;
button._ondrag = props.onDrag;
},
setProperties(props) {
const p = {
backgroundWidth: props.backgroundWidth || 10,
backgroundHeight: props.backgroundHeight || 10,
direction: props.direction || 'vertical',
backgroundColor: (typeof props.backgroundColor === 'number') ? props.backgroundColor : 0xffffff,
backgroundAlpha: (typeof props.backgroundAlpha === 'number') ? props.backgroundAlpha : 1,
x: props.x || 0,
y: props.y || 0,
visible: (typeof props.visible === 'boolean') ? props.visible : true,
buttonWidth: props.buttonWidth || 10,
buttonColor: (typeof props.buttonColor === 'number') ? props.buttonColor : 0xffffff,
buttonAlpha: (typeof props.buttonAlpha === 'number') ? props.buttonAlpha : 1,
buttonLength: props.buttonLength || 10,
buttonPosition: props.buttonPosition || 0,
};
const layer = this.node;
layer.clear();
layer.beginFill(p.backgroundColor, p.backgroundAlpha);
layer.drawRect(0, 0, p.backgroundWidth, p.backgroundHeight);
layer.endFill();
layer.x = p.x;
layer.y = p.y;
layer.visible = p.visible;
const button = this.node.children[0];
// 若为按下状态,说明当前滚动条正在被拖动,不进行样式重绘,也没必要重绘
button.clear();
button.beginFill(p.buttonColor, p.buttonAlpha);
if (p.direction === 'vertical') {
const radius = (button.isPressDown ? p.backgroundWidth : p.buttonWidth) / 2;
button.drawRoundedRect(0, 0, (button.isPressDown ? p.backgroundWidth : p.buttonWidth), p.buttonLength, radius);
} else {
const radius = (button.isPressDown ? p.backgroundHeight : p.buttonWidth) / 2;
button.drawRoundedRect(0, 0, p.buttonLength, (button.isPressDown ? p.backgroundHeight : p.buttonWidth), radius);
}
button.endFill();
if (p.direction === 'vertical') {
!button.isPressDown && (button.x = (p.backgroundWidth - p.buttonWidth) / 2);
button.y = (p.backgroundHeight - p.buttonLength) * p.buttonPosition;
} else {
!button.isPressDown && (button.y = (p.backgroundHeight - p.buttonWidth) / 2);
button.x = (p.backgroundWidth - p.buttonLength) * p.buttonPosition;
}
/* store size info for event */
layer.backgroundColor = p.backgroundColor;
layer.backgroundAlpha = p.backgroundAlpha;
layer.backgroundWidth = p.backgroundWidth;
layer.backgroundHeight = p.backgroundHeight;
button.buttonColor = p.buttonColor;
button.buttonAlpha = p.buttonAlpha;
button.buttonWidth = p.buttonWidth;
button.buttonLength = p.buttonLength;
layer.direction = p.direction;
}
});
export default class Scroller extends React.PureComponent {
static propTypes = {
x: PropTypes.number,
y: PropTypes.number,
visible: PropTypes.bool,
children: PropTypes.any,
};
render() {
return React.createElement(RawScroller, this.props, this.props.children);
}
}