Created
March 4, 2017 03:58
-
-
Save qnnnnez/97f1be2feadcf35fd5a2e9c174977a15 to your computer and use it in GitHub Desktop.
模仿 UWP 磁贴的 3D 效果风格
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<meta charset="utf-8" /> | |
<title>Fake UWP</title> | |
<style> | |
#viewport | |
{ | |
width: 200px; | |
height: 200px; | |
} | |
#camera | |
{ | |
perspective: 100px; | |
} | |
#target | |
{ | |
font-size: 100px; | |
background: grey; | |
} | |
</style> | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> | |
</head> | |
<body> | |
<script> | |
function distance(x1, y1, x2, y2) { // 两点之间的距离 | |
return Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); | |
} | |
$(document).ready(function (){ | |
var target = $("#target"); | |
var preasure = 0.0; | |
var mouseInside = false; | |
var x; | |
var y; | |
var mouseDown = false; | |
function draw(x, y, preasure){ | |
var X = target.width(); | |
var Y = target.height(); | |
console.log({X: X, Y: Y, x: x, y: y}); | |
// 旋转轴 | |
var axisX = Y/2 - y; | |
var axisY = -(X/2 - x); | |
var armLength = distance(x, y, X/2, Y/2); // 鼠标位置到中心的距离,=动力臂的长度 | |
// 将旋转轴向量标准化 | |
axisX /= armLength; | |
axisY /= armLength; | |
console.log({axisX: axisX, axisY: axisY}); | |
var k = axisY / axisX; // 鼠标到中心点连线的斜率 | |
// 接下来计算中心-鼠标延长线与边框的相交点 | |
if (Math.abs(k) < Y/X) { // 相交点位于左右边框 | |
var py = Y; | |
var px = (X/2) + k * py/2; | |
} else { // 相交点位于上下边框或顶点 | |
var px = X; | |
var py = (Y/2) + k / (px/2); | |
} | |
console.log({px: px, py: py}); | |
var armExtend = distance(px, py, 0, 0); // 阻力臂的长度 | |
var armFactor = armLength / armExtend; // ∈[0, 1] | |
console.log({armFactor: armFactor, preasure: preasure}); | |
// 旋转角,鼠标离中心越远,旋转角越大 | |
var angle = 15 * armFactor * preasure; // deg | |
// 按下去的距离,离中心越近,距离越大 | |
var zOffset = -20 * (1 - armFactor) * preasure; // px | |
var cssValue = "perspective(300px) translateZ(" + zOffset.toString() + "px) rotate3d(" + axisX.toString() + ", " + axisY.toString() + ", 0, " + angle.toString() + "deg)"; | |
target.css("transform", cssValue); | |
} | |
target.mousemove(function (e) { | |
x = e.offsetX; | |
y = e.offsetY; | |
draw(x, y, preasure); | |
}); | |
target.mouseenter(function() { | |
preasure = 0.5; | |
mouseInside = true; | |
}); | |
target.mouseleave(function () { | |
mouseInside = false; | |
}); | |
target.mousedown(function () { | |
mouseDown = true; | |
}); | |
target.mouseup(function () { | |
mouseDown = false; | |
}) | |
var updatePreasure = window.setInterval(function() { | |
if (mouseInside) { | |
preasure += 0.1; | |
} else { | |
preasure -= 0.1; | |
} | |
if (preasure > 1.0) { | |
preasure -= 0.2; | |
} else if (preasure < 0) { | |
preasure = 0; | |
} | |
if (mouseDown) { | |
preasure = 2; | |
} | |
if (preasure != 0) { | |
draw(x, y, preasure); | |
} | |
}, 16); // 60 FPS =_= | |
}); | |
</script> | |
<div id="viewport"> | |
<div id="camera"> | |
<div id="world"> | |
<div id="target"> | |
<span id="text">一些文字</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment