├── .gitignore ├── examples ├── images │ ├── btn.png │ ├── cup.png │ ├── Tshirt.png │ ├── metal.png │ ├── movie.png │ ├── pro5.png │ ├── thanks.png │ └── umbrella.png ├── transition.html └── frame.html ├── .babelrc ├── gulpfile.js ├── rollup.config.js ├── src ├── tween.js └── index.js ├── package.json ├── README.md ├── lib └── turntable.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | npm-debug.log 4 | -------------------------------------------------------------------------------- /examples/images/btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coffeedeveloper/turntable/HEAD/examples/images/btn.png -------------------------------------------------------------------------------- /examples/images/cup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coffeedeveloper/turntable/HEAD/examples/images/cup.png -------------------------------------------------------------------------------- /examples/images/Tshirt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coffeedeveloper/turntable/HEAD/examples/images/Tshirt.png -------------------------------------------------------------------------------- /examples/images/metal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coffeedeveloper/turntable/HEAD/examples/images/metal.png -------------------------------------------------------------------------------- /examples/images/movie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coffeedeveloper/turntable/HEAD/examples/images/movie.png -------------------------------------------------------------------------------- /examples/images/pro5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coffeedeveloper/turntable/HEAD/examples/images/pro5.png -------------------------------------------------------------------------------- /examples/images/thanks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coffeedeveloper/turntable/HEAD/examples/images/thanks.png -------------------------------------------------------------------------------- /examples/images/umbrella.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coffeedeveloper/turntable/HEAD/examples/images/umbrella.png -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-1"], 3 | "sourceMaps": true, 4 | "plugins": ["add-module-exports", "transform-es2015-modules-umd"], 5 | "moduleId": "Turntable" 6 | } 7 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var uglify = require('gulp-uglify'); 3 | var rename = require('gulp-rename'); 4 | 5 | gulp.task('compress', function() { 6 | return gulp.src('turntable.js') 7 | .pipe(uglify()) 8 | .pipe(rename({ suffix: '.min' })) 9 | .pipe(gulp.dest('.')); 10 | }); 11 | 12 | gulp.task('default', ['compress']); 13 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import buble from 'rollup-plugin-buble'; 2 | import nodeResolve from 'rollup-plugin-node-resolve'; 3 | import commonjs from 'rollup-plugin-commonjs'; 4 | 5 | export default { 6 | entry: 'src/index.js', 7 | dest: 'lib/turntable.js', 8 | moduleName: 'Turntable', 9 | format: 'umd', 10 | plugins: [ 11 | nodeResolve({ 12 | jsnext: true, 13 | browser: true, 14 | }), 15 | commonjs(), 16 | buble() 17 | ] 18 | }; 19 | -------------------------------------------------------------------------------- /src/tween.js: -------------------------------------------------------------------------------- 1 | let start = 0; 2 | let during = 5 * 60; 3 | let init = parseInt(this.svg.style.transform 4 | .replace('rotate(', '') 5 | .replace('deg)', '') || 0, 10); 6 | let end = init + (360 * 8); 7 | 8 | let s = () => { 9 | start++; 10 | let r = tween.easeInQuart(start, init, end - init, during); 11 | this.svg.style.transform = 'rotate(' + r + 'deg)'; 12 | if (start < during) requestAnimationFrame(s); 13 | else { 14 | start = 0; 15 | init = parseInt(this.svg.style.transform 16 | .replace('rotate(', '') 17 | .replace('deg)', ''), 10); 18 | end = init + (360 * 8); 19 | requestAnimationFrame(p); 20 | } 21 | }; 22 | 23 | let p = () => { 24 | start++; 25 | let r = tween.linear(start, init, end - init, during); 26 | this.svg.style.transform = 'rotate(' + r + 'deg)'; 27 | if (start < during) requestAnimationFrame(p); 28 | }; 29 | 30 | s(); 31 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lottery-turntable", 3 | "version": "1.3.6", 4 | "description": "turntable for lottery", 5 | "main": "lib/turntable.js", 6 | "scripts": { 7 | "dev": "rollup -c -w", 8 | "build": "rollup -c", 9 | "release": "rollup -c && uglifyjs -o build/turntable.min.js lib/turntable.js", 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/coffeedeveloper/turntable.git" 15 | }, 16 | "keywords": [ 17 | "lottery", 18 | "turntable" 19 | ], 20 | "author": "CoffeeDeveloper", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/coffeedeveloper/turntable/issues" 24 | }, 25 | "homepage": "https://github.com/coffeedeveloper/turntable#readme", 26 | "devDependencies": { 27 | "rollup": "^0.41.4", 28 | "rollup-plugin-buble": "^0.15.0", 29 | "rollup-plugin-commonjs": "^7.0.0", 30 | "rollup-plugin-node-resolve": "^2.0.0", 31 | "rollup-watch": "^3.2.2", 32 | "uglify-js": "^2.6.2" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 抽奖转盘 2 | 3 | 由于每个抽奖活动的样式都会不一样,因此这个插件只实现了绘画转盘及转盘转动的模块。 4 | 点击抽奖按钮,和抽奖转盘的外框则自行实现,可以参考`examples`里面的例子。 5 | 6 | **支持IE9以上版本浏览器** 7 | 8 | #### 示例 9 | 10 | ![示例](http://oap12gnk8.bkt.clouddn.com/turntable-example.png) 11 | - [默认方式转盘](http://example.coffeedeveloper.com/turntable/examples/frame.html) 12 | - [transition方式转盘](http:///example.coffeedeveloper.com/turntable/examples/transition.html) 13 | 14 | #### 安装 15 | 16 | ``` 17 | npm install lottery-turntable 18 | 19 | or 20 | 21 | 直接下载 https://raw.githubusercontent.com/coffeedeveloper/turntable/master/build/turntable.min.js 22 | ``` 23 | 24 | #### 接口说明 25 | ```javascript 26 | var turntable = new Turntable({ 27 | size: 320, //转盘尺寸,默认为320 28 | textSpace: 15, //奖品名称距离转盘边距,默认为15 29 | imgSpace: 50, //奖品图片距离转盘边距,默认为50 30 | speed: 5, //触发start事件后,转盘开始转动的速度,数字必须能给360整除 31 | fastSpeed: 10, //转盘进入高速转动的速度,数字必须能够给360整除 32 | slowSpeed: 5, //转盘从高速转动降下来的速度,数字必须能够给360整除 33 | speedUp: 2000, //多少毫秒后进入高速转动 34 | speedDown: 2000, //触发stop事件后,多少毫秒进入缓速 35 | values: [], //奖品对象,根据传多少个奖品对象,自动生成相应数量的转盘抽奖内容 36 | container: document.getElementById('id') //转盘的容器,如果设置了之后,new Turntable的时候会自动填充内容 37 | }); 38 | ``` 39 | 40 | #### 新增支持`transition`方式 41 | 42 | ```javascript 43 | var turntabl = new Turntable({ 44 | type: 'transition', //转盘转动类型 45 | size: 320, //转盘尺寸,默认为320 46 | textSpace: 15, //奖品名称距离转盘边距,默认为15 47 | imgSpace: 50, //奖品图片距离转盘边距,默认为50 48 | speed: 5, //transition动画持续多长时间,秒为单位 49 | ring: 8, //转动多少圈后到达终点,越大转速越快 50 | values: [], //奖品对象,根据传多少个奖品对象,自动生成相应数量的转盘抽奖内容 51 | container: document.getElementById('id') //转盘的容器,如果设置了之后,new Turntable的时候会自动填充内容 52 | }); 53 | ``` 54 | 55 | #### turntable的奖品对象说明 56 | 57 | ```javascript 58 | var turntable = new Turntable({ 59 | values: [ 60 | { 61 | id: 1, //奖品id,可以重复(比如:谢谢参与就可以有n个,中奖后会随即选择一个转动到该位置 62 | name: '一等奖', //奖品名称 63 | img: { 64 | src: 'gift.png', //奖品图片路径 65 | width: 50, //奖品图片宽度,请根据实际情况去设置,避免太大 66 | height: 50, //奖品图片高度,请根据实际情况去设置,避免太大,与宽度等比率缩放 67 | }, 68 | bg: '#ccc', //该奖品的在转盘中的扇形背景颜色 69 | fill: '#000' //奖品名称的文字颜色 70 | } 71 | ] 72 | }); 73 | ``` 74 | 75 | #### turntable事件说明 76 | 77 | ##### draw 78 | 将转盘实例化到容器当中,如果设置`container`属性,则不需要调用该方法 79 | 80 | ```javascript 81 | turntable.draw(document.getElementById('container')); 82 | ``` 83 | 84 | #### start(非transition方式的抽奖) 85 | 开始抽奖(开始转动转盘) 86 | 87 | ```javascript 88 | turntable.start(); 89 | ``` 90 | 91 | #### stop(非transition方式的抽奖) 92 | 抽奖结束(停止转动转盘) 93 | 94 | ```javascript 95 | //id 中奖的奖品id,对应初始化选项里面的values的奖品对象的id 96 | //callback 转盘滚动结束后,触发回调 97 | turntable.stop(id, function(data) { 98 | console.log(data); //对应在values里面的礼品对象 99 | }); 100 | ``` 101 | 102 | #### goto(只能用于transition方式的抽奖) 103 | 跳转到指定的id的奖品,在请求后台取得中奖奖品id后,就滚动到对应的奖品 104 | 105 | ```javascript 106 | //id 中奖的奖品id,对应初始化选项里面的values的奖品对象的id 107 | //callback 转盘滚动结束后,触发回调 108 | turntable.goto(id, function(data) { 109 | console.log(data); //对应在values里面的礼品对象 110 | }); 111 | ``` 112 | -------------------------------------------------------------------------------- /examples/transition.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | transition 9 | 36 | 37 | 38 | 39 |
40 |
41 |
42 | 43 |
44 | 45 | 46 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /examples/frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | frame 9 | 36 | 37 | 38 | 39 |
40 |
41 |
42 | 43 |
44 | 45 |

46 | 点击抽奖开始抽奖,再次点击抽奖停止抽奖 47 |

48 | 49 | 50 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | const tween = { 2 | linear: (t, b, c, d) => c*t/d + b, 3 | easeInQuart: (t, b, c, d) => c * (t /= d) * t * t * t + b, 4 | easeOutQuart: (t, b, c, d) => -c * ((t=t/d-1)*t*t*t - 1) + b, 5 | }; 6 | 7 | const appendCSS = (css) => { 8 | let head = document.head || document.getElementsByTagName('head')[0]; 9 | let style = document.createElement('style'); 10 | style.appendChild(document.createTextNode(css)); 11 | head.appendChild(style); 12 | }; 13 | 14 | const extend = function(target) { 15 | for (var i = 0; i < arguments.length; i++) { 16 | let arg = arguments[i]; 17 | for (let p in arg) { 18 | target[p] = arg[p]; 19 | } 20 | } 21 | return target; 22 | }; 23 | 24 | const createSvgEle = name => document.createElementNS('http://www.w3.org/2000/svg', name); 25 | 26 | const setAttrs = (ele, attrs) => { 27 | for (let t in attrs) { 28 | if (t == 'href') ele.setAttributeNS('http://www.w3.org/1999/xlink', t, attrs[t]); 29 | else ele.setAttribute(t, attrs[t]); 30 | } 31 | 32 | return ele; 33 | }; 34 | 35 | const getPathPoint = (oPoint, degree) => { 36 | return { 37 | x: oPoint.x + oPoint.r * Math.cos(degree * (Math.PI / 180)), 38 | y: oPoint.y + oPoint.r * Math.sin(degree * (Math.PI / 180)), 39 | degree, 40 | } 41 | }; 42 | 43 | const getPointsDistance = (o, t) => Math.sqrt(Math.pow(t.x - o.x, 2) + Math.pow(t.y - o.y, 2)); 44 | 45 | const movePoint = (oPoint, tPoint, dis, len) => { 46 | let x = -1 * ((dis * (tPoint.x - oPoint.x) / len - tPoint.x)); 47 | let y = -1 * ((dis * (tPoint.y - oPoint.y) / len - tPoint.y)); 48 | return { x, y }; 49 | } 50 | 51 | const random = (min, max) => min + Math.floor(Math.random() * (max - min + 1)); 52 | 53 | const defaults = { 54 | type: 'frame', 55 | size: 320, 56 | textSpace: 15, 57 | imgSpace: 50, 58 | speed: 5, 59 | fastSpeed: 10, 60 | slowSpeed: 5, 61 | speedUp: 2000, 62 | speedDown: 2000, 63 | values: [], 64 | className: 'turntable-effect', 65 | ring: 8, 66 | }; 67 | 68 | let requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame 69 | || window.mozRequestAnimationFrame || window.oRequestAnimationFrame 70 | || window.msRequestAnimationFrame; 71 | 72 | export default class Turntable { 73 | constructor(options) { 74 | this.opts = extend({}, defaults, options); 75 | if (!this.opts.values) { 76 | throw Error('values必须要有值'); 77 | return; 78 | } 79 | 80 | let half = this.opts.size / 2; 81 | this.center = { 82 | x: half, 83 | y: half, 84 | r: half, 85 | }; 86 | 87 | //圆的x轴坐标 88 | this.startPoint = { 89 | x: this.opts.size, 90 | y: half, 91 | }; 92 | 93 | this.values = this.opts.values; 94 | this.count = this.opts.values.length; 95 | this.degree = 360 / this.count; 96 | 97 | this.container = null; 98 | this.svg = null; 99 | 100 | if (this.opts.container) this.draw(this.opts.container); 101 | 102 | } 103 | 104 | getValueIndexById(id) { 105 | let r = this.values.filter(d => d.id == id).map(d => d.index); 106 | 107 | return r[random(0, r.length - 1)]; 108 | } 109 | 110 | getValueDegreeByIndex(index) { 111 | return this.values[index].degree; 112 | } 113 | 114 | setTransform(val) { 115 | this.svg.style.msTransform = val; 116 | this.svg.style.oTransform = val; 117 | this.svg.style.mozTransform = val; 118 | this.svg.style.webkitTransform = val; 119 | this.svg.style.transform = val; 120 | } 121 | 122 | turning() { 123 | this.turnTotal += this.turnBase; 124 | if (this.turnTotal >= 360 || this.turnTotal <= -360 ) this.turnTotal = 0; 125 | 126 | this.setTransform('rotate(' + -this.turnTotal + 'deg)'); 127 | } 128 | 129 | turned() { 130 | if (this.turnTotal >= 360 || this.turnTotal <= -360 ) this.turnTotal = 0; 131 | this.turnTotal += this.turnBase; 132 | 133 | if (parseInt(this.turnTotal, 10) == parseInt(this.turnEndDegree)) { 134 | cancelAnimationFrame(this.animation); 135 | this.setTransform('rotate(' + -this.turnTotal + 'deg)'); 136 | this.isTurning = false; 137 | this.turnCallback(this.opts.values[this.index]); 138 | return false; 139 | } 140 | 141 | this.setTransform('rotate(' + -this.turnTotal + 'deg)'); 142 | return true; 143 | } 144 | 145 | turn() { 146 | this.animation = requestAnimationFrame(function() { 147 | if (!this.isTurnStop) { 148 | this.turning(); 149 | this.turn(); 150 | } else { 151 | if (this.turned()) { 152 | this.turn(); 153 | } 154 | } 155 | }.bind(this)); 156 | } 157 | 158 | start() { 159 | if (this.isTurning) return; 160 | this.turnBase = this.opts.speed; 161 | this.turnTotal = 0; 162 | this.isTurnStop = false; 163 | this.index = null; 164 | this.isTurning = true; 165 | this.turn(); 166 | 167 | setTimeout(function() { 168 | this.turnBase = this.opts.fastSpeed; 169 | }.bind(this), this.opts.speedUp); 170 | } 171 | 172 | stop(id, cb) { 173 | this.index = this.getValueIndexById(id); 174 | this.turnEndDegree = this.getValueDegreeByIndex(this.index); 175 | this.turnBase = this.opts.slowSpeed; 176 | if (typeof cb !== 'function') cb = function(){}; 177 | this.turnCallback = cb; 178 | 179 | setTimeout(function() { 180 | this.turnBase = 1; 181 | this.isTurnStop = true; 182 | }.bind(this), this.opts.speedDown); 183 | } 184 | 185 | goto(id, cb) { 186 | if (this.isTurning) return; 187 | this.isTurning = true; 188 | let deg = Math.abs(this.svg.style.transform.replace('rotate(', '').replace('deg)', '') || 0); 189 | let ndeg = deg != 0 ? Math.abs(this.turnEndDegree) : 0; 190 | 191 | ndeg = Math.abs(this.opts.ring * 360 + deg - ndeg); 192 | 193 | this.index = this.getValueIndexById(id); 194 | this.turnEndDegree = this.getValueDegreeByIndex(this.index); 195 | this.turnCallback = cb; 196 | 197 | this.setTransform(`rotate(-${ndeg + this.turnEndDegree}deg)`); 198 | } 199 | 200 | draw(container) { 201 | var that = this; 202 | this.container = container; 203 | 204 | let svg = setAttrs(createSvgEle('svg'), { 205 | width: this.opts.size, 206 | height: this.opts.size, 207 | xmlns: 'http://www.w3.org/2000/svg', 208 | 'xmlns:xlink': 'http://www.w3.org/1999/xlink' 209 | }); 210 | 211 | let degree = this.degree; 212 | let pathStartPoint = this.startPoint; 213 | let pathEndPoint = getPathPoint(this.center, degree); 214 | 215 | this.values = this.values.map((info, i) => { 216 | info.degree = i == 0 ? 90 + this.degree / 2 : this.values[i-1].degree + this.degree; 217 | if (info.degree >= 360) info.degree = info.degree - 360; 218 | info.index = i; 219 | 220 | let g = createSvgEle('g'); 221 | 222 | let path = setAttrs(createSvgEle('path'), { 223 | fill: info.bg, 224 | d: ` 225 | M${this.center.x}, ${this.center.y} 226 | L${pathStartPoint.x}, ${pathStartPoint.y} 227 | A${this.center.x}, ${this.center.y} 228 | 1 0, 1 229 | ${pathEndPoint.x}, ${pathEndPoint.y} 230 | z 231 | ` 232 | }); 233 | 234 | g.appendChild(path); 235 | 236 | let fanCenterPoint = { 237 | x: (pathEndPoint.x + pathStartPoint.x) / 2, 238 | y: (pathEndPoint.y + pathStartPoint.y) / 2 239 | }; 240 | 241 | let centerDistance = getPointsDistance(fanCenterPoint, this.center); 242 | 243 | let textDegree = 180 - ((360 - this.degree * 2) / 2) / 2; 244 | let textPoint = movePoint(this.center, fanCenterPoint, this.opts.textSpace, centerDistance); 245 | let rotate = textDegree + this.degree * i; 246 | 247 | let text = setAttrs(createSvgEle('text'), { 248 | x: textPoint.x, 249 | y: textPoint.y, 250 | 'text-anchor': 'middle', 251 | fill: info.color, 252 | transform: `rotate(${rotate}, ${textPoint.x}, ${textPoint.y})` 253 | }); 254 | text.appendChild(document.createTextNode(info.name)); 255 | 256 | g.appendChild(text); 257 | 258 | if (info.img) { 259 | var imgPoint = movePoint(this.center, fanCenterPoint, this.opts.imgSpace, centerDistance); 260 | var img = setAttrs(createSvgEle('image'), { 261 | width: info.img.width, 262 | height: info.img.height, 263 | href: info.img.src, 264 | x: imgPoint.x, 265 | y: imgPoint.y, 266 | transform: `rotate(${rotate}, ${imgPoint.x}, ${imgPoint.y}) translate(${-(info.img.width / 2)}, ${-(info.img.height / 2)})` 267 | }); 268 | g.appendChild(img); 269 | } 270 | 271 | svg.appendChild(g); 272 | 273 | pathStartPoint = pathEndPoint; 274 | pathEndPoint = getPathPoint(this.center, this.degree + this.degree * (i + 1)); 275 | 276 | return info; 277 | }); 278 | 279 | container.appendChild(svg); 280 | this.svg = svg; 281 | 282 | if (this.opts.type == 'transition') this.initTransition(); 283 | } 284 | 285 | initTransition() { 286 | setAttrs(this.svg, {class: this.opts.className}); 287 | 288 | this.svg.addEventListener('transitionend', () => { 289 | this.isTurning = false; 290 | this.turnCallback(this.values[this.index]); 291 | }, false); 292 | 293 | appendCSS(` 294 | .${this.opts.className} { 295 | -webkit-transition: -webkit-transform ${this.opts.speed}s ease-in-out; 296 | transition: transform ${this.opts.speed}s ease-in-out; 297 | } 298 | `); 299 | } 300 | } 301 | -------------------------------------------------------------------------------- /lib/turntable.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global.Turntable = factory()); 5 | }(this, (function () { 'use strict'; 6 | 7 | var appendCSS = function (css) { 8 | var head = document.head || document.getElementsByTagName('head')[0]; 9 | var style = document.createElement('style'); 10 | style.appendChild(document.createTextNode(css)); 11 | head.appendChild(style); 12 | }; 13 | 14 | var extend = function(target) { 15 | var arguments$1 = arguments; 16 | 17 | for (var i = 0; i < arguments.length; i++) { 18 | var arg = arguments$1[i]; 19 | for (var p in arg) { 20 | target[p] = arg[p]; 21 | } 22 | } 23 | return target; 24 | }; 25 | 26 | var createSvgEle = function (name) { return document.createElementNS('http://www.w3.org/2000/svg', name); }; 27 | 28 | var setAttrs = function (ele, attrs) { 29 | for (var t in attrs) { 30 | if (t == 'href') { ele.setAttributeNS('http://www.w3.org/1999/xlink', t, attrs[t]); } 31 | else { ele.setAttribute(t, attrs[t]); } 32 | } 33 | 34 | return ele; 35 | }; 36 | 37 | var getPathPoint = function (oPoint, degree) { 38 | return { 39 | x: oPoint.x + oPoint.r * Math.cos(degree * (Math.PI / 180)), 40 | y: oPoint.y + oPoint.r * Math.sin(degree * (Math.PI / 180)), 41 | degree: degree, 42 | } 43 | }; 44 | 45 | var getPointsDistance = function (o, t) { return Math.sqrt(Math.pow(t.x - o.x, 2) + Math.pow(t.y - o.y, 2)); }; 46 | 47 | var movePoint = function (oPoint, tPoint, dis, len) { 48 | var x = -1 * ((dis * (tPoint.x - oPoint.x) / len - tPoint.x)); 49 | var y = -1 * ((dis * (tPoint.y - oPoint.y) / len - tPoint.y)); 50 | return { x: x, y: y }; 51 | }; 52 | 53 | var random = function (min, max) { return min + Math.floor(Math.random() * (max - min + 1)); }; 54 | 55 | var defaults = { 56 | type: 'frame', 57 | size: 320, 58 | textSpace: 15, 59 | imgSpace: 50, 60 | speed: 5, 61 | fastSpeed: 10, 62 | slowSpeed: 5, 63 | speedUp: 2000, 64 | speedDown: 2000, 65 | values: [], 66 | className: 'turntable-effect', 67 | ring: 8, 68 | }; 69 | 70 | var requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame 71 | || window.mozRequestAnimationFrame || window.oRequestAnimationFrame 72 | || window.msRequestAnimationFrame; 73 | 74 | var Turntable = function Turntable(options) { 75 | this.opts = extend({}, defaults, options); 76 | if (!this.opts.values) { 77 | throw Error('values必须要有值'); 78 | return; 79 | } 80 | 81 | var half = this.opts.size / 2; 82 | this.center = { 83 | x: half, 84 | y: half, 85 | r: half, 86 | }; 87 | 88 | //圆的x轴坐标 89 | this.startPoint = { 90 | x: this.opts.size, 91 | y: half, 92 | }; 93 | 94 | this.values = this.opts.values; 95 | this.count = this.opts.values.length; 96 | this.degree = 360 / this.count; 97 | 98 | this.container = null; 99 | this.svg = null; 100 | 101 | if (this.opts.container) { this.draw(this.opts.container); } 102 | 103 | }; 104 | 105 | Turntable.prototype.getValueIndexById = function getValueIndexById (id) { 106 | var r = this.values.filter(function (d) { return d.id == id; }).map(function (d) { return d.index; }); 107 | 108 | return r[random(0, r.length - 1)]; 109 | }; 110 | 111 | Turntable.prototype.getValueDegreeByIndex = function getValueDegreeByIndex (index) { 112 | return this.values[index].degree; 113 | }; 114 | 115 | Turntable.prototype.setTransform = function setTransform (val) { 116 | this.svg.style.msTransform = val; 117 | this.svg.style.oTransform = val; 118 | this.svg.style.mozTransform = val; 119 | this.svg.style.webkitTransform = val; 120 | this.svg.style.transform = val; 121 | }; 122 | 123 | Turntable.prototype.turning = function turning () { 124 | this.turnTotal += this.turnBase; 125 | if (this.turnTotal >= 360 || this.turnTotal <= -360 ) { this.turnTotal = 0; } 126 | 127 | this.setTransform('rotate(' + -this.turnTotal + 'deg)'); 128 | }; 129 | 130 | Turntable.prototype.turned = function turned () { 131 | if (this.turnTotal >= 360 || this.turnTotal <= -360 ) { this.turnTotal = 0; } 132 | this.turnTotal += this.turnBase; 133 | 134 | if (parseInt(this.turnTotal, 10) == parseInt(this.turnEndDegree)) { 135 | cancelAnimationFrame(this.animation); 136 | this.setTransform('rotate(' + -this.turnTotal + 'deg)'); 137 | this.isTurning = false; 138 | this.turnCallback(this.opts.values[this.index]); 139 | return false; 140 | } 141 | 142 | this.setTransform('rotate(' + -this.turnTotal + 'deg)'); 143 | return true; 144 | }; 145 | 146 | Turntable.prototype.turn = function turn () { 147 | this.animation = requestAnimationFrame(function() { 148 | if (!this.isTurnStop) { 149 | this.turning(); 150 | this.turn(); 151 | } else { 152 | if (this.turned()) { 153 | this.turn(); 154 | } 155 | } 156 | }.bind(this)); 157 | }; 158 | 159 | Turntable.prototype.start = function start () { 160 | if (this.isTurning) { return; } 161 | this.turnBase = this.opts.speed; 162 | this.turnTotal = 0; 163 | this.isTurnStop = false; 164 | this.index = null; 165 | this.isTurning = true; 166 | this.turn(); 167 | 168 | setTimeout(function() { 169 | this.turnBase = this.opts.fastSpeed; 170 | }.bind(this), this.opts.speedUp); 171 | }; 172 | 173 | Turntable.prototype.stop = function stop (id, cb) { 174 | this.index = this.getValueIndexById(id); 175 | this.turnEndDegree = this.getValueDegreeByIndex(this.index); 176 | this.turnBase = this.opts.slowSpeed; 177 | if (typeof cb !== 'function') { cb = function(){}; } 178 | this.turnCallback = cb; 179 | 180 | setTimeout(function() { 181 | this.turnBase = 1; 182 | this.isTurnStop = true; 183 | }.bind(this), this.opts.speedDown); 184 | }; 185 | 186 | Turntable.prototype.goto = function goto (id, cb) { 187 | if (this.isTurning) { return; } 188 | this.isTurning = true; 189 | var deg = Math.abs(this.svg.style.transform.replace('rotate(', '').replace('deg)', '') || 0); 190 | var ndeg = deg != 0 ? Math.abs(this.turnEndDegree) : 0; 191 | 192 | ndeg = Math.abs(this.opts.ring * 360 + deg - ndeg); 193 | 194 | this.index = this.getValueIndexById(id); 195 | this.turnEndDegree = this.getValueDegreeByIndex(this.index); 196 | this.turnCallback = cb; 197 | 198 | this.setTransform(("rotate(-" + (ndeg + this.turnEndDegree) + "deg)")); 199 | }; 200 | 201 | Turntable.prototype.draw = function draw (container) { 202 | var this$1 = this; 203 | 204 | var that = this; 205 | this.container = container; 206 | 207 | var svg = setAttrs(createSvgEle('svg'), { 208 | width: this.opts.size, 209 | height: this.opts.size, 210 | xmlns: 'http://www.w3.org/2000/svg', 211 | 'xmlns:xlink': 'http://www.w3.org/1999/xlink' 212 | }); 213 | 214 | var degree = this.degree; 215 | var pathStartPoint = this.startPoint; 216 | var pathEndPoint = getPathPoint(this.center, degree); 217 | 218 | this.values = this.values.map(function (info, i) { 219 | info.degree = i == 0 ? 90 + this$1.degree / 2 : this$1.values[i-1].degree + this$1.degree; 220 | if (info.degree >= 360) { info.degree = info.degree - 360; } 221 | info.index = i; 222 | 223 | var g = createSvgEle('g'); 224 | 225 | var path = setAttrs(createSvgEle('path'), { 226 | fill: info.bg, 227 | d: ("\n M" + (this$1.center.x) + ", " + (this$1.center.y) + "\n L" + (pathStartPoint.x) + ", " + (pathStartPoint.y) + "\n A" + (this$1.center.x) + ", " + (this$1.center.y) + "\n 1 0, 1\n " + (pathEndPoint.x) + ", " + (pathEndPoint.y) + "\n z\n ") 228 | }); 229 | 230 | g.appendChild(path); 231 | 232 | var fanCenterPoint = { 233 | x: (pathEndPoint.x + pathStartPoint.x) / 2, 234 | y: (pathEndPoint.y + pathStartPoint.y) / 2 235 | }; 236 | 237 | var centerDistance = getPointsDistance(fanCenterPoint, this$1.center); 238 | 239 | var textDegree = 180 - ((360 - this$1.degree * 2) / 2) / 2; 240 | var textPoint = movePoint(this$1.center, fanCenterPoint, this$1.opts.textSpace, centerDistance); 241 | var rotate = textDegree + this$1.degree * i; 242 | 243 | var text = setAttrs(createSvgEle('text'), { 244 | x: textPoint.x, 245 | y: textPoint.y, 246 | 'text-anchor': 'middle', 247 | fill: info.color, 248 | transform: ("rotate(" + rotate + ", " + (textPoint.x) + ", " + (textPoint.y) + ")") 249 | }); 250 | text.appendChild(document.createTextNode(info.name)); 251 | 252 | g.appendChild(text); 253 | 254 | if (info.img) { 255 | var imgPoint = movePoint(this$1.center, fanCenterPoint, this$1.opts.imgSpace, centerDistance); 256 | var img = setAttrs(createSvgEle('image'), { 257 | width: info.img.width, 258 | height: info.img.height, 259 | href: info.img.src, 260 | x: imgPoint.x, 261 | y: imgPoint.y, 262 | transform: ("rotate(" + rotate + ", " + (imgPoint.x) + ", " + (imgPoint.y) + ") translate(" + (-(info.img.width / 2)) + ", " + (-(info.img.height / 2)) + ")") 263 | }); 264 | g.appendChild(img); 265 | } 266 | 267 | svg.appendChild(g); 268 | 269 | pathStartPoint = pathEndPoint; 270 | pathEndPoint = getPathPoint(this$1.center, this$1.degree + this$1.degree * (i + 1)); 271 | 272 | return info; 273 | }); 274 | 275 | container.appendChild(svg); 276 | this.svg = svg; 277 | 278 | if (this.opts.type == 'transition') { this.initTransition(); } 279 | }; 280 | 281 | Turntable.prototype.initTransition = function initTransition () { 282 | var this$1 = this; 283 | 284 | setAttrs(this.svg, {class: this.opts.className}); 285 | 286 | this.svg.addEventListener('transitionend', function () { 287 | this$1.isTurning = false; 288 | this$1.turnCallback(this$1.values[this$1.index]); 289 | }, false); 290 | 291 | appendCSS(("\n ." + (this.opts.className) + " {\n -webkit-transition: -webkit-transform " + (this.opts.speed) + "s ease-in-out;\n transition: transform " + (this.opts.speed) + "s ease-in-out;\n }\n ")); 292 | }; 293 | 294 | return Turntable; 295 | 296 | }))); 297 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | acorn-jsx@^3.0.1: 6 | version "3.0.1" 7 | resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" 8 | dependencies: 9 | acorn "^3.0.4" 10 | 11 | acorn-object-spread@^1.0.0: 12 | version "1.0.0" 13 | resolved "https://registry.yarnpkg.com/acorn-object-spread/-/acorn-object-spread-1.0.0.tgz#48ead0f4a8eb16995a17a0db9ffc6acaada4ba68" 14 | dependencies: 15 | acorn "^3.1.0" 16 | 17 | acorn@^3.0.4, acorn@^3.1.0, acorn@^3.3.0: 18 | version "3.3.0" 19 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" 20 | 21 | acorn@^4.0.1: 22 | version "4.0.11" 23 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.11.tgz#edcda3bd937e7556410d42ed5860f67399c794c0" 24 | 25 | align-text@^0.1.1, align-text@^0.1.3: 26 | version "0.1.4" 27 | resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" 28 | dependencies: 29 | kind-of "^3.0.2" 30 | longest "^1.0.1" 31 | repeat-string "^1.5.2" 32 | 33 | ansi-regex@^2.0.0: 34 | version "2.1.1" 35 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 36 | 37 | ansi-styles@^2.2.1: 38 | version "2.2.1" 39 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 40 | 41 | arr-diff@^2.0.0: 42 | version "2.0.0" 43 | resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" 44 | dependencies: 45 | arr-flatten "^1.0.1" 46 | 47 | arr-flatten@^1.0.1: 48 | version "1.0.1" 49 | resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.1.tgz#e5ffe54d45e19f32f216e91eb99c8ce892bb604b" 50 | 51 | array-unique@^0.2.1: 52 | version "0.2.1" 53 | resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" 54 | 55 | balanced-match@^0.4.1: 56 | version "0.4.2" 57 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" 58 | 59 | brace-expansion@^1.0.0: 60 | version "1.1.6" 61 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" 62 | dependencies: 63 | balanced-match "^0.4.1" 64 | concat-map "0.0.1" 65 | 66 | braces@^1.8.2: 67 | version "1.8.5" 68 | resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" 69 | dependencies: 70 | expand-range "^1.8.1" 71 | preserve "^0.2.0" 72 | repeat-element "^1.1.2" 73 | 74 | browser-resolve@^1.11.0: 75 | version "1.11.2" 76 | resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce" 77 | dependencies: 78 | resolve "1.1.7" 79 | 80 | buble@^0.15.0: 81 | version "0.15.2" 82 | resolved "https://registry.yarnpkg.com/buble/-/buble-0.15.2.tgz#547fc47483f8e5e8176d82aa5ebccb183b02d613" 83 | dependencies: 84 | acorn "^3.3.0" 85 | acorn-jsx "^3.0.1" 86 | acorn-object-spread "^1.0.0" 87 | chalk "^1.1.3" 88 | magic-string "^0.14.0" 89 | minimist "^1.2.0" 90 | os-homedir "^1.0.1" 91 | 92 | builtin-modules@^1.1.0: 93 | version "1.1.1" 94 | resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" 95 | 96 | camelcase@^1.0.2: 97 | version "1.2.1" 98 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" 99 | 100 | center-align@^0.1.1: 101 | version "0.1.3" 102 | resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" 103 | dependencies: 104 | align-text "^0.1.3" 105 | lazy-cache "^1.0.3" 106 | 107 | chalk@^1.1.3: 108 | version "1.1.3" 109 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 110 | dependencies: 111 | ansi-styles "^2.2.1" 112 | escape-string-regexp "^1.0.2" 113 | has-ansi "^2.0.0" 114 | strip-ansi "^3.0.0" 115 | supports-color "^2.0.0" 116 | 117 | cliui@^2.1.0: 118 | version "2.1.0" 119 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" 120 | dependencies: 121 | center-align "^0.1.1" 122 | right-align "^0.1.1" 123 | wordwrap "0.0.2" 124 | 125 | concat-map@0.0.1: 126 | version "0.0.1" 127 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 128 | 129 | decamelize@^1.0.0: 130 | version "1.2.0" 131 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 132 | 133 | escape-string-regexp@^1.0.2: 134 | version "1.0.5" 135 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 136 | 137 | estree-walker@^0.2.1: 138 | version "0.2.1" 139 | resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.2.1.tgz#bdafe8095383d8414d5dc2ecf4c9173b6db9412e" 140 | 141 | estree-walker@^0.3.0: 142 | version "0.3.1" 143 | resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.3.1.tgz#e6b1a51cf7292524e7237c312e5fe6660c1ce1aa" 144 | 145 | expand-brackets@^0.1.4: 146 | version "0.1.5" 147 | resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" 148 | dependencies: 149 | is-posix-bracket "^0.1.0" 150 | 151 | expand-range@^1.8.1: 152 | version "1.8.2" 153 | resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" 154 | dependencies: 155 | fill-range "^2.1.0" 156 | 157 | extglob@^0.3.1: 158 | version "0.3.2" 159 | resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" 160 | dependencies: 161 | is-extglob "^1.0.0" 162 | 163 | filename-regex@^2.0.0: 164 | version "2.0.0" 165 | resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775" 166 | 167 | fill-range@^2.1.0: 168 | version "2.2.3" 169 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" 170 | dependencies: 171 | is-number "^2.1.0" 172 | isobject "^2.0.0" 173 | randomatic "^1.1.3" 174 | repeat-element "^1.1.2" 175 | repeat-string "^1.5.2" 176 | 177 | for-in@^1.0.1: 178 | version "1.0.2" 179 | resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" 180 | 181 | for-own@^0.1.4: 182 | version "0.1.5" 183 | resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" 184 | dependencies: 185 | for-in "^1.0.1" 186 | 187 | glob-base@^0.3.0: 188 | version "0.3.0" 189 | resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" 190 | dependencies: 191 | glob-parent "^2.0.0" 192 | is-glob "^2.0.0" 193 | 194 | glob-parent@^2.0.0: 195 | version "2.0.0" 196 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" 197 | dependencies: 198 | is-glob "^2.0.0" 199 | 200 | has-ansi@^2.0.0: 201 | version "2.0.0" 202 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 203 | dependencies: 204 | ansi-regex "^2.0.0" 205 | 206 | is-buffer@^1.0.2: 207 | version "1.1.5" 208 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" 209 | 210 | is-dotfile@^1.0.0: 211 | version "1.0.2" 212 | resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" 213 | 214 | is-equal-shallow@^0.1.3: 215 | version "0.1.3" 216 | resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" 217 | dependencies: 218 | is-primitive "^2.0.0" 219 | 220 | is-extendable@^0.1.1: 221 | version "0.1.1" 222 | resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" 223 | 224 | is-extglob@^1.0.0: 225 | version "1.0.0" 226 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" 227 | 228 | is-glob@^2.0.0, is-glob@^2.0.1: 229 | version "2.0.1" 230 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" 231 | dependencies: 232 | is-extglob "^1.0.0" 233 | 234 | is-number@^2.0.2, is-number@^2.1.0: 235 | version "2.1.0" 236 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" 237 | dependencies: 238 | kind-of "^3.0.2" 239 | 240 | is-posix-bracket@^0.1.0: 241 | version "0.1.1" 242 | resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" 243 | 244 | is-primitive@^2.0.0: 245 | version "2.0.0" 246 | resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" 247 | 248 | isarray@1.0.0: 249 | version "1.0.0" 250 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 251 | 252 | isobject@^2.0.0: 253 | version "2.1.0" 254 | resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" 255 | dependencies: 256 | isarray "1.0.0" 257 | 258 | kind-of@^3.0.2: 259 | version "3.1.0" 260 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.1.0.tgz#475d698a5e49ff5e53d14e3e732429dc8bf4cf47" 261 | dependencies: 262 | is-buffer "^1.0.2" 263 | 264 | lazy-cache@^1.0.3: 265 | version "1.0.4" 266 | resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" 267 | 268 | longest@^1.0.1: 269 | version "1.0.1" 270 | resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" 271 | 272 | magic-string@^0.14.0: 273 | version "0.14.0" 274 | resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.14.0.tgz#57224aef1701caeed273b17a39a956e72b172462" 275 | dependencies: 276 | vlq "^0.2.1" 277 | 278 | magic-string@^0.19.0: 279 | version "0.19.0" 280 | resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.19.0.tgz#198948217254e3e0b93080e01146b7c73b2a06b2" 281 | dependencies: 282 | vlq "^0.2.1" 283 | 284 | micromatch@^2.3.11: 285 | version "2.3.11" 286 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" 287 | dependencies: 288 | arr-diff "^2.0.0" 289 | array-unique "^0.2.1" 290 | braces "^1.8.2" 291 | expand-brackets "^0.1.4" 292 | extglob "^0.3.1" 293 | filename-regex "^2.0.0" 294 | is-extglob "^1.0.0" 295 | is-glob "^2.0.1" 296 | kind-of "^3.0.2" 297 | normalize-path "^2.0.1" 298 | object.omit "^2.0.0" 299 | parse-glob "^3.0.4" 300 | regex-cache "^0.4.2" 301 | 302 | minimatch@^3.0.2: 303 | version "3.0.3" 304 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" 305 | dependencies: 306 | brace-expansion "^1.0.0" 307 | 308 | minimist@^1.2.0: 309 | version "1.2.0" 310 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" 311 | 312 | normalize-path@^2.0.1: 313 | version "2.0.1" 314 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.0.1.tgz#47886ac1662760d4261b7d979d241709d3ce3f7a" 315 | 316 | object.omit@^2.0.0: 317 | version "2.0.1" 318 | resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" 319 | dependencies: 320 | for-own "^0.1.4" 321 | is-extendable "^0.1.1" 322 | 323 | os-homedir@^1.0.1: 324 | version "1.0.2" 325 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" 326 | 327 | parse-glob@^3.0.4: 328 | version "3.0.4" 329 | resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" 330 | dependencies: 331 | glob-base "^0.3.0" 332 | is-dotfile "^1.0.0" 333 | is-extglob "^1.0.0" 334 | is-glob "^2.0.0" 335 | 336 | path-parse@^1.0.5: 337 | version "1.0.5" 338 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" 339 | 340 | preserve@^0.2.0: 341 | version "0.2.0" 342 | resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" 343 | 344 | randomatic@^1.1.3: 345 | version "1.1.6" 346 | resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" 347 | dependencies: 348 | is-number "^2.0.2" 349 | kind-of "^3.0.2" 350 | 351 | regex-cache@^0.4.2: 352 | version "0.4.3" 353 | resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" 354 | dependencies: 355 | is-equal-shallow "^0.1.3" 356 | is-primitive "^2.0.0" 357 | 358 | repeat-element@^1.1.2: 359 | version "1.1.2" 360 | resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" 361 | 362 | repeat-string@^1.5.2: 363 | version "1.6.1" 364 | resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" 365 | 366 | require-relative@0.8.7: 367 | version "0.8.7" 368 | resolved "https://registry.yarnpkg.com/require-relative/-/require-relative-0.8.7.tgz#7999539fc9e047a37928fa196f8e1563dabd36de" 369 | 370 | resolve@1.1.7: 371 | version "1.1.7" 372 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" 373 | 374 | resolve@^1.1.6, resolve@^1.1.7: 375 | version "1.3.2" 376 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.2.tgz#1f0442c9e0cbb8136e87b9305f932f46c7f28235" 377 | dependencies: 378 | path-parse "^1.0.5" 379 | 380 | right-align@^0.1.1: 381 | version "0.1.3" 382 | resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" 383 | dependencies: 384 | align-text "^0.1.1" 385 | 386 | rollup-plugin-buble@^0.15.0: 387 | version "0.15.0" 388 | resolved "https://registry.yarnpkg.com/rollup-plugin-buble/-/rollup-plugin-buble-0.15.0.tgz#83c3e89c7fd2266c7918f41ba3980313519c7fd0" 389 | dependencies: 390 | buble "^0.15.0" 391 | rollup-pluginutils "^1.5.0" 392 | 393 | rollup-plugin-commonjs@^7.0.0: 394 | version "7.1.0" 395 | resolved "https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-7.1.0.tgz#c3a772c2e4a5fa13507f5c578b66cc13b0cb8a79" 396 | dependencies: 397 | acorn "^4.0.1" 398 | estree-walker "^0.3.0" 399 | magic-string "^0.19.0" 400 | resolve "^1.1.7" 401 | rollup-pluginutils "^2.0.1" 402 | 403 | rollup-plugin-node-resolve@^2.0.0: 404 | version "2.0.0" 405 | resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-2.0.0.tgz#07e0ae94ac002a3ea36e8f33ca121d9f836b1309" 406 | dependencies: 407 | browser-resolve "^1.11.0" 408 | builtin-modules "^1.1.0" 409 | resolve "^1.1.6" 410 | 411 | rollup-pluginutils@^1.5.0: 412 | version "1.5.2" 413 | resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz#1e156e778f94b7255bfa1b3d0178be8f5c552408" 414 | dependencies: 415 | estree-walker "^0.2.1" 416 | minimatch "^3.0.2" 417 | 418 | rollup-pluginutils@^2.0.1: 419 | version "2.0.1" 420 | resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.0.1.tgz#7ec95b3573f6543a46a6461bd9a7c544525d0fc0" 421 | dependencies: 422 | estree-walker "^0.3.0" 423 | micromatch "^2.3.11" 424 | 425 | rollup-watch@^3.2.2: 426 | version "3.2.2" 427 | resolved "https://registry.yarnpkg.com/rollup-watch/-/rollup-watch-3.2.2.tgz#5e574232e9ef36da9177f46946d8080cb267354b" 428 | dependencies: 429 | require-relative "0.8.7" 430 | 431 | rollup@^0.41.4: 432 | version "0.41.6" 433 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.41.6.tgz#e0d05497877a398c104d816d2733a718a7a94e2a" 434 | dependencies: 435 | source-map-support "^0.4.0" 436 | 437 | source-map-support@^0.4.0: 438 | version "0.4.13" 439 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.13.tgz#9782e6f7deb424d5f173327a1879eb46453bdcd4" 440 | dependencies: 441 | source-map "^0.5.6" 442 | 443 | source-map@^0.5.6, source-map@~0.5.1: 444 | version "0.5.6" 445 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" 446 | 447 | strip-ansi@^3.0.0: 448 | version "3.0.1" 449 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 450 | dependencies: 451 | ansi-regex "^2.0.0" 452 | 453 | supports-color@^2.0.0: 454 | version "2.0.0" 455 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 456 | 457 | uglify-js@^2.6.2: 458 | version "2.8.13" 459 | resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.13.tgz#d0cdf02f3c661484fac601b7e723207b735a374c" 460 | dependencies: 461 | source-map "~0.5.1" 462 | uglify-to-browserify "~1.0.0" 463 | yargs "~3.10.0" 464 | 465 | uglify-to-browserify@~1.0.0: 466 | version "1.0.2" 467 | resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" 468 | 469 | vlq@^0.2.1: 470 | version "0.2.1" 471 | resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.1.tgz#14439d711891e682535467f8587c5630e4222a6c" 472 | 473 | window-size@0.1.0: 474 | version "0.1.0" 475 | resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" 476 | 477 | wordwrap@0.0.2: 478 | version "0.0.2" 479 | resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" 480 | 481 | yargs@~3.10.0: 482 | version "3.10.0" 483 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" 484 | dependencies: 485 | camelcase "^1.0.2" 486 | cliui "^2.1.0" 487 | decamelize "^1.0.0" 488 | window-size "0.1.0" 489 | --------------------------------------------------------------------------------