Skip to content

Instantly share code, notes, and snippets.

@abernier
Last active September 28, 2015 23:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abernier/1512474 to your computer and use it in GitHub Desktop.
Save abernier/1512474 to your computer and use it in GitHub Desktop.
camera CSS
A simple 2D camera over DOM elements.
$screen = $('#screen')
$world = $('#world')
H = $screen.height()
W = $screen.width()
spotOn = (el, spec = {}) ->
$target = $(el)
spec = $.extend(true, {
theta: 0
radian: false
}, spec)
bounds = bounding($target, spec.radian and spec.theta or deg2rad(spec.theta))
x = $target.position().left
y = $target.position().top
h = $target.height()
w = $target.width()
$world.animate
scale: Math.min W / bounds.w, H / bounds.h
rotate: "#{spec.radian and rad2deg(spec.theta) or spec.theta}deg"
translateX: "#{W/2 - (x + w/2)}px"
translateY: "#{H/2 - (y + h/2)}px"
, 3000
###
Utilities
###
deg2rad = (theta) ->
theta * Math.PI / 180
rad2deg = (theta) ->
theta * 180 / Math.PI
bounding = (el, theta = 0) ->
$el = $(el)
w = $el.width()
h = $el.height()
#
# Our rotation matrix
#
# see: http://en.wikipedia.org/wiki/Rotation_matrix
#
R = $M [
[Math.cos(theta), -Math.sin(theta)]
[Math.sin(theta), Math.cos(theta)]
]
#
# Our 4 original points
#
A = $V [0, 0]
B = $V [w, 0]
C = $V [w, h]
D = $V [0, h]
#
# Our four points, rotated
#
AA = R.multiply A
BB = R.multiply B
CC = R.multiply C
DD = R.multiply D
xs = [AA, BB, CC, DD].map((el) -> el.elements[0])
ys = [AA, BB, CC, DD].map((el) -> el.elements[1])
{
w: Math.max.apply(null, xs) - Math.min.apply(null, xs)
h: Math.max.apply(null, ys) - Math.min.apply(null, ys)
}
#console.log bounding($('#box1'))
spotOn($('#box3'), {theta: 0})
spotOn($('#box1'), {theta: 0})
spotOn($('#box2'), {theta: 80})
spotOn($('#box2'), {theta: 360})
spotOn($('#box1'), {theta: 0})
html, body {height:100%;}
html {display:table; width:100%;}
body {margin:0; display:table-cell; text-align:center; vertical-align:middle;}
#screen {display:inline-block; outline:50em solid rgba(0,0,0,.2); width:300px; height:200px;}
#world {position:relative; height:100%; z-index:-1;}
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title></title>
<link rel="stylesheet" href="index.css">
<script src="http://jashkenas.github.com/coffee-script/extras/coffee-script.js"></script>
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="https://rawgithub.com/heygrady/transform/master/dist/jquery.transform-0.9.3.min.js"></script>
<script src="https://rawgithub.com/jcoglan/sylvester/master/src/sylvester.js"></script>
<script src="https://rawgithub.com/jcoglan/sylvester/master/src/vector.js"></script>
<script src="https://rawgithub.com/jcoglan/sylvester/master/src/matrix.js"></script>
</head>
<body>
<div id="screen"><div id="world">
<div id="box1" style="width:1em; height:48px; background-color:red; position:absolute; top:15%; left:20%"></div>
<div id="box2" style="width:15%; height:2.5em; background-color:green; position:absolute; bottom:5em; right:10%;"></div>
<div id="box3" style="width:.5em; height:1em; background-color:yellowGreen; position:absolute; bottom:15em; left:20%;"></div>
<div id="circle" style="width:50px; height:50px; position:absolute; top:50%; left:50%; margin-top:-25px; margin-left:-25px; border-radius:100%; background-color:yellow;"></div>
</div></div>
<script src="index.coffee" type="text/coffeescript"></script>
</body>
</html>
@abernier
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment