UNPKG

react-turntable

Version:
399 lines (341 loc) 16.8 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); exports.easeOut = easeOut; var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** * @author Jinke.Li * @version 1.2.7 * @description https://juejin.im/post/5992b6065188257dd3664dbc */ function easeOut(t, b, c, d) { if ((t /= d / 2) < 1) return c / 2 * t * t + b; return -c / 2 * (--t * (t - 2) - 1) + b; } var prefix = 'react-turntable'; var ReactTurntable = function (_PureComponent) { _inherits(ReactTurntable, _PureComponent); function ReactTurntable(props) { _classCallCheck(this, ReactTurntable); var _this = _possibleConstructorReturn(this, (ReactTurntable.__proto__ || Object.getPrototypeOf(ReactTurntable)).call(this, props)); _this.state = { isRotate: false, startRotate: 0 }; _this.noticePrize = function () { return _this.__noticePrize__REACT_HOT_LOADER__.apply(_this, arguments); }; _this.rotateTurntable = function () { return _this.__rotateTurntable__REACT_HOT_LOADER__.apply(_this, arguments); }; _this.getSelectedPrize = function () { return _this.__getSelectedPrize__REACT_HOT_LOADER__.apply(_this, arguments); }; _this.onStartRotate = function () { return _this.__onStartRotate__REACT_HOT_LOADER__.apply(_this, arguments); }; _this.stopRotate = function () { return _this.__stopRotate__REACT_HOT_LOADER__.apply(_this, arguments); }; _this.initTurntable = function () { return _this.__initTurntable__REACT_HOT_LOADER__.apply(_this, arguments); }; _this.getTurntable = function () { return _this.__getTurntable__REACT_HOT_LOADER__.apply(_this, arguments); }; _this.canvas = null; _this.ctx = null; _this.animateId = null; return _this; } _createClass(ReactTurntable, [{ key: '__getTurntable__REACT_HOT_LOADER__', value: function __getTurntable__REACT_HOT_LOADER__() { if (this.props.getTurntable) { this.props.getTurntable({ start: this.onStartRotate, stop: this.stopRotate }); } } }, { key: '__initTurntable__REACT_HOT_LOADER__', value: function __initTurntable__REACT_HOT_LOADER__() { var _props = this.props, width = _props.width, height = _props.height, prizes = _props.prizes; this.prizes = prizes; this.startRotate = 0; this.rotateTime = 0; this.rotateAllTime = 0; this.rotateChange = 0; this.ctx = this.canvas.getContext('2d'); this.canvas.width = width; this.canvas.height = height; this.awardRotate = Math.PI * 2 / prizes.length; this.centerX = this.canvas.width / 2; this.centerY = this.canvas.height / 2; this.R = this.canvas.width / 2 - 20; this.TEXT_R = this.R - 50; this.INSERT_R = 0; this.drawTurntable(); } }, { key: '__stopRotate__REACT_HOT_LOADER__', value: function __stopRotate__REACT_HOT_LOADER__() { this.setState({ isRotate: false }); window.cancelAnimationFrame(this.animateId); this.noticePrize(); } }, { key: '__onStartRotate__REACT_HOT_LOADER__', value: function __onStartRotate__REACT_HOT_LOADER__() { var _this2 = this; var _props2 = this.props, speed = _props2.speed, duration = _props2.duration, onStart = _props2.onStart; if (this.state.isRotate) return; if (onStart && !onStart()) return; this.setState({ isRotate: true }, function () { _this2.rotateTime = 0; _this2.rotateAllTime = Math.random() * 5 + duration; _this2.rotateChange = Math.random() * 10 + speed / 100; _this2.rotateTurntable(); }); } }, { key: '__getSelectedPrize__REACT_HOT_LOADER__', value: function __getSelectedPrize__REACT_HOT_LOADER__() { var startAngle = this.startRotate * 180 / Math.PI, awardAngle = this.awardRotate * 180 / Math.PI, pointerAngle = 90, overAngle = (startAngle + pointerAngle) % 360, restAngle = 360 - overAngle, index = Math.floor(restAngle / awardAngle); return this.prizes[index]; } }, { key: '__rotateTurntable__REACT_HOT_LOADER__', value: function __rotateTurntable__REACT_HOT_LOADER__() { this.rotateTime += 20; if (this.rotateTime >= this.rotateAllTime) { this.setState({ isRotate: false }); this.noticePrize(); return; } var _rotateChange = (this.rotateChange - easeOut(this.rotateTime, 0, this.rotateChange, this.rotateAllTime)) * (Math.PI / 180); this.startRotate += _rotateChange; this.drawTurntable(); this.animateId = requestAnimationFrame(this.rotateTurntable); } }, { key: '__noticePrize__REACT_HOT_LOADER__', value: function __noticePrize__REACT_HOT_LOADER__() { var prize = this.getSelectedPrize(); this.props.onComplete && this.props.onComplete(prize); } }, { key: 'render', value: function render() { var _this3 = this; var _props3 = this.props, clickText = _props3.clickText, style = _props3.style, className = _props3.className, width = _props3.width, height = _props3.height, hiddenButton = _props3.hiddenButton; var styles = _extends({}, style, { width: width, height: height }); return _react2.default.createElement( 'div', { className: (0, _classnames2.default)(prefix, prefix + '-section', className), style: styles }, _react2.default.createElement('canvas', { id: 'react-turntable-section-canvas', ref: function ref(node) { return _this3.canvas = node; } }), !hiddenButton && (Object.is(typeof clickText === 'undefined' ? 'undefined' : _typeof(clickText), 'string') ? _react2.default.createElement( 'div', { className: 'react-turntable-section-btn', onClick: this.onStartRotate }, clickText ) : _react2.default.createElement( 'div', { onClick: this.onStartRotate }, clickText )) ); } }, { key: 'drawTurntable', value: function drawTurntable() { var ctx = this.ctx; ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); var _props4 = this.props, primaryColor = _props4.primaryColor, secondaryColor = _props4.secondaryColor, _props4$fontStyle = _props4.fontStyle, fontVertical = _props4$fontStyle.fontVertical, fontWeight = _props4$fontStyle.fontWeight, fontFamily = _props4$fontStyle.fontFamily, size = _props4$fontStyle.size, color = _props4$fontStyle.color; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = this.prizes.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var _step$value = _slicedToArray(_step.value, 2), i = _step$value[0], prize = _step$value[1]; var _currentStartRotate = this.startRotate + this.awardRotate * i; var _currentEndRotate = _currentStartRotate + this.awardRotate; this.ctx.save(); i % 2 === 0 ? ctx.fillStyle = primaryColor : ctx.fillStyle = secondaryColor; ctx.beginPath(); ctx.arc(this.centerX, this.centerY, this.R, _currentStartRotate, _currentEndRotate, false); ctx.arc(this.centerX, this.centerY, this.INSERT_R, _currentEndRotate, _currentStartRotate, true); ctx.fill(); ctx.closePath(); ctx.restore(); ctx.save(); ctx.beginPath(); ctx.font = fontWeight + ' ' + (/.*px$/.test(size) ? size : size + 'px') + ' ' + fontFamily; ctx.fillStyle = color; ctx.textBaseline = 'middle'; var currentX = Math.cos(_currentStartRotate + this.awardRotate / 2) * this.TEXT_R; var currentY = Math.sin(_currentStartRotate + this.awardRotate / 2) * this.TEXT_R; ctx.translate(this.centerX + currentX, this.centerY + currentY); ctx.rotate(_currentStartRotate + this.awardRotate / 2 + Math.PI / 2); var _ctx$measureText = ctx.measureText(prize), fontWidth = _ctx$measureText.width; if (fontVertical === true) { ctx.translate(0, Math.min(fontWidth, 25)); ctx.rotate(90 / 180 * Math.PI); } ctx.fillText(prize, -fontWidth / 2, 0); ctx.closePath(); ctx.restore(); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } }, { key: 'destroyContext', value: function destroyContext() { window.cancelAnimationFrame(this.animateId); delete this.canvas; delete this.ctx; } }, { key: 'compatibilityFrame', value: function compatibilityFrame() { window.requestAnimFrame = function () { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) { return window.setTimeout(callback, 1000 / 60); }; }(); window.cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame; } }, { key: 'componentWillMount', value: function componentWillMount() { if (this.props.prizes.length < 2) throw new Error('options prizes It needs to be an array , Not less than two'); } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { this.destroyContext(); } }, { key: 'componentDidMount', value: function componentDidMount() { this.compatibilityFrame(); this.initTurntable(); this.getTurntable(); } }]); return ReactTurntable; }(_react.PureComponent); ReactTurntable.defaultProps = { width: 500, height: 500, speed: 1000, //旋转速度 duration: 5000, //旋转时间 prizes: [], clickText: 'Click', primaryColor: '#83AF9B', secondaryColor: '#C8C8A9', fontStyle: { color: '#fff', size: '14px', fontWeight: 'bold', fontVertical: false, fontFamily: 'Microsoft YaHei' }, onStart: function onStart() { return true; }, hiddenButton: false }; ReactTurntable.propTypes = { width: _propTypes2.default.number.isRequired, height: _propTypes2.default.number.isRequired, prizes: _propTypes2.default.array.isRequired, clickText: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.object]), primaryColor: _propTypes2.default.string, secondaryColor: _propTypes2.default.string, speed: _propTypes2.default.number, duration: _propTypes2.default.number, onComplete: _propTypes2.default.func, onStart: _propTypes2.default.func, fontVertical: _propTypes2.default.bool, fontStyle: _propTypes2.default.object, hiddenButton: _propTypes2.default.bool }; var _default = ReactTurntable; exports.default = _default; ; var _temp = function () { if (typeof __REACT_HOT_LOADER__ === 'undefined') { return; } __REACT_HOT_LOADER__.register(easeOut, 'easeOut', 'src/index.js'); __REACT_HOT_LOADER__.register(prefix, 'prefix', 'src/index.js'); __REACT_HOT_LOADER__.register(ReactTurntable, 'ReactTurntable', 'src/index.js'); __REACT_HOT_LOADER__.register(_default, 'default', 'src/index.js'); }(); ;