手机 html5 hammer drag widget,HTML5 Rx.js+Hammer.js城市规划拿破仑定理交互动画图解

JavaScript

语言:

JaveScriptBabelCoffeeScript

确定

'use strict';

// Dom Nodes

var triangle = document.querySelector('#js-triangle');

var centroidTriangle = document.querySelector('#js-centroid-triangle');

var handle1 = document.querySelector('#js-handle-1');

var handle2 = document.querySelector('#js-handle-2');

var handle3 = document.querySelector('#js-handle-3');

var showDebug = false;

if (showDebug) {

var _debugCC = document.querySelector('#js-circum-center');

var _debug = document.querySelector('#js-debug');

}

var animationFrame$ = Rx.Observable.interval(0, Rx.Scheduler.animationFrame);

// Drag Handler

var drag = function drag(domNode, pan$) {

return pan$.filter(function(e) {

return e.type === 'panstart';

}).switchMap(function(pd) {

var start = {

x: +domNode.getAttribute('cx'),

y: +domNode.getAttribute('cy')

};

var w = document.body.clientWidth;

var h = document.body.clientHeight;

domNode.setAttribute('r', 15);

var svgW = w > h ? 400 * w / h : 400;

var svgH = w > h ? 400 : 400 * h / w;

var move$ = pan$.filter(function(e) {

return e.type === 'panmove';

}).map(function(pm) {

return {

x: start.x + linInterp(pm.deltaX, 0, w, 0, svgW),

y: start.y + linInterp(pm.deltaY, 0, h, 0, svgH)

};

}).takeUntil(pan$.filter(function(e) {

return e.type === 'panend';

}));

move$.subscribe(null, null, function() {

return domNode.setAttribute('r', 10);

});

return move$;

});

};

var handleDrag = function handleDrag(domNode) {

var hammerPan = new Hammer(domNode, {

direction: Hammer.DIRECTION_ALL

});

hammerPan.get('pan').set({

direction: Hammer.DIRECTION_ALL

});

var pan$ = Rx.Observable.fromEventPattern(function(h) {

return hammerPan.on('panstart panup pandown panmove panend', h);

});

var drag$ = drag(domNode, pan$);

return animationFrame$.withLatestFrom(drag$, function(_, e) {

return e;

}).scan(RxCSS.lerp(0.1)).map(function(p) {

return [p.x, p.y];

});

};

var points$ = Rx.Observable.combineLatest(handleDrag(handle1).startWith([100, 200]), handleDrag(handle2).startWith([150, 100]), handleDrag(handle3).startWith([300, 200]));

var triangle$ = points$.distinctUntilChanged(function(p, n) {

return Math.abs(addAll(p) - addAll(n)) < 0.1;

}).map(function(points) {

return {

points: points,

circumCenter: circumCenter.apply(undefined, points)

};

});

// State: Main Triangle, Equilateral triangles and Centroid Triangle

var state$ = triangle$.map(function(_ref) {

var _ref$points = _ref.points;

var u = _ref$points[0];

var v = _ref$points[1];

var w = _ref$points[2];

var circumCenter = _ref.circumCenter;

return {

triangle: [u, v, w],

a: eqTriangle(u, v, circumCenter, w),

b: eqTriangle(v, w, circumCenter, u),

c: eqTriangle(w, u, circumCenter, v),

circumCenter: circumCenter

};

}).map(function(_ref2) {

var triangle = _ref2.triangle;

var a = _ref2.a;

var b = _ref2.b;

var c = _ref2.c;

var circumCenter = _ref2.circumCenter;

return {

triangle: triangle,

a: a,

b: b,

c: c,

centroidTriangle: [centroid(a), centroid(b), centroid(c)],

cc: circumCenter

};

});

// Convert state to SVG geometry and render

var svgGeometry$ = state$.map(function(_ref3) {

var triangle = _ref3.triangle;

var a = _ref3.a;

var b = _ref3.b;

var c = _ref3.c;

var centroidTriangle = _ref3.centroidTriangle;

var cc = _ref3.cc;

return {

triangleD: ['M', triangle.join('L'), 'L', a.join('L'), 'L', b.join('L'), 'L', c.join('L')],

cc: cc,

debugD: ['M'].concat(triangle[0], ['L'], cc, ['L'], triangle[1], ['M'], cc, ['L'], triangle[2], ['M'], a[1], ['L'], cc, ['L'], b[1], ['M'], cc, ['L'], c[1]).join(' '),

centroidTriangleD: ['M', centroidTriangle.join('L'), 'Z'],

handles: [triangle[0], triangle[1], triangle[2]]

};

});

svgGeometry$.subscribe(function(_ref4) {

var triangleD = _ref4.triangleD;

var centroidTriangleD = _ref4.centroidTriangleD;

var _ref4$handles = _ref4.handles;

var h1 = _ref4$handles[0];

var h2 = _ref4$handles[1];

var h3 = _ref4$handles[2];

var cc = _ref4.cc;

var debugD = _ref4.debugD;

triangle.setAttribute('d', triangleD.join(''));

centroidTriangle.setAttribute('d', centroidTriangleD.join(''));

handle1.setAttribute('cx', h1[0]);

handle1.setAttribute('cy', h1[1]);

handle2.setAttribute('cx', h2[0]);

handle2.setAttribute('cy', h2[1]);

handle3.setAttribute('cx', h3[0]);

handle3.setAttribute('cy', h3[1]);

if (showDebug) {

debugCC.setAttribute('cx', cc[0]);

debugCC.setAttribute('cy', cc[1]);

debug.setAttribute('d', debugD);

}

});

/**

* Geometry

*/

function eqTriangle(u, v, cc) {

return [u, apex(u, v, cc), v];

}

function apex(_ref5, _ref6, _ref7) {

var ux = _ref5[0];

var uy = _ref5[1];

var vx = _ref6[0];

var vy = _ref6[1];

var ccx = _ref7[0];

var ccy = _ref7[1];

var mpx = (vx + ux) / 2;

var mpy = (vy + uy) / 2;

var dir = sign([ccx, ccy], [ux, uy], [vx, vy]) > 0 ? 1 : -1;

var ccMp = [mpx - ccx, mpy - ccy].map(function(x) {

return x * dir;

});

var h = triangleHeight([ux, uy], [vx, vy]);

var m = magnitude(ccMp);

var _ccMp$map = ccMp.map(function(s) {

return s * (h + dir * m) / m;

});

var nx = _ccMp$map[0];

var ny = _ccMp$map[1];

return [nx + ccx, ny + ccy];

}

function circumCenter(_ref8, _ref9, _ref10) {

var ax = _ref8[0];

var ay = _ref8[1];

var bx = _ref9[0];

var by = _ref9[1];

var cx = _ref10[0];

var cy = _ref10[1];

var d = (ax - cx) * (by - cy) - (bx - cx) * (ay - cy);

var x = (((ax - cx) * (ax + cx) + (ay - cy) * (ay + cy)) / 2 * (by - cy) - ((bx - cx) * (bx + cx) + (by - cy) * (by + cy)) / 2 * (ay - cy)) / d;

var y = (((bx - cx) * (bx + cx) + (by - cy) * (by + cy)) / 2 * (ax - cx) - ((ax - cx) * (ax + cx) + (ay - cy) * (ay + cy)) / 2 * (bx - cx)) / d;

return [Math.round(x * 100) / 100, Math.round(y * 100) / 100];

}

function centroid(_ref11) {

var _ref11$ = _ref11[0];

var ux = _ref11$[0];

var uy = _ref11$[1];

var _ref11$2 = _ref11[1];

var vx = _ref11$2[0];

var vy = _ref11$2[1];

var _ref11$3 = _ref11[2];

var wx = _ref11$3[0];

var wy = _ref11$3[1];

return [avg(ux, vx, wx), avg(uy, vy, wy)];

}

/**

* Utils

*/

function magnitude(_ref12) {

var x = _ref12[0];

var y = _ref12[1];

return Math.pow(Math.pow(x, 2) + Math.pow(y, 2), 0.5);

}

function triangleHeight(_ref13, _ref14) {

var ux = _ref13[0];

var uy = _ref13[1];

var vx = _ref14[0];

var vy = _ref14[1];

return Math.pow(3, 0.5) * dist([ux, uy], [vx, vy]) / 2;

}

function dist(_ref15, _ref16) {

var ux = _ref15[0];

var uy = _ref15[1];

var vx = _ref16[0];

var vy = _ref16[1];

return Math.sqrt((ux - vx) * (ux - vx) + (uy - vy) * (uy - vy));

}

function avg(t0, t1, t2) {

return (t0 + t1 + t2) / 3;

}

function linInterp(x, x1, x2, y1, y2) {

return (x - x1) * ((y2 - y1) / (x2 - x1)) + y1;

}

function add(a, b) {

return a + b;

}

function addAll(list) {

return list.map(function(x) {

return x.reduce(add, 0);

}).reduce(add, 0);

}

function sign(_ref17, _ref18, _ref19) {

var p1x = _ref17[0];

var p1y = _ref17[1];

var p2x = _ref18[0];

var p2y = _ref18[1];

var p3x = _ref19[0];

var p3y = _ref19[1];

return (p1x - p3x) * (p2y - p3y) - (p2x - p3x) * (p1y - p3y);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值