Skip to content

Instantly share code, notes, and snippets.

@targetkiller
Created January 21, 2016 09:43
Show Gist options
  • Save targetkiller/50f2776a61e53f3b57fb to your computer and use it in GitHub Desktop.
Save targetkiller/50f2776a61e53f3b57fb to your computer and use it in GitHub Desktop.
一个小球页面
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>拖拽小点点</title>
<style type="text/css">
body{
margin: 0;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
}
#canvas{
z-index: 1;
position: absolute;
}
#showHelp{
position: absolute;
top: 0;
left: 0;
width: 70px;
height: 30px;
line-height: 30px;
text-align: center;
background-color: rgba(10,10,10,0.5);
color: #fff;
font-size: 12px;
text-decoration: none;
z-index: 2;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<a href="javascript:;" id="showHelp">辅助线</a>
<script type="text/javascript">
// Tween.js
(function () {
if ('performance' in window === false) {
window.performance = {};
}
// IE 8
Date.now = (Date.now || function () {
return new Date().getTime();
});
if ('now' in window.performance === false) {
var offset = window.performance.timing && window.performance.timing.navigationStart ? window.performance.timing.navigationStart: Date.now();
window.performance.now = function () {
return Date.now() - offset;
};
}
})();
var TWEEN = TWEEN || (function () {
var _tweens = [];
return {
getAll: function () {
return _tweens;
},
removeAll: function () {
_tweens = [];
},
add: function (tween) {
_tweens.push(tween);
},
remove: function (tween) {
var i = _tweens.indexOf(tween);
if (i !== -1) {
_tweens.splice(i, 1);
}
},
update: function (time) {
if (_tweens.length === 0) {
return false;
}
var i = 0;
time = time !== undefined ? time : window.performance.now();
while (i < _tweens.length) {
if (_tweens[i].update(time)) {
i++;
} else {
_tweens.splice(i, 1);
}
}
return true;
}
};
})();
TWEEN.Tween = function (object) {
var _object = object;
var _valuesStart = {};
var _valuesEnd = {};
var _valuesStartRepeat = {};
var _duration = 1000;
var _repeat = 0;
var _yoyo = false;
var _isPlaying = false;
var _reversed = false;
var _delayTime = 0;
var _startTime = null;
var _easingFunction = TWEEN.Easing.Linear.None;
var _interpolationFunction = TWEEN.Interpolation.Linear;
var _chainedTweens = [];
var _onStartCallback = null;
var _onStartCallbackFired = false;
var _onUpdateCallback = null;
var _onCompleteCallback = null;
var _onStopCallback = null;
// Set all starting values present on the target object
for (var field in object) {
_valuesStart[field] = parseFloat(object[field], 10);
}
this.to = function (properties, duration) {
if (duration !== undefined) {
_duration = duration;
}
_valuesEnd = properties;
return this;
};
this.start = function (time) {
TWEEN.add(this);
_isPlaying = true;
_onStartCallbackFired = false;
_startTime = time !== undefined ? time : window.performance.now();
_startTime += _delayTime;
for (var property in _valuesEnd) {
// Check if an Array was provided as property value
if (_valuesEnd[property] instanceof Array) {
if (_valuesEnd[property].length === 0) {
continue;
}
// Create a local copy of the Array with the start value at the front
_valuesEnd[property] = [_object[property]].concat(_valuesEnd[property]);
}
// If `to()` specifies a property that doesn't exist in the source object,
// we should not set that property in the object
if (_valuesStart[property] === undefined) {
continue;
}
_valuesStart[property] = _object[property];
if ((_valuesStart[property] instanceof Array) === false) {
_valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings
}
_valuesStartRepeat[property] = _valuesStart[property] || 0;
}
return this;
};
this.stop = function () {
if (!_isPlaying) {
return this;
}
TWEEN.remove(this);
_isPlaying = false;
if (_onStopCallback !== null) {
_onStopCallback.call(_object);
}
this.stopChainedTweens();
return this;
};
this.stopChainedTweens = function () {
for (var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++) {
_chainedTweens[i].stop();
}
};
this.delay = function (amount) {
_delayTime = amount;
return this;
};
this.repeat = function (times) {
_repeat = times;
return this;
};
this.yoyo = function (yoyo) {
_yoyo = yoyo;
return this;
};
this.easing = function (easing) {
_easingFunction = easing;
return this;
};
this.interpolation = function (interpolation) {
_interpolationFunction = interpolation;
return this;
};
this.chain = function () {
_chainedTweens = arguments;
return this;
};
this.onStart = function (callback) {
_onStartCallback = callback;
return this;
};
this.onUpdate = function (callback) {
_onUpdateCallback = callback;
return this;
};
this.onComplete = function (callback) {
_onCompleteCallback = callback;
return this;
};
this.onStop = function (callback) {
_onStopCallback = callback;
return this;
};
this.update = function (time) {
var property;
var elapsed;
var value;
if (time < _startTime) {
return true;
}
if (_onStartCallbackFired === false) {
if (_onStartCallback !== null) {
_onStartCallback.call(_object);
}
_onStartCallbackFired = true;
}
elapsed = (time - _startTime) / _duration;
elapsed = elapsed > 1 ? 1 : elapsed;
value = _easingFunction(elapsed);
for (property in _valuesEnd) {
// Don't update properties that do not exist in the source object
if (_valuesStart[property] === undefined) {
continue;
}
var start = _valuesStart[property] || 0;
var end = _valuesEnd[property];
if (end instanceof Array) {
_object[property] = _interpolationFunction(end, value);
} else {
// Parses relative end values with start as base (e.g.: +10, -3)
if (typeof (end) === 'string') {
if (end.startsWith('+') || end.startsWith('-')) {
end = start + parseFloat(end, 10);
} else {
end = parseFloat(end, 10);
}
}
// Protect against non numeric properties.
if (typeof (end) === 'number') {
_object[property] = start + (end - start) * value;
}
}
}
if (_onUpdateCallback !== null) {
_onUpdateCallback.call(_object, value);
}
if (elapsed === 1) {
if (_repeat > 0) {
if (isFinite(_repeat)) {
_repeat--;
}
// Reassign starting values, restart by making startTime = now
for (property in _valuesStartRepeat) {
if (typeof (_valuesEnd[property]) === 'string') {
_valuesStartRepeat[property] = _valuesStartRepeat[property] + parseFloat(_valuesEnd[property], 10);
}
if (_yoyo) {
var tmp = _valuesStartRepeat[property];
_valuesStartRepeat[property] = _valuesEnd[property];
_valuesEnd[property] = tmp;
}
_valuesStart[property] = _valuesStartRepeat[property];
}
if (_yoyo) {
_reversed = !_reversed;
}
_startTime = time + _delayTime;
return true;
} else {
if (_onCompleteCallback !== null) {
_onCompleteCallback.call(_object);
}
for (var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++) {
// Make the chained tweens start exactly at the time they should,
// even if the `update()` method was called way past the duration of the tween
_chainedTweens[i].start(_startTime + _duration);
}
return false;
}
}
return true;
};
};
TWEEN.Easing = {
Linear: {
None: function (k) {
return k;
}
},
Quadratic: {
In: function (k) {
return k * k;
},
Out: function (k) {
return k * (2 - k);
},
InOut: function (k) {
if ((k *= 2) < 1) {
return 0.5 * k * k;
}
return - 0.5 * (--k * (k - 2) - 1);
}
},
Cubic: {
In: function (k) {
return k * k * k;
},
Out: function (k) {
return --k * k * k + 1;
},
InOut: function (k) {
if ((k *= 2) < 1) {
return 0.5 * k * k * k;
}
return 0.5 * ((k -= 2) * k * k + 2);
}
},
Quartic: {
In: function (k) {
return k * k * k * k;
},
Out: function (k) {
return 1 - (--k * k * k * k);
},
InOut: function (k) {
if ((k *= 2) < 1) {
return 0.5 * k * k * k * k;
}
return - 0.5 * ((k -= 2) * k * k * k - 2);
}
},
Quintic: {
In: function (k) {
return k * k * k * k * k;
},
Out: function (k) {
return --k * k * k * k * k + 1;
},
InOut: function (k) {
if ((k *= 2) < 1) {
return 0.5 * k * k * k * k * k;
}
return 0.5 * ((k -= 2) * k * k * k * k + 2);
}
},
Sinusoidal: {
In: function (k) {
return 1 - Math.cos(k * Math.PI / 2);
},
Out: function (k) {
return Math.sin(k * Math.PI / 2);
},
InOut: function (k) {
return 0.5 * (1 - Math.cos(Math.PI * k));
}
},
Exponential: {
In: function (k) {
return k === 0 ? 0 : Math.pow(1024, k - 1);
},
Out: function (k) {
return k === 1 ? 1 : 1 - Math.pow(2, - 10 * k);
},
InOut: function (k) {
if (k === 0) {
return 0;
}
if (k === 1) {
return 1;
}
if ((k *= 2) < 1) {
return 0.5 * Math.pow(1024, k - 1);
}
return 0.5 * (- Math.pow(2, - 10 * (k - 1)) + 2);
}
},
Circular: {
In: function (k) {
return 1 - Math.sqrt(1 - k * k);
},
Out: function (k) {
return Math.sqrt(1 - (--k * k));
},
InOut: function (k) {
if ((k *= 2) < 1) {
return - 0.5 * (Math.sqrt(1 - k * k) - 1);
}
return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1);
}
},
Elastic: {
In: function (k) {
var s;
var a = 0.1;
var p = 0.4;
if (k === 0) {
return 0;
}
if (k === 1) {
return 1;
}
if (!a || a < 1) {
a = 1;
s = p / 4;
} else {
s = p * Math.asin(1 / a) / (2 * Math.PI);
}
return - (a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p));
},
Out: function (k) {
var s;
var a = 0.1;
var p = 0.4;
if (k === 0) {
return 0;
}
if (k === 1) {
return 1;
}
if (!a || a < 1) {
a = 1;
s = p / 4;
} else {
s = p * Math.asin(1 / a) / (2 * Math.PI);
}
return (a * Math.pow(2, - 10 * k) * Math.sin((k - s) * (2 * Math.PI) / p) + 1);
},
InOut: function (k) {
var s;
var a = 0.1;
var p = 0.4;
if (k === 0) {
return 0;
}
if (k === 1) {
return 1;
}
if (!a || a < 1) {
a = 1;
s = p / 4;
} else {
s = p * Math.asin(1 / a) / (2 * Math.PI);
}
if ((k *= 2) < 1) {
return - 0.5 * (a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p));
}
return a * Math.pow(2, -10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1;
}
},
Back: {
In: function (k) {
var s = 1.70158;
return k * k * ((s + 1) * k - s);
},
Out: function (k) {
var s = 1.70158;
return --k * k * ((s + 1) * k + s) + 1;
},
InOut: function (k) {
var s = 1.70158 * 1.525;
if ((k *= 2) < 1) {
return 0.5 * (k * k * ((s + 1) * k - s));
}
return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
}
},
Bounce: {
In: function (k) {
return 1 - TWEEN.Easing.Bounce.Out(1 - k);
},
Out: function (k) {
if (k < (1 / 2.75)) {
return 7.5625 * k * k;
} else if (k < (2 / 2.75)) {
return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75;
} else if (k < (2.5 / 2.75)) {
return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375;
} else {
return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375;
}
},
InOut: function (k) {
if (k < 0.5) {
return TWEEN.Easing.Bounce.In(k * 2) * 0.5;
}
return TWEEN.Easing.Bounce.Out(k * 2 - 1) * 0.5 + 0.5;
}
}
};
TWEEN.Interpolation = {
Linear: function (v, k) {
var m = v.length - 1;
var f = m * k;
var i = Math.floor(f);
var fn = TWEEN.Interpolation.Utils.Linear;
if (k < 0) {
return fn(v[0], v[1], f);
}
if (k > 1) {
return fn(v[m], v[m - 1], m - f);
}
return fn(v[i], v[i + 1 > m ? m : i + 1], f - i);
},
Bezier: function (v, k) {
var b = 0;
var n = v.length - 1;
var pw = Math.pow;
var bn = TWEEN.Interpolation.Utils.Bernstein;
for (var i = 0; i <= n; i++) {
b += pw(1 - k, n - i) * pw(k, i) * v[i] * bn(n, i);
}
return b;
},
CatmullRom: function (v, k) {
var m = v.length - 1;
var f = m * k;
var i = Math.floor(f);
var fn = TWEEN.Interpolation.Utils.CatmullRom;
if (v[0] === v[m]) {
if (k < 0) {
i = Math.floor(f = m * (1 + k));
}
return fn(v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m], f - i);
} else {
if (k < 0) {
return v[0] - (fn(v[0], v[0], v[1], v[1], -f) - v[0]);
}
if (k > 1) {
return v[m] - (fn(v[m], v[m], v[m - 1], v[m - 1], f - m) - v[m]);
}
return fn(v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2], f - i);
}
},
Utils: {
Linear: function (p0, p1, t) {
return (p1 - p0) * t + p0;
},
Bernstein: function (n, i) {
var fc = TWEEN.Interpolation.Utils.Factorial;
return fc(n) / fc(i) / fc(n - i);
},
Factorial: (function () {
var a = [1];
return function (n) {
var s = 1;
if (a[n]) {
return a[n];
}
for (var i = n; i > 1; i--) {
s *= i;
}
a[n] = s;
return s;
};
})(),
CatmullRom: function (p0, p1, p2, p3, t) {
var v0 = (p2 - p0) * 0.5;
var v1 = (p3 - p1) * 0.5;
var t2 = t * t;
var t3 = t * t2;
return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (- 3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1;
}
}
};
// UMD (Universal Module Definition)
(function (root) {
if (typeof define === 'function' && define.amd) {
// AMD
define([], function () {
return TWEEN;
});
} else if (typeof module !== 'undefined' && typeof exports === 'object') {
// Node.js
module.exports = TWEEN;
} else if (root !== undefined) {
// Global variable
root.TWEEN = TWEEN;
}
})(this);
// ===配置===
var sw = document.documentElement.clientWidth;
var sh = document.documentElement.clientHeight;
var dpr = window.devicePixelRatio;//适配高清屏
var oX = sw/2;
var oY = sh/2;
var oRadius = 30;//中心圆半径
var oColor = '#ff0000';//中心圆颜色
var base_angle = Math.PI;//基准弧度
var distance_angle = Math.PI / 800;//每px距离转化的弧度
var distance_angle_limit = Math.PI * 3/4;//最大基准弧度
var helpColor = '#aaa';
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var showHelp = document.getElementById('showHelp');
var is_showHelp = false;
var is_canMove = true;//是否能拖动
var move_rest = 20;//拖动的边缘容差
var bounce_duration_time = 600;
var bounce_animate_type = TWEEN.Easing.Elastic.Out;
var last_x,last_y,last_angle,last_distance,coords,tween;
// ===函数===
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
// 画圆
function makeCircle(x,y,r,a,c,color) {
ctx.beginPath();
ctx.arc(x*dpr,y*dpr,r*dpr,a,c);
ctx.fillStyle = color;
ctx.closePath();
ctx.fill();
};
// 每次重绘函数
function draw(){
// 重设画布
ctx.clearRect(0,0,sw*dpr,sh*dpr);
// 画圆点
makeCircle(oX,oY,oRadius,0,2*Math.PI,oColor);
}
// 辅助线
function drawHelpLine(a1_x,a1_y,a2_x,a2_y,b1_x,b1_y,b2_x,b2_y){
ctx.strokeStyle = helpColor;
ctx.lineWidth = 0.5;
ctx.beginPath();
ctx.moveTo(a1_x*dpr,a1_y*dpr);
ctx.lineTo(b1_x*dpr,b1_y*dpr);
ctx.moveTo(a2_x*dpr,a2_y*dpr);
ctx.lineTo(b2_x*dpr,b2_y*dpr);
ctx.stroke();
ctx.closePath();
}
// 画贝塞尔曲线
function drawBezier(x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6){
ctx.filleStyle = oColor;
ctx.beginPath();
ctx.moveTo(x1*dpr,y1*dpr);
ctx.quadraticCurveTo(x3*dpr,y3*dpr,x2*dpr,y2*dpr);
ctx.lineTo(x5*dpr,y5*dpr);
ctx.quadraticCurveTo(x6*dpr,y6*dpr,x4*dpr,y4*dpr);
ctx.lineTo(x1*dpr,y1*dpr);
ctx.fill();
ctx.closePath();
}
// 放手回弹圆形
function bounceCircle(){
coords = { x: last_x, y: last_y };
tween = new TWEEN.Tween(coords)
.to({ x: oX, y: oY }, bounce_duration_time)
.easing(bounce_animate_type)
.onUpdate(bounceUpdate)
.start();
bounceAnimate();
}
function bounceAnimate(time) {
requestAnimationFrame(bounceAnimate);
TWEEN.update(time);
}
function bounceUpdate(){
// 弹行速度
x = coords.x;
y = coords.y;
var distance = Math.sqrt(Math.pow(x-oX,2)+Math.pow(y-oY,2));
var Bangle = base_angle - distance*distance_angle;
if(Bangle < distance_angle_limit){Bangle = distance_angle_limit;}
// 计算拖拽水平夹角
var angle = last_angle;
var dis_x1 = Math.cos(Math.abs(Bangle/2-angle))*oRadius;
var dis_y1 = Math.sin(Bangle/2-angle)*oRadius;
var dis_x2 = Math.cos(Math.abs(Math.PI-Bangle/2-angle))*oRadius;
var dis_y2 = Math.sin(Math.PI-Bangle/2-angle)*oRadius;
// 求四个交点
var a1_x,a1_y,a2_x,a2_y,b1_x,b1_y,b2_x,b2_y,c1_x,c1_y,c2_x,c2_y;
// 求四个交点
var a1_x,a1_y,a2_x,a2_y,b1_x,b1_y,b2_x,b2_y,c1_x,c1_y,c2_x,c2_y;
// 第一象限
if(x>oX&&y<oY){
// 圆A的两个点
a1_x = oX-dis_x2;
a1_y = oY-dis_y2;
a2_x = oX+dis_x1;
a2_y = oY+dis_y1;
// 圆B的两个点
b1_x = x-dis_x1;
b1_y = y-dis_y1;
b2_x = x+dis_x2;
b2_y = y+dis_y2;
}
// 第二象限
else if(x<oX&&y<oY){
// 圆A的两个点
a1_x = oX-dis_x1;
a1_y = oY+dis_y1;
a2_x = oX+dis_x2;
a2_y = oY-dis_y2;
// 圆B的两个点
b1_x = x-dis_x2;
b1_y = y+dis_y2;
b2_x = x+dis_x1;
b2_y = y-dis_y1;
}
// 第三象限
else if(x<oX&&y>oY){
// 圆A的两个点
a1_x = oX+dis_x2;
a1_y = oY+dis_y2;
a2_x = oX-dis_x1;
a2_y = oY-dis_y1;
// 圆B的两个点
b1_x = x+dis_x1;
b1_y = y+dis_y1;
b2_x = x-dis_x2;
b2_y = y-dis_y2;
}
// 第四象限
else if(x>oX&&y>oY){
// 圆A的两个点
a1_x = oX+dis_x1;
a1_y = oY-dis_y1;
a2_x = oX-dis_x2;
a2_y = oY+dis_y2;
// 圆B的两个点
b1_x = x+dis_x2;
b1_y = y-dis_y2;
b2_x = x-dis_x1;
b2_y = y+dis_y1;
}
// 贝塞尔曲线控制点
c1_x = (b2_x+a1_x)/2;
c1_y = (b2_y+a1_y)/2;
c2_x = (b1_x+a2_x)/2;
c2_y = (b1_y+a2_y)/2;
// 贝塞尔曲线控制点
c1_x = (b2_x+a1_x)/2;
c1_y = (b2_y+a1_y)/2;
c2_x = (b1_x+a2_x)/2;
c2_y = (b1_y+a2_y)/2;
draw();
makeCircle(x,y,oRadius,0,2*Math.PI,oColor);
drawBezier(a1_x,a1_y,b1_x,b1_y,c1_x,c1_y,a2_x,a2_y,b2_x,b2_y,c2_x,c2_y);
}
// ===绑定===
// 绑定拖拽
showHelp.addEventListener('click',function(e){
e.preventDefault();
if(is_showHelp){
is_showHelp = false;
}
else{
is_showHelp = true;
}
});
canvas.addEventListener('touchstart',function(e){
e.preventDefault();
var x = e.touches[0].clientX;
var y = e.touches[0].clientY;
// 计算是否在圆内
var distance = Math.sqrt(Math.pow(x-oX,2)+Math.pow(y-oY,2));
// 圆外无法拖动
is_canMove = (distance-move_rest) > oRadius ? false : true;
});
canvas.addEventListener('touchmove',function(e){
e.preventDefault();
if(!is_canMove){
return;
}
var x = e.touches[0].clientX;
var y = e.touches[0].clientY;
// 计算两点间距离
var distance = Math.sqrt(Math.pow(x-oX,2)+Math.pow(y-oY,2));
var Bangle = base_angle - distance*distance_angle;
if(Bangle < distance_angle_limit){Bangle = distance_angle_limit;}
// 计算拖拽水平夹角
var angle = Math.atan(Math.abs(y - oY)/Math.abs(x - oX));
var dis_x1 = Math.cos(Math.abs(Bangle/2-angle))*oRadius;
var dis_y1 = Math.sin(Bangle/2-angle)*oRadius;
var dis_x2 = Math.cos(Math.abs(Math.PI-Bangle/2-angle))*oRadius;
var dis_y2 = Math.sin(Math.PI-Bangle/2-angle)*oRadius;
// 记录最新点
last_x = x;
last_y = y;
last_angle = angle;
last_distance = distance;
// 求四个交点
var a1_x,a1_y,a2_x,a2_y,b1_x,b1_y,b2_x,b2_y,c1_x,c1_y,c2_x,c2_y;
// 第一象限
if(x>oX&&y<oY){
// 圆A的两个点
a1_x = oX-dis_x2;
a1_y = oY-dis_y2;
a2_x = oX+dis_x1;
a2_y = oY+dis_y1;
// 圆B的两个点
b1_x = x-dis_x1;
b1_y = y-dis_y1;
b2_x = x+dis_x2;
b2_y = y+dis_y2;
}
// 第二象限
else if(x<oX&&y<oY){
// 圆A的两个点
a1_x = oX-dis_x1;
a1_y = oY+dis_y1;
a2_x = oX+dis_x2;
a2_y = oY-dis_y2;
// 圆B的两个点
b1_x = x-dis_x2;
b1_y = y+dis_y2;
b2_x = x+dis_x1;
b2_y = y-dis_y1;
}
// 第三象限
else if(x<oX&&y>oY){
// 圆A的两个点
a1_x = oX+dis_x2;
a1_y = oY+dis_y2;
a2_x = oX-dis_x1;
a2_y = oY-dis_y1;
// 圆B的两个点
b1_x = x+dis_x1;
b1_y = y+dis_y1;
b2_x = x-dis_x2;
b2_y = y-dis_y2;
}
// 第四象限
else if(x>oX&&y>oY){
// 圆A的两个点
a1_x = oX+dis_x1;
a1_y = oY-dis_y1;
a2_x = oX-dis_x2;
a2_y = oY+dis_y2;
// 圆B的两个点
b1_x = x+dis_x2;
b1_y = y-dis_y2;
b2_x = x-dis_x1;
b2_y = y+dis_y1;
}
// 贝塞尔曲线控制点
c1_x = (b2_x+a1_x)/2;
c1_y = (b2_y+a1_y)/2;
c2_x = (b1_x+a2_x)/2;
c2_y = (b1_y+a2_y)/2;
console.log('两点间距离:'+distance);
console.log('与x轴夹角:'+angle*180/Math.PI);
console.log('圆A点p1:('+a1_x+','+a1_y+')');
console.log('圆A点p2:('+a2_x+','+a2_y+')');
console.log('圆B点p1:('+b1_x+','+b1_y+')');
console.log('圆B点p2:('+b2_x+','+b2_y+')');
draw();
makeCircle(x,y,oRadius,0,2*Math.PI,oColor);
drawBezier(a1_x,a1_y,b1_x,b1_y,c1_x,c1_y,a2_x,a2_y,b2_x,b2_y,c2_x,c2_y);
if(is_showHelp){
drawHelpLine(a1_x,a1_y,a2_x,a2_y,b1_x,b1_y,b2_x,b2_y);
}
});
canvas.addEventListener('touchend',function(e){
e.preventDefault();
if(!is_canMove){
return;
}
bounce_distance = last_distance;
bounceCircle();
});
// ===调用===
// 基本画圆
canvas.setAttribute('style', ';height:' + sh + 'px;width:' + sw + 'px;');
ctx.canvas.width = sw*dpr;
ctx.canvas.height = sh*dpr;
draw();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment