UNPKG

avg-core-ts

Version:

Develop Adventure Game (or ADV, Visual Novel, Galgame, etc.) on your own!

201 lines (166 loc) 6.58 kB
/** * @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); } }