285 lines
7.2 KiB
HTML
285 lines
7.2 KiB
HTML
<!DOCTYPE html>
|
|
|
|
<!--
|
|
|
|
Copyright 2006 Google Inc.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
-->
|
|
|
|
<html>
|
|
<head>
|
|
<title></title>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<!--[if IE]><script type="text/javascript" src="../excanvas.js"></script><![endif]-->
|
|
<style type="text/css">
|
|
|
|
body {
|
|
overflow: hidden;
|
|
width: 100%;
|
|
height: 100%;
|
|
margin: 0;
|
|
}
|
|
|
|
#image-rotator {
|
|
position: absolute;
|
|
left: 0;
|
|
top: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
#image-rotator .tool-bar {
|
|
text-align: center;
|
|
}
|
|
|
|
.tool-bar button {
|
|
margin: 0.5em 0.5em 0 0;
|
|
}
|
|
|
|
#image-rotator img,
|
|
#image-rotator canvas {
|
|
position: absolute;
|
|
}
|
|
|
|
</style>
|
|
<script type="text/javascript">
|
|
|
|
function sawFunc(a) {
|
|
var PI = Math.PI;
|
|
var PI2 = PI / 2;
|
|
// make sure a is within 0 to PI
|
|
a = a % PI;
|
|
if (a < 0) {
|
|
a += PI;
|
|
}
|
|
if (a < PI2) {
|
|
return a / PI2;
|
|
} else {
|
|
return (PI - a) / PI2;
|
|
}
|
|
}
|
|
|
|
function easeInEaseOut(t) {
|
|
var t2 = t * t;
|
|
return 3 * t2 - 2 * t * t2;
|
|
}
|
|
|
|
function ImageRotator(el, src, w, h) {
|
|
this.element = el;
|
|
this.toolBar = el.getElementsByTagName("div")[0];
|
|
this.canvas = el.getElementsByTagName("canvas")[0];
|
|
var images = el.getElementsByTagName("img");
|
|
this.image = images[images.length - 1];
|
|
var btns = el.getElementsByTagName("button");
|
|
this.btnCw = btns[0];
|
|
this.btnCcw = btns[1];
|
|
var self = this;
|
|
this.btnCcw.onclick = function () {
|
|
self.rotateCcw();
|
|
};
|
|
this.btnCw.onclick = function () {
|
|
self.rotateCw();
|
|
};
|
|
this.image.onload = function (e) {
|
|
self.onImageLoad(e);
|
|
};
|
|
this.image.onerror = function (e) {
|
|
self.onImageError(e);
|
|
};
|
|
this.image.onabort = function (e) {
|
|
self.onImageAbort(e);
|
|
};
|
|
this.setImage(src, w, h);
|
|
this.layout();
|
|
|
|
var onResize = function () {
|
|
self.layout();
|
|
};
|
|
var onLoad = function () {
|
|
self.onWindowLoad();
|
|
};
|
|
if (window.addEventListener) {
|
|
window.addEventListener("resize", onResize, false);
|
|
window.addEventListener("load", onLoad, false);
|
|
} else if (window.attachEvent) {
|
|
window.attachEvent("onresize", onResize);
|
|
window.attachEvent("onload", onLoad);
|
|
}
|
|
}
|
|
|
|
ImageRotator.prototype = {
|
|
getLoaded: function () {
|
|
return this.imageLoaded && this.windowLoaded;
|
|
},
|
|
setImage: function (src, w, h) {
|
|
this.imageLoaded = false;
|
|
this.image.src = src;
|
|
this.imageWidth = w;
|
|
this.imageHeight = h;
|
|
},
|
|
|
|
layout: function () {
|
|
var PI2 = Math.PI / 2;
|
|
var h = this.element.clientHeight;
|
|
var w = this.element.clientWidth;
|
|
var th = this.toolBar.offsetHeight;
|
|
h -= this.toolBar.offsetHeight;
|
|
if (!this.ctx || !this.getLoaded()) {
|
|
this.btnCw.disabled = true;
|
|
this.btnCcw.disabled = true;
|
|
this.canvas.style.display = "none";
|
|
this.image.style.display = "block";
|
|
var ratio = Math.min(w / this.imageWidth, h / this.imageHeight, 1);
|
|
var imgW = this.imageWidth * ratio;
|
|
var imgH = this.imageHeight * ratio;
|
|
var y = th + (h - imgH) / 2;
|
|
var x = (w - imgW) / 2;
|
|
this.image.style.left = Math.round(x) + "px";
|
|
this.image.style.top = Math.round(y) + "px";
|
|
this.image.style.width = Math.round(imgW) + "px";
|
|
this.image.style.height = Math.round(imgH) + "px";
|
|
} else {
|
|
this.btnCw.disabled = this.isAnimating_;
|
|
this.btnCcw.disabled = this.isAnimating_;
|
|
this.canvas.style.display = "block";
|
|
this.image.style.display = "none";
|
|
|
|
this.canvas.style.left = 0 + "px";
|
|
this.canvas.style.top = th + "px";
|
|
this.canvas.style.width = w + "px";
|
|
this.canvas.width = w;
|
|
this.canvas.style.height = h + "px";
|
|
this.canvas.height = h;
|
|
|
|
this.ctx.save();
|
|
this.ctx.clearRect(0, 0, w, h);
|
|
this.ctx.translate(w / 2, h / 2);
|
|
this.ctx.rotate(this.rotation);
|
|
// 0 -> 1, sin(0) = 0
|
|
// PI / 2 -> H / W, sin(PI/2) = 1
|
|
|
|
// sin(PI/2) = 1 -> limit factor is w and imgH
|
|
|
|
var iw = this.imageWidth;
|
|
var ih = this.imageHeight;
|
|
var scale;
|
|
if (iw <= w && iw <= h && ih <= h && ih <= w) {
|
|
scale = 1;
|
|
} else {
|
|
var sinr = sawFunc(this.rotation);
|
|
var cosr = sawFunc(this.rotation + PI2);
|
|
var ratio1 = sinr * Math.min(w / ih, h / iw);
|
|
var ratio2 = cosr * Math.min(w / iw, h / ih);
|
|
var ratio = Math.min(1, ratio1 + ratio2);
|
|
scale = ratio;
|
|
}
|
|
this.ctx.scale(scale, scale);
|
|
this.ctx.translate(-iw / 2, -ih / 2);
|
|
this.ctx.drawImage(this.image, 0, 0, iw, ih);
|
|
this.ctx.restore();
|
|
}
|
|
},
|
|
|
|
rotation: 0,
|
|
animationDuration: 500,
|
|
|
|
rotateCcw: function () {
|
|
if (!this.isAnimating_) {
|
|
this.startTime_ = (new Date).valueOf();
|
|
this.currentAngle_ = this.rotation;
|
|
this.deltaAngle_ = Math.PI / 2;
|
|
this.isAnimating_ = true;
|
|
this.animCounter_ = 0;
|
|
this.rotate_();
|
|
}
|
|
},
|
|
|
|
rotateCw: function () {
|
|
if (!this.isAnimating_) {
|
|
this.startTime_ = (new Date).valueOf();
|
|
this.currentAngle_ = this.rotation;
|
|
this.deltaAngle_ = -Math.PI / 2;
|
|
this.isAnimating_ = true;
|
|
this.animCounter_ = 0;
|
|
this.rotate_();
|
|
}
|
|
},
|
|
|
|
rotate_: function () {
|
|
if (this.isAnimating_) {
|
|
var t = easeInEaseOut(Math.min(1, (new Date - this.startTime_) /
|
|
this.animationDuration));
|
|
this.rotation = t * this.deltaAngle_ + this.currentAngle_;
|
|
if (t < 1) {
|
|
var self = this;
|
|
window.setTimeout(function () {
|
|
self.rotate_();
|
|
}, 10);
|
|
} else {
|
|
this.isAnimating_ = false;
|
|
}
|
|
this.layout();
|
|
}
|
|
},
|
|
|
|
onImageLoad: function (e) {
|
|
this.imageLoaded = true;
|
|
this.initCanvas();
|
|
},
|
|
onImageError: function (e) {
|
|
this.imageLoaded = false;
|
|
},
|
|
onImageAbort: function (e) {
|
|
this.imageLoaded = false;
|
|
},
|
|
onWindowLoad: function (e) {
|
|
this.windowLoaded = true;
|
|
this.initCanvas();
|
|
},
|
|
|
|
initCanvas: function () {
|
|
if (!this.ctx && this.getLoaded()) {
|
|
// IE recreates the element?
|
|
this.canvas = this.element.getElementsByTagName("canvas")[0];
|
|
this.ctx = this.canvas.getContext("2d");
|
|
|
|
if (!this.ctx) {
|
|
return;
|
|
}
|
|
this.layout();
|
|
}
|
|
}
|
|
};
|
|
|
|
</script>
|
|
</head>
|
|
<body>
|
|
|
|
<div id="image-rotator">
|
|
<div class="tool-bar">
|
|
<button>Rotate Left</button><button>Rotate Right</button>
|
|
</div>
|
|
<canvas id="c"></canvas>
|
|
<img src="" alt="">
|
|
</div>
|
|
<script type="text/javascript">
|
|
new ImageRotator(document.getElementById("image-rotator"),
|
|
"ff.jpg", 608, 380);
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|
|
|