Skip to content

Instantly share code, notes, and snippets.

@qnnnnez
Created March 4, 2017 03:58
Show Gist options
  • Save qnnnnez/97f1be2feadcf35fd5a2e9c174977a15 to your computer and use it in GitHub Desktop.
Save qnnnnez/97f1be2feadcf35fd5a2e9c174977a15 to your computer and use it in GitHub Desktop.
模仿 UWP 磁贴的 3D 效果风格
<!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