in my project I came across with a need for pinch to zoom support, but not the basic one.
and there are two main "must have" while doing so.
1) only the DIV container will zoom, and not the rest of the page (eg: top bar)
2) I need to keep the window basic scroll
I've added a simple code showing how I've done so and it left me with 2 questions
I) the page is jumpy while I'm pinching for zoom.
II) have I calculate this correctly? or should I have it another way?
* you can find a working example in the link below
https://www.klika.co.il/canvas/pinch.html
// ----------- TOUCH --------------
//handles on move events for tracking touches
var touches = {
points: null,
start: function (e) {
if (gesture.is.on) {
e = e || window.event;
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}
//reset touches
touches.points = null;
msg('touch start');
},
move: function (e) {
// msg('touch move');
if (e.touches.length > 1) {
// msg('touch move ' + e.touches.length + ' fingers');
//set touches only if two fingers are on
touches.points = { x: {}, y: {} }
for (var i = 0; i < e.touches.length; i++) {
touches.points.x[i] = e.touches[i].clientX;
touches.points.y[i] = e.touches[i].clientY;
}
}
},
end: function (e) {
msg('touch end');
}
};
// ----------- GESTURE --------------
var gesture = {
is: {
on: false,
init: false
},
data: {
content: null,
elem: null,
width: 0,
state: {},
},
start: function (e) {
gesture.is.on = true;
msg('gesture start');
gesture.data.content = $('.containter')[0];
gesture.data.elem = $('.containter .wrap')[0];
gesture.data.width = toFloat(gesture.data.elem.style.width, 100);
gesture.is.init = true;
},
move: function (e) {
if (!touches.points) { return; }
//set the body element for Y axis
const el = document.scrollingElement || document.documentElement;
//set mid points
var X1 = touches.points.x[0];
var Y1 = touches.points.y[0];
var X2 = touches.points.x[1];
var Y2 = touches.points.y[1];
var mid = getMidPoint(X1, Y1, X2, Y2);
//set start position on init
if (gesture.is.init) {
gesture.data.state = {
w: gesture.data.width / 100,
sl: ((gesture.data.content.scrollLeft + mid.x) / gesture.data.content.scrollWidth) * 100,
st: ((el.scrollTop + mid.y) / el.scrollHeight) * 100,
mid: mid
}
gesture.is.init = false;
}
//calc/set width of the wrapping DIV
var inc = e.scale * gesture.data.state.w;
var WPX = gesture.data.content.scrollWidth * inc;
var HPX = document.body.scrollHeight * inc;
var w = (WPX / gesture.data.content.scrollWidth) * 100;
gesture.data.elem.style.width = w + '%';
//calc/set scrollLeft of the wrapping DIV (X axis)
var sln = Math.round(((gesture.data.state.sl / 100) * gesture.data.content.scrollWidth) - (getWindowXY().w / 2));
if (sln < 0) { sln = 0; }
sln += gesture.data.state.mid.x - mid.x;
gesture.data.content.scrollLeft = sln;
//calc/set scrollLeft of the body element (Y axis)
var slt = Math.round(((gesture.data.state.st / 100) * el.scrollHeight) - (getWindowXY().h / 2));
if (slt < 0) { slt = 0; }
slt += gesture.data.state.mid.y - mid.y;
el.scrollTop = slt;
},
end: function (e) {
var w = toFloat(gesture.data.elem.style.width);
if (isNaN(w) || w < 100) {
gesture.data.elem.style.width = '100%';
}
gesture.is.on = false;
}
}
// -------- BIND ------
window.addEventListener('touchstart', touches.start, false);
window.addEventListener('touchmove', touches.move, true);
window.addEventListener('touchend', touches.end, true);
window.addEventListener('gesturestart', gesture.start, false);
window.addEventListener('gesturechange', gesture.move, false);
window.addEventListener('gestureend', gesture.end, false);
//------ GENERAL --------
String.prototype.format = function () {
var s = this,
i = arguments.length;
if (!s) {
return "";
}
while (i--) {
s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]);
}
return s;
}
var toFloat = function (val) {
return parseFloat(val.replace("%", ""));
}
var getWindowXY = function () {
var myWidth = 0, myHeight = 0;
if (typeof (window.innerWidth) == 'number') {
//Non-IE
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
//IE 6+ in 'standards compliant mode'
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
} else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
//IE 4 compatible
myWidth = document.body.clientWidth;
myHeight = document.body.clientHeight;
}
return {
h: myHeight,
w: myWidth
}
}
var msg = function (text) {
$('.info').html(text);
}
var getMidPoint = function (x1, y1, x2, y2) {
return { x: ((x1 + x2) / 2), y: ((y1 + y2) / 2) }
}
window.oncontextmenu = function (event) {
event.preventDefault();
event.stopPropagation();
return false;
};
window.addEventListener('error', function (e) {
if (e.message == "Script error.") { return; }
if (e.message.indexOf('facebook') != -1) { return; }
msg(e.message);
}, false);
body {
margin: 0;
padding: 0;
width:100vw;
}
.top{
position: fixed;
width: 100%;
background-color: #333;
line-height: 40pt;
text-align: center;
color: #f1f1f1;
font-size: 20pt;
left: 0;
top: 0;
}
.top .info{
}
.containter {
width: 100%;
overflow-x: auto;
}
.containter .wrap {
display: flex;
flex-direction: column;
width: 100%;
}
.containter .wrap img {
width: 100%;
margin-top: 30pt;
}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width, height=device-height, user-scalable=no" />
<title>Pinch to zoom</title>
<script src="https://www.klika.co.il/plugins/jqTools/js/jquery-1.7.1.min.js" type="text/javascript"></script>
</head>
<body>
<div class="top">
<div class="info">Pinch to zoom</div>
</div>
<div class="containter">
<div class="wrap">
<img src="https://thumb7.shutterstock.com/display_pic_with_logo/91858/594887747/stock-photo-dreams-of-travel-child-flying-on-a-suitcase-against-the-backdrop-of-sunset-594887747.jpg" />
<img src="https://thumb9.shutterstock.com/display_pic_with_logo/1020994/556702975/stock-photo-portrait-of-a-happy-and-proud-pregnant-woman-looking-at-her-belly-in-a-park-at-sunrise-with-a-warm-556702975.jpg" />
<img src="https://thumb7.shutterstock.com/display_pic_with_logo/234100/599187701/stock-photo-funny-little-girl-plays-super-hero-over-blue-sky-background-superhero-concept-599187701.jpg" />
<img src="https://thumb1.shutterstock.com/display_pic_with_logo/1316512/661476343/stock-photo-funny-pineapple-in-sunglasses-near-swimming-pool-661476343.jpg" />
<img src="https://thumb1.shutterstock.com/display_pic_with_logo/2114402/689953639/stock-photo-adult-son-hugging-his-old-father-against-cloudy-sky-with-sunshine-689953639.jpg" />
<img src="https://thumb7.shutterstock.com/display_pic_with_logo/172762/705978841/stock-photo-businessman-looking-to-the-future-for-new-business-opportunity-705978841.jpg" />
</div>
</div>
</body>
</html>
Related
There are many "pull to refresh" plugins. I have already tested 5 of them. But none of them running fast (especially on old smartphones).
What is the best (buttery UX performance and responsiveness) way to check for pull to refresh?
PS: I don't need any animation. I just want to recognize if a user "pull to refresh"
Performance requires minimal code
Plugins and libraries have to be written to be as flexible and general as possible, in order to solve many related problems. This means they'll always be bulkier than you need, impacting performance. It also means you'll never have to maintain that code. That's the trade off.
If performance is your goal, build it yourself.
Since ALL you need is a pull-down detection, build a simple swipe detector.
Of course, you'll have to adapt this to your needs, and the event-properties, event-triggers of the OS and browser you're targeting.
Simplified from my old js-minimal-swipe-detect
var pStart = { x: 0, y: 0 };
var pStop = { x: 0, y: 0 };
function swipeStart(e) {
if (typeof e["targetTouches"] !== "undefined") {
var touch = e.targetTouches[0];
pStart.x = touch.screenX;
pStart.y = touch.screenY;
} else {
pStart.x = e.screenX;
pStart.y = e.screenY;
}
}
function swipeEnd(e) {
if (typeof e["changedTouches"] !== "undefined") {
var touch = e.changedTouches[0];
pStop.x = touch.screenX;
pStop.y = touch.screenY;
} else {
pStop.x = e.screenX;
pStop.y = e.screenY;
}
swipeCheck();
}
function swipeCheck() {
var changeY = pStart.y - pStop.y;
var changeX = pStart.x - pStop.x;
if (isPullDown(changeY, changeX)) {
alert("Swipe Down!");
}
}
function isPullDown(dY, dX) {
// methods of checking slope, length, direction of line created by swipe action
return (
dY < 0 &&
((Math.abs(dX) <= 100 && Math.abs(dY) >= 300) ||
(Math.abs(dX) / Math.abs(dY) <= 0.3 && dY >= 60))
);
}
document.addEventListener(
"touchstart",
function (e) {
swipeStart(e);
},
false
);
document.addEventListener(
"touchend",
function (e) {
swipeEnd(e);
},
false
);
What about this?
var lastScrollPosition = 0;
window.onscroll = function(event)
{
if((document.body.scrollTop >= 0) && (lastScrollPosition < 0))
{
alert("refresh");
}
lastScrollPosition = document.body.scrollTop;
}
If your browser doesn't scroll negative, then you could replace line 4 with something like this:
if((document.body.scrollTop == 0) && (lastScrollPosition > 0))
Alternatively for android devices, you could swap out lastScrollPosition for "ontouchmove" or other gesture events.
have you tired these solutions??
You need to check this fiddle
var mouseY = 0
var startMouseY = 0
$("body").on("mousedown", function (ev) {
mouseY = ev.pageY
startMouseY = mouseY
$(document).mousemove(function (e) {
if (e.pageY > mouseY) {
var d = e.pageY - startMouseY
console.log("d: " + d)
if (d >= 200) location.reload()
$("body").css("margin-top", d / 4 + "px")
} else $(document).unbind("mousemove")
})
})
$("body").on("mouseup", function () {
$("body").css("margin-top", "0px")
$(document).unbind("mousemove")
})
$("body").on("mouseleave", function () {
$("body").css("margin-top", "0px")
$(document).unbind("mousemove")
})
and if you are looking for some plugin this plugin might help you
I know this answer has been answered by a lot many people but it may help someone.
It's based on Mr. Pryamid's answer. but his answer does not work touch screen. that only works with mouse.
this answer works well on touch screen and desktop. i have tested in chrome in desktop and chrome in android
<!DOCTYPE html>
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
}
html,
body {
width: 100%;
height: 100%;
}
.pull-to-refresh-container {
width: 100%;
height: 100%;
background-color: yellow;
position: relative;
}
.pull-to-refresh-content-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: white;
margin: 0px;
text-align: center;
}
</style>
</head>
<body>
<div class="pull-to-refresh-container">
<div class="pull-to-refresh-loader-container">
loading ...
</div>
<div class="pull-to-refresh-content-container">
here lies the content
</div>
</div>
<script>
var mouseY = 0
var startMouseY = 0
var container = document.querySelector(
".pull-to-refresh-content-container"
)
container.onmousedown = (ev) => {
mouseY = ev.pageY
startMouseY = mouseY
container.onmousemove = (e) => {
if (e.pageY > mouseY) {
var d = e.pageY - startMouseY
console.log("d: " + d)
container.style.marginTop = d / 4 + "px"
if (d >= 300) {
// alert("load more content");
}
} else {
container.onmousemove = null
}
}
}
container.onmouseup = (ev) => {
container.style.marginTop = "0px"
container.onmousemove = null
}
container.onmouseleave = (ev) => {
container.style.marginTop = "0px"
container.onmousemove = null
}
container.ontouchstart = (ev) => {
mouseY = ev.touches[0].pageY
startMouseY = mouseY
container.ontouchmove = (e) => {
if (e.touches[0].pageY > mouseY) {
var d = e.touches[0].pageY - startMouseY
console.log("d: " + d)
container.style.marginTop = d / 4 + "px"
if (d >= 300) {
// alert("load more content");
}
} else {
container.onmousemove = null
}
}
}
container.ontouchcancel = (ev) => {
container.style.marginTop = "0px"
container.onmousemove = null
}
container.ontouchend = (ev) => {
container.style.marginTop = "0px"
container.onmousemove = null
}
</script>
</body>
</html>
Here is how I did it with Stimulus and Turbolinks:
See video in action: https://imgur.com/a/qkzbhZS
import { Controller } from "stimulus"
import Turbolinks from "turbolinks"
export default class extends Controller {
static targets = ["logo", "refresh"]
touchstart(event) {
this.startPageY = event.changedTouches[0].pageY
}
touchmove(event) {
if (this.willRefresh) {
return
}
const scrollTop = document.documentElement.scrollTop
const dy = event.changedTouches[0].pageY - this.startPageY
if (scrollTop === 0 && dy > 0) {
this.logoTarget.classList.add("hidden")
this.refreshTarget.classList.remove("hidden")
if (dy > 360) {
this.willRefresh = true
this.refreshTarget.classList.add("animate-spin")
this.refreshTarget.style.transform = ""
} else {
this.refreshTarget.classList.remove("animate-spin")
this.refreshTarget.style.transform = `rotate(${dy}deg)`
}
} else {
this.logoTarget.classList.remove("hidden")
this.refreshTarget.classList.add("hidden")
this.refreshTarget.classList.remove("animate-spin")
this.refreshTarget.style.transform = ""
}
}
touchend(event) {
if (this.willRefresh) {
Turbolinks.visit(window.location.toString(), { action: 'replace' })
} else {
this.logoTarget.classList.remove("hidden")
this.refreshTarget.classList.add("hidden")
this.refreshTarget.classList.remove("animate-spin")
this.refreshTarget.style.transform = ""
}
}
}
body(class="max-w-md mx-auto" data-controller="pull-to-refresh" data-action="touchstart#window->pull-to-refresh#touchstart touchmove#window->pull-to-refresh#touchmove touchend#window->pull-to-refresh#touchend")
= image_tag "logo.png", class: "w-8 h-8 mr-2", "data-pull-to-refresh-target": "logo"
= image_tag "refresh.png", class: "w-8 h-8 mr-2 hidden", "data-pull-to-refresh-target": "refresh"
One simple way:
$(document.body).pullToRefresh(function() {
setTimeout(function() {
$(document.body).pullToRefreshDone();
}, 2000);
});
i'm making a simple game with HTML only, more or less it works... My question is if i can make a simple menu /with "click to start" or something similar/ with an image at the background and 1 button to start the game. And if i can make it in the same archive.
Thanks.
<canvas id="ctx" width="1024" height="800" style="border:3px solid #000000;"></canvas>
<script>
var Height = 800;
var Width = 1024;
var timeElapset = Date.now();
var ctx = document.getElementById("ctx").getContext("2d");
ctx.font = '30px Consolas';
var frameCount = 0;
var score = 0;
var player = {
x:50,
spdX:30,
y:40,
spdY:30,
name:'P',
hp:10,
width:20,
height:20,
color:'green',
};
var enemyList = {};
getDistance = function (Obj1,Obj2){
var vx = Obj1.x - Obj2.x;
var vy = Obj1.y - Obj2.y;
return Math.sqrt((vx*vx)+(vy*vy));
}
checkCollision = function (Obj1,Obj2){
var rect1 = {
x: Obj1.x - Obj1.width/2,
y: Obj1.y - Obj1.height/2,
height: Obj1.height,
width: Obj1.width,
}
var rect2 = {
x: Obj2.x - Obj2.width/2,
y: Obj2.y - Obj2.height/2,
height: Obj2.height,
width: Obj2.width,
}
return testCollisionRectRect(rect1,rect2); //true o false
}
Enemy = function (id,x,y,spdX,spdY,width,height){
var enemy = {
x:x,
spdX:spdX,
y:y,
spdY:spdY,
name:'E',
id:id,
width:width,
height:height,
color:'black',
};
enemyList[id] = enemy;
}
document.onmousemove = function(mouse){
var mouseX = mouse.clientX - document.getElementById('ctx').getBoundingClientRect().left;
var mouseY = mouse.clientY - document.getElementById('ctx').getBoundingClientRect().top;
if(mouseX < player.width/2)
mouseX = player.width/2;
if(mouseX > Width-player.width/2)
mouseX = Width - player.width/2;
if(mouseY < player.height/2)
mouseY = player.height/2;
if(mouseY > Height - player.height/2)
mouseY = Height - player.height/2;
player.x = mouseX;
player.y = mouseY;
}
updateEntity = function (Z){
updatePosition(Z);
drawPlayer(Z);
}
updatePosition = function(Z){
Z.x += Z.spdX;
Z.y += Z.spdY;
if(Z.x < 0 || Z.x > Width){
Z.spdX = -Z.spdX;
}
if(Z.y < 0 || Z.y > Height){
Z.spdY = -Z.spdY;
}
}
testCollisionRectRect = function(rect1,rect2){
return rect1.x <= rect2.x+rect2.width &&
rect2.x <= rect1.x+rect1.width &&
rect1.y <= rect2.y + rect2.height &&
rect2.y <= rect1.y + rect1.height;
}
drawPlayer = function(Z){
ctx.save();
ctx.fillStyle = Z.color;
ctx.fillRect(Z.x-Z.width/2,Z.y-Z.height/2,Z.width,Z.height);
ctx.restore();
}
update = function(){
ctx.clearRect(0,0,Width,Height);
frameCount++;
score++;
if(frameCount % 100 == 0)
randomGenerateEnemy();
for(var key in enemyList){
updateEntity(enemyList[key]);
var isColliding = checkCollision(player, enemyList[key]);
if(isColliding){
player.hp = player.hp -1;
}
}
if(player.hp <= 0){
var timeSurvived = Date.now() - timeElapset;
console.log("Has ganado Kappa, Tiempo vivo " + timeSurvived + " ms.");
ctx.fillText(" You Lose! ", Width/2, Height/2);
GameEngine();
}
drawPlayer(player);
ctx.fillText(player.hp + " Hp",20,30);
ctx.fillText('Puntuacion: ' + score/10,700,30);
}
GameEngine = function(){
player.hp = 13;
timeElapset = Date.now();
frameCount = 0;
score = 0;
enemyList = {};
randomGenerateEnemy();
randomGenerateEnemy();
randomGenerateEnemy();
randomGenerateEnemy();
}
randomGenerateEnemy = function(){
var x = Math.random()*Width;
var y = Math.random()*Height;
var height = 10 + Math.random()*70;
var width = 10 + Math.random()*70;
var id = Math.random();
var spdX = 5 + Math.random() * 5;
var spdY = 5 + Math.random() * 5;
Enemy(id,x,y,spdX,spdY,width,height);
}
GameEngine();
setInterval(update,30);
</script>
That's what i have.
The code also contains javascript.For proper gaming function .js file has to be called on your html page.Also use css to make it attractive.Consider this example
enter code here
<html>
<head>
<title>Your game title</title>
<script type="text/javascript" src="src/Common.js"></script>
<script type="text/javascript" src="src/Perlin.js"></script>
<script type="text/javascript" src="src/ChaikinCurve.js"></script>
<script type="text/javascript">
var app = null;
window.onload = function() {
utils.loadShaderXml("src/render/shaders.xml", null, function(shaders) {
if (shaders instanceof Exception) {
app = shaders;
} else {
try {
app = new App('canvas', shaders, null);
} catch (e) {
app = e;
}
}
});
document.onselectstart = function () {
return false;
};
};
function application() {
if (app == null) {
alert("Application is absent");
throw "no application";
} else if (app instanceof Exception) {
alert("An exception occured while creating the application:\n" + app.message);
throw app;
} else {
return app;
}
}
</script>
<style type="text/css">
body{
margin: 0px; padding: 0px; overflow: hidden;
background: #000;
}
#canvas-holder.active {
position: absolute;
padding: 0px;
left: 50%;
top: 50%;
}
#canvas-holder.inactive {
position: absolute;
top:50%;
width: 100%;
text-align: center;
}
#canvas {
padding: 0px;
width: 100%;
height: 100%;
color: #fff;
font-family: Allan, Arial;
font-size: 40px;
}
</style>
</head>
<body>
<div id="canvas-holder" class="inactive">
<div id="canvas">Your game` is loading...</div>
</div>
<div style="font-family: Lobster; visibility: hidden">one</div>
<div style="font-family: Allan; visibility: hidden">two</div>
<div style="font-family: Meddon; visibility: hidden">three</div>
<div style="font-family: Cuprum; visibility: hidden">four</div>
</body>
</html>
I'm using a simple JavaScript. I change the container's height and width. I think I need to fix the JavaScript, because it is working on the container which as height set in px, but I have set the height as %. The problem is appearing when you resize (you can't see full img or there is too much space) on bottom of the container.
Or maybe I'm wrong... Any tips?
function jsScroller (o, w, h) {
var self = this;
var list = o.getElementsByTagName("div");
for (var i = 0; i < list.length; i++) {
if (list[i].className.indexOf("Scroller-Container") > -1) {
o = list[i];
}
}
//Private methods
this._setPos = function (x, y) {
if (x < this.viewableWidth - this.totalWidth)
x = this.viewableWidth - this.totalWidth;
if (x > 0) x = 0;
if (y < this.viewableHeight - this.totalHeight)
y = this.viewableHeight - this.totalHeight;
if (y > 0) y = 0;
this._x = x;
this._y = y;
with (o.style) {
left = this._x +"px";
top = this._y +"px";
}
};
//Public Methods
this.reset = function () {
this.content = o;
this.totalHeight = o.offsetHeight;
this.totalWidth = o.offsetWidth;
this._x = 0;
this._y = 0;
with (o.style) {
left = "0px";
top = "0px";
}
};
this.scrollBy = function (x, y) {
this._setPos(this._x + x, this._y + y);
};
this.scrollTo = function (x, y) {
this._setPos(-x, -y);
};
this.stopScroll = function () {
if (this.scrollTimer) window.clearInterval(this.scrollTimer);
};
this.startScroll = function (x, y) {
this.stopScroll();
this.scrollTimer = window.setInterval(
function(){ self.scrollBy(x, y); }, 40
);
};
this.swapContent = function (c, w, h) {
o = c;
var list = o.getElementsByTagName("div");
for (var i = 0; i < list.length; i++) {
if (list[i].className.indexOf("Scroller-Container") > -1) {
o = list[i];
}
}
if (w) this.viewableWidth = w;
if (h) this.viewableHeight = h;
this.reset();
};
//variables
this.content = o;
this.viewableWidth = w;
this.viewableHeight = h;
this.totalWidth = o.offsetWidth;
this.totalHeight = o.offsetHeight;
this.scrollTimer = null;
this.reset();
};
function jsScrollbar (o, s, a, ev) {
var self = this;
this.reset = function () {
//Arguments that were passed
this._parent = o;
this._src = s;
this.auto = a ? a : false;
this.eventHandler = ev ? ev : function () {};
//Component Objects
this._up = this._findComponent("Scrollbar-Up", this._parent);
this._down = this._findComponent("Scrollbar-Down", this._parent);
this._yTrack = this._findComponent("Scrollbar-Track", this._parent);
this._yHandle = this._findComponent("Scrollbar-Handle", this._yTrack);
//Height and position properties
this._trackTop = findOffsetTop(this._yTrack);
this._trackHeight = this._yTrack.offsetHeight;
this._handleHeight = this._yHandle.offsetHeight;
this._x = 0;
this._y = 0;
//Misc. variables
this._scrollDist = 5;
this._scrollTimer = null;
this._selectFunc = null;
this._grabPoint = null;
this._tempTarget = null;
this._tempDistX = 0;
this._tempDistY = 0;
this._disabled = false;
this._ratio = (this._src.totalHeight - this._src.viewableHeight)/(this._trackHeight - this._handleHeight);
this._yHandle.ondragstart = function () {return false;};
this._yHandle.onmousedown = function () {return false;};
this._addEvent(this._src.content, "mousewheel", this._scrollbarWheel);
this._removeEvent(this._parent, "mousedown", this._scrollbarClick);
this._addEvent(this._parent, "mousedown", this._scrollbarClick);
this._src.reset();
with (this._yHandle.style) {
top = "0px";
left = "0px";
}
this._moveContent();
if (this._src.totalHeight < this._src.viewableHeight) {
this._disabled = true;
this._yHandle.style.visibility = "hidden";
if (this.auto) this._parent.style.visibility = "hidden";
} else {
this._disabled = false;
this._yHandle.style.visibility = "visible";
this._parent.style.visibility = "visible";
}
};
this._addEvent = function (o, t, f) {
if (o.addEventListener) o.addEventListener(t, f, false);
else if (o.attachEvent) o.attachEvent('on'+ t, f);
else o['on'+ t] = f;
};
this._removeEvent = function (o, t, f) {
if (o.removeEventListener) o.removeEventListener(t, f, false);
else if (o.detachEvent) o.detachEvent('on'+ t, f);
else o['on'+ t] = null;
};
this._findComponent = function (c, o) {
var kids = o.childNodes;
for (var i = 0; i < kids.length; i++) {
if (kids[i].className && kids[i].className == c) {
return kids[i];
}
}
};
//Thank you, Quirksmode
function findOffsetTop (o) {
var t = 0;
if (o.offsetParent) {
while (o.offsetParent) {
t += o.offsetTop;
o = o.offsetParent;
}
}
return t;
};
this._scrollbarClick = function (e) {
if (self._disabled) return false;
e = e ? e : event;
if (!e.target) e.target = e.srcElement;
if (e.target.className.indexOf("Scrollbar-Up") > -1) self._scrollUp(e);
else if (e.target.className.indexOf("Scrollbar-Down") > -1) self._scrollDown(e);
else if (e.target.className.indexOf("Scrollbar-Track") > -1) self._scrollTrack(e);
else if (e.target.className.indexOf("Scrollbar-Handle") > -1) self._scrollHandle(e);
self._tempTarget = e.target;
self._selectFunc = document.onselectstart;
document.onselectstart = function () {return false;};
self.eventHandler(e.target, "mousedown");
self._addEvent(document, "mouseup", self._stopScroll, false);
return false;
};
this._scrollbarDrag = function (e) {
e = e ? e : event;
var t = parseInt(self._yHandle.style.top);
var v = e.clientY + document.body.scrollTop - self._trackTop;
with (self._yHandle.style) {
if (v >= self._trackHeight - self._handleHeight + self._grabPoint)
top = self._trackHeight - self._handleHeight +"px";
else if (v <= self._grabPoint) top = "0px";
else top = v - self._grabPoint +"px";
self._y = parseInt(top);
}
self._moveContent();
};
this._scrollbarWheel = function (e) {
e = e ? e : event;
var dir = 0;
if (e.wheelDelta >= 120) dir = -1;
if (e.wheelDelta <= -120) dir = 1;
self.scrollBy(0, dir * 20);
e.returnValue = false;
};
this._startScroll = function (x, y) {
this._tempDistX = x;
this._tempDistY = y;
this._scrollTimer = window.setInterval(function () {
self.scrollBy(self._tempDistX, self._tempDistY);
}, 40);
};
this._stopScroll = function () {
self._removeEvent(document, "mousemove", self._scrollbarDrag, false);
self._removeEvent(document, "mouseup", self._stopScroll, false);
if (self._selectFunc) document.onselectstart = self._selectFunc;
else document.onselectstart = function () { return true; };
if (self._scrollTimer) window.clearInterval(self._scrollTimer);
self.eventHandler (self._tempTarget, "mouseup");
};
this._scrollUp = function (e) {this._startScroll(0, -this._scrollDist);};
this._scrollDown = function (e) {this._startScroll(0, this._scrollDist);};
this._scrollTrack = function (e) {
var curY = e.clientY + document.body.scrollTop;
this._scroll(0, curY - this._trackTop - this._handleHeight/2);
};
this._scrollHandle = function (e) {
var curY = e.clientY + document.body.scrollTop;
this._grabPoint = curY - findOffsetTop(this._yHandle);
this._addEvent(document, "mousemove", this._scrollbarDrag, false);
};
this._scroll = function (x, y) {
if (y > this._trackHeight - this._handleHeight)
y = this._trackHeight - this._handleHeight;
if (y < 0) y = 0;
this._yHandle.style.top = y +"px";
this._y = y;
this._moveContent();
};
this._moveContent = function () {
this._src.scrollTo(0, Math.round(this._y * this._ratio));
};
this.scrollBy = function (x, y) {
this._scroll(0, (-this._src._y + y)/this._ratio);
};
this.scrollTo = function (x, y) {
this._scroll(0, y/this._ratio);
};
this.swapContent = function (o, w, h) {
this._removeEvent(this._src.content, "mousewheel", this._scrollbarWheel, false);
this._src.swapContent(o, w, h);
this.reset();
};
this.reset();
};
#no-template-pager {
width: 34%;
height: 25vw;
overflow: hidden;
white-space: nowrap;
float: left;
}
.Scroller-Container {
position: relative;
width: 100%;
height: 100%;
}
#Scrollbar-Container {
position: relative;
top: 0px;
left: 0%;
background: green;
width: 1%;
height: 100%;
overflow: hidden;
}
.Scrollbar-Track {
width: 100%;
height: 100%;
position: absolute;
background: #222;
}
.Scrollbar-Handle {
position: absolute;
width: 100%;
height: 70%;
background: #8E8E8E;
-webkit-border-radius: 15px;
-moz-border-radius: 15px;
border-radius: 15px;
}
.Scrollbar-Handle:hover, .Scrollbar-Handle:active {
background: #fff;
}
#slider2 {
margin: 50px auto;
width: 60%;
height: 25vw;
background: #222;
}
#youtube {
width: 65%;
height: 25vw;
float: right;
background: blue;
}
.thumbs {
width: 100%;
height: 25%;
box-shadow: 0 -1px 0 #5A5A5A,
0 -1px 0 #707070;
}
.thumbs img {
margin: 3% 4%;
width: 80%;
height: 80%;
float: left;
}
<section id="slider2">
<div id="youtube">
</div>
<div id="no-template-pager" class="cycle-pager external">
<div class="Scroller-Container">
<!-- using thumbnail image files would be even better! -->
<div class="thumbs">
<img src="http://img.youtube.com/vi/Je7VuV9yHIw/mqdefault.jpg">
</div>
<div class="thumbs">
<img src="http://img.youtube.com/vi/uxps_fYUeJk/mqdefault.jpg">
</div>
<div class="thumbs">
<img src="http://img.youtube.com/vi/Zvr3cwbbqHU/mqdefault.jpg">
</div>
<div class="thumbs">
<img src="http://img.youtube.com/vi/Ka9xtXPD3BA/mqdefault.jpg">
</div>
<div class="thumbs">
<img src="http://img.youtube.com/vi/U8HVQXkeU8U/mqdefault.jpg">
</div>
<div class="thumbs">
<img src="http://img.youtube.com/vi/e7_UUfokexM/mqdefault.jpg">
</div>
</div>
</div>
<div id="Scrollbar-Container">
<div class="Scrollbar-Track">
<div class="Scrollbar-Handle"></div>
</div>
</div>
</section>
<script>
var scroller = null;
var scrollbar = null;
window.onload = function () {
scroller = new jsScroller(document.getElementById("no-template-pager"), 400, 200);
scrollbar = new jsScrollbar (document.getElementById("Scrollbar-Container"), scroller, true);
}
</script>
Link to CodePen 1. and to Javascript 2.:
[1]: http://codepen.io/psairidas/pen/RaVwzw
[2]: http://www.n-son.com/scripts/jsScrolling/jsScrollbar.html
You should probably set a max-height or max-width in pixels, so that it will resize but once it hits that max-height or max-width it won't get any smaller. Then if you want it to scroll, you can set overflow: scroll or overflow: auto (auto is generally recommended).
I found this game online and am trying to get it to run from my desktop. Is there something special that a person has to do with the URL's or images to make the file recognize were everything is running and located at. I have all of the files and .png files in one folder and on the same level.
I would think that I should see the game on the screen. It is like a left to right horizontal scroll-er with enemy ships that come out of the right side of the screen and the main ship is on the right side of the screen. (Similar to that of the old style defender game)
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="app.css">
</head>
<body>
<div id="game-over-overlay"></div>
<div id="game-over">
<h1>GAME OVER</h1>
<button id="play-again">Play Again</button>
</div>
<div class="wrapper">
<div id="instructions">
<div>
move with <span class="key">arrows</span> or <span class="key">wasd</span>
</div>
<div>
shoot with <span class="key">space</span>
</div>
</div>
<div id="score"></div>
</div>
<script type="text/javascript" src="resources.js"></script>
<script type="text/javascript" src="input.js"></script>
<script type="text/javascript" src="sprite.js"></script>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
sprite.js
(function() {
function Sprite(url, pos, size, speed, frames, dir, once) {
this.pos = pos;
this.size = size;
this.speed = typeof speed === 'number' ? speed : 0;
this.frames = frames;
this._index = 0;
this.url = url;
this.dir = dir || 'horizontal';
this.once = once;
};
Sprite.prototype = {
update: function(dt) {
this._index += this.speed*dt;
},
render: function(ctx) {
var frame;
if(this.speed > 0) {
var max = this.frames.length;
var idx = Math.floor(this._index);
frame = this.frames[idx % max];
if(this.once && idx >= max) {
this.done = true;
return;
}
}
else {
frame = 0;
}
var x = this.pos[0];
var y = this.pos[1];
if(this.dir == 'vertical') {
y += frame * this.size[1];
}
else {
x += frame * this.size[0];
}
ctx.drawImage(resources.get(this.url),
x, y,
this.size[0], this.size[1],
0, 0,
this.size[0], this.size[1]);
}
};
window.Sprite = Sprite;
resources.js
(function() {
var resourceCache = {};
var loading = [];
var readyCallbacks = [];
// Load an image url or an array of image urls
function load(urlOrArr) {
if(urlOrArr instanceof Array) {
urlOrArr.forEach(function(url) {
_load(url);
});
}
else {
_load(urlOrArr);
}
}
function _load(url) {
if(resourceCache[url]) {
return resourceCache[url];
}
else {
var img = new Image();
img.onload = function() {
resourceCache[url] = img;
if(isReady()) {
readyCallbacks.forEach(function(func) { func(); });
}
};
resourceCache[url] = false;
img.src = url;
}
}
function get(url) {
return resourceCache[url];
}
function isReady() {
var ready = true;
for(var k in resourceCache) {
if(resourceCache.hasOwnProperty(k) &&
!resourceCache[k]) {
ready = false;
}
}
return ready;
}
function onReady(func) {
readyCallbacks.push(func);
}
window.resources = {
load: load,
get: get,
onReady: onReady,
isReady: isReady
};
input.js
(function() {
var pressedKeys = {};
function setKey(event, status) {
var code = event.keyCode;
var key;
switch(code) {
case 32:
key = 'SPACE'; break;
case 37:
key = 'LEFT'; break;
case 38:
key = 'UP'; break;
case 39:
key = 'RIGHT'; break;
case 40:
key = 'DOWN'; break;
default:
key = String.fromCharCode(code);
}
pressedKeys[key] = status;
}
document.addEventListener('keydown', function(e) {
setKey(e, true);
});
document.addEventListener('keyup', function(e) {
setKey(e, false);
});
window.addEventListener('blur', function() {
pressedKeys = {};
});
window.input = {
isDown: function(key) {
return pressedKeys[key.toUpperCase()];
}
};
apps.js
// A cross-browser requestAnimationFrame
// See https://hacks.mozilla.org/2011/08/animating-with-javascript-from-setinterval-to-requestanimationframe/
var requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback){
window.setTimeout(callback, 1000 / 60);
};
})();
// Create the canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 512;
canvas.height = 480;
document.body.appendChild(canvas);
// The main game loop
var lastTime;
function main() {
var now = Date.now();
var dt = (now - lastTime) / 1000.0;
update(dt);
render();
lastTime = now;
requestAnimFrame(main);
};
function init() {
terrainPattern = ctx.createPattern(resources.get('terrain.png'), 'repeat');
document.getElementById('play-again').addEventListener('click', function() {
reset();
});
reset();
lastTime = Date.now();
main();
}
resources.load([
'sprites.png',
'terrain.png'
]);
resources.onReady(init);
// Game state
var player = {
pos: [0, 0],
sprite: new Sprite('sprites.png', [0, 0], [39, 39], 16, [0, 1])
};
var bullets = [];
var enemies = [];
var explosions = [];
var lastFire = Date.now();
var gameTime = 0;
var isGameOver;
var terrainPattern;
var score = 0;
var scoreEl = document.getElementById('score');
// Speed in pixels per second
var playerSpeed = 200;
var bulletSpeed = 500;
var enemySpeed = 100;
// Update game objects
function update(dt) {
gameTime += dt;
handleInput(dt);
updateEntities(dt);
// It gets harder over time by adding enemies using this
// equation: 1-.993^gameTime
if(Math.random() < 1 - Math.pow(.993, gameTime)) {
enemies.push({
pos: [canvas.width,
Math.random() * (canvas.height - 39)],
sprite: new Sprite('sprites.png', [0, 78], [80, 39],
6, [0, 1, 2, 3, 2, 1])
});
}
checkCollisions();
scoreEl.innerHTML = score;
};
function handleInput(dt) {
if(input.isDown('DOWN') || input.isDown('s')) {
player.pos[1] += playerSpeed * dt;
}
if(input.isDown('UP') || input.isDown('w')) {
player.pos[1] -= playerSpeed * dt;
}
if(input.isDown('LEFT') || input.isDown('a')) {
player.pos[0] -= playerSpeed * dt;
}
if(input.isDown('RIGHT') || input.isDown('d')) {
player.pos[0] += playerSpeed * dt;
}
if(input.isDown('SPACE') && !isGameOver && Date.now() - lastFire > 100) {
var x = player.pos[0] + player.sprite.size[0] / 2;
var y = player.pos[1] + player.sprite.size[1] / 2;
bullets.push({ pos: [x, y],
dir: 'forward',
sprite: new Sprite('sprites.png', [0, 39], [18, 8]) });
bullets.push({ pos: [x, y],
dir: 'up',
sprite: new Sprite('sprites.png', [0, 50], [9, 5]) });
bullets.push({ pos: [x, y],
dir: 'down',
sprite: new Sprite('sprites.png', [0, 60], [9, 5]) });
lastFire = Date.now();
}
}
function updateEntities(dt) {
// Update the player sprite animation
player.sprite.update(dt);
// Update all the bullets
for(var i=0; i<bullets.length; i++) {
var bullet = bullets[i];
switch(bullet.dir) {
case 'up': bullet.pos[1] -= bulletSpeed * dt; break;
case 'down': bullet.pos[1] += bulletSpeed * dt; break;
default:
bullet.pos[0] += bulletSpeed * dt;
}
// Remove the bullet if it goes offscreen
if(bullet.pos[1] < 0 || bullet.pos[1] > canvas.height ||
bullet.pos[0] > canvas.width) {
bullets.splice(i, 1);
i--;
}
}
// Update all the enemies
for(var i=0; i<enemies.length; i++) {
enemies[i].pos[0] -= enemySpeed * dt;
enemies[i].sprite.update(dt);
// Remove if offscreen
if(enemies[i].pos[0] + enemies[i].sprite.size[0] < 0) {
enemies.splice(i, 1);
i--;
}
}
// Update all the explosions
for(var i=0; i<explosions.length; i++) {
explosions[i].sprite.update(dt);
// Remove if animation is done
if(explosions[i].sprite.done) {
explosions.splice(i, 1);
i--;
}
}
}
// Collisions
function collides(x, y, r, b, x2, y2, r2, b2) {
return !(r <= x2 || x > r2 ||
b <= y2 || y > b2);
}
function boxCollides(pos, size, pos2, size2) {
return collides(pos[0], pos[1],
pos[0] + size[0], pos[1] + size[1],
pos2[0], pos2[1],
pos2[0] + size2[0], pos2[1] + size2[1]);
}
function checkCollisions() {
checkPlayerBounds();
// Run collision detection for all enemies and bullets
for(var i=0; i<enemies.length; i++) {
var pos = enemies[i].pos;
var size = enemies[i].sprite.size;
for(var j=0; j<bullets.length; j++) {
var pos2 = bullets[j].pos;
var size2 = bullets[j].sprite.size;
if(boxCollides(pos, size, pos2, size2)) {
// Remove the enemy
enemies.splice(i, 1);
i--;
// Add score
score += 100;
// Add an explosion
explosions.push({
pos: pos,
sprite: new Sprite('sprites.png',
[0, 117],
[39, 39],
16,
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
null,
true)
});
// Remove the bullet and stop this iteration
bullets.splice(j, 1);
break;
}
}
if(boxCollides(pos, size, player.pos, player.sprite.size)) {
gameOver();
}
}
}
function checkPlayerBounds() {
// Check bounds
if(player.pos[0] < 0) {
player.pos[0] = 0;
}
else if(player.pos[0] > canvas.width - player.sprite.size[0]) {
player.pos[0] = canvas.width - player.sprite.size[0];
}
if(player.pos[1] < 0) {
player.pos[1] = 0;
}
else if(player.pos[1] > canvas.height - player.sprite.size[1]) {
player.pos[1] = canvas.height - player.sprite.size[1];
}
}
// Draw everything
function render() {
ctx.fillStyle = terrainPattern;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Render the player if the game isn't over
if(!isGameOver) {
renderEntity(player);
}
renderEntities(bullets);
renderEntities(enemies);
renderEntities(explosions);
};
function renderEntities(list) {
for(var i=0; i<list.length; i++) {
renderEntity(list[i]);
}
}
function renderEntity(entity) {
ctx.save();
ctx.translate(entity.pos[0], entity.pos[1]);
entity.sprite.render(ctx);
ctx.restore();
}
// Game over
function gameOver() {
document.getElementById('game-over').style.display = 'block';
document.getElementById('game-over-overlay').style.display = 'block';
isGameOver = true;
}
// Reset game to original state
function reset() {
document.getElementById('game-over').style.display = 'none';
document.getElementById('game-over-overlay').style.display = 'none';
isGameOver = false;
gameTime = 0;
score = 0;
enemies = [];
bullets = [];
player.pos = [50, canvas.height / 2];
app.css
html, body {
margin: 0;
padding: 0;
background-color: #151515;
}
canvas {
display: block;
margin: auto;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.wrapper {
width: 512px;
margin: 0 auto;
margin-top: 2em;
}
#instructions {
float: left;
font-family: sans-serif;
color: #757575;
}
#score {
float: right;
color: white;
font-size: 2em;
}
.key {
color: #aaffdd;
}
#game-over, #game-over-overlay {
margin: auto;
width: 512px;
height: 480px;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
display: none;
}
#game-over-overlay {
background-color: black;
opacity: .5;
}
#game-over {
height: 200px;
text-align: center;
color: white;
}
#game-over h1 {
font-size: 3em;
font-family: sans-serif;
}
#game-over button {
font-size: 1.5em;
}
Here is the original game link
http://jlongster.com/Making-Sprite-based-Games-with-Canvas
If someone could put up a fiddle to see why it is not working it would be most appreciated.
Errors from the console
Uncaught SyntaxError: Unexpected end of input resources.js:61
Uncaught SyntaxError: Unexpected end of input input.js:43
Uncaught SyntaxError: Unexpected end of input sprite.js:54
Uncaught SyntaxError: Unexpected end of input app.js:302
Are you running this on a webserver? The way that you phrased it makes me think you you downloaded those files and just double-clicked index.html.
You need to download something like https://www.apachefriends.org/index.html and start the Apache service up, then put your files in the /xampp/htdocs/ folder... then goto
http://localhost/index.html
to get it to load.
So im attempting to use lulu's CCV JavaScript library and this code example seen here that draws glasses over a detected face: enter link description here
But instead of drawing glasses I would like to be able to detect the face, and draw a rectangle around it, then save it in the web browser as a variable.
In the face.html file there is a line which I believe draws the glasses to the detected face
for (i = App.comp.length; i--; ) {
ctx.strokeRect(App.glasses, (App.comp[i].x - w / 2) * m, (App.comp[i].y - w / 2) * m, (App.comp[i].width + w) * m, (App.comp[i].height + w) * m);
}
}
};
I have tried replaced that line with this code snippet:
ctx.strokeRect(comp[i].x, comp[i].y, comp[i].width, comp[i].height);
It does draw a rectangle, but a small one in the corner of the screen. I'm lost lost as where to go from here.
The entire code for the html page is seen here:
<pre>
<!DOCTYPE html>
<html lang="en">
<!-- Adapted to work with the getUserMedia API using code from http://wesbos.com/html5-video-face-detection-canvas-javascript/ -->
<head>
<meta charset="utf-8">
<title>HTML5 Face Detection - JavaScript getUserMedia API and Groucho Marx glasses!</title>
<style>
body {
font-family: sans-serif;
font-size: 17px;
line-height: 24px;
color: #fff;
width: 100%;
height: 100%;
margin: 0;
text-align: center;
background-color: #111;
}
#info {
position: absolute;
width: 100%;
height: 30px;
top: 50%;
margin-top: -15px;
}
#output {
width: auto;
height: 100%;
background: black;
-webkit-transform: scale(-1, 1);
}
</style>
</head>
<body>
<p id="info">Please allow access to your camera!</p>
<canvas id="output"></canvas>
<script src="ccv.js"></script>
<script src="face.js"></script>
<script>
// requestAnimationFrame shim
(function() {
var i = 0,
lastTime = 0,
vendors = ['ms', 'moz', 'webkit', 'o'];
while (i < vendors.length && !window.requestAnimationFrame) {
window.requestAnimationFrame = window[vendors[i] + 'RequestAnimationFrame'];
i++;
}
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime(),
timeToCall = Math.max(0, 1000 / 60 - currTime + lastTime),
id = setTimeout(function() { callback(currTime + timeToCall); }, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
}
}());
var App = {
start: function(stream) {
App.video.addEventListener('canplay', function() {
App.video.removeEventListener('canplay');
setTimeout(function() {
App.video.play();
App.canvas.style.display = 'inline';
App.info.style.display = 'none';
App.canvas.width = App.video.videoWidth;
App.canvas.height = App.video.videoHeight;
App.backCanvas.width = App.video.videoWidth / 4;
App.backCanvas.height = App.video.videoHeight / 4;
App.backContext = App.backCanvas.getContext('2d');
var w = 300 / 4 * 0.8,
h = 270 / 4 * 0.8;
App.comp = [{
x: (App.video.videoWidth / 4 - w) / 2,
y: (App.video.videoHeight / 4 - h) / 2,
width: w,
height: h,
}];
App.drawToCanvas();
}, 500);
}, true);
var domURL = window.URL || window.webkitURL;
App.video.src = domURL ? domURL.createObjectURL(stream) : stream;
},
denied: function() {
App.info.innerHTML = 'Camera access denied!<br>Please reload and try again.';
},
error: function(e) {
if (e) {
console.error(e);
}
App.info.innerHTML = 'Please go to about:flags in Google Chrome and enable the "MediaStream" flag.';
},
drawToCanvas: function() {
requestAnimationFrame(App.drawToCanvas);
var video = App.video,
ctx = App.context,
backCtx = App.backContext,
m = 4,
w = 4,
i,
comp;
ctx.drawImage(video, 0, 0, App.canvas.width, App.canvas.height);
backCtx.drawImage(video, 0, 0, App.backCanvas.width, App.backCanvas.height);
comp = ccv.detect_objects(App.ccv = App.ccv || {
canvas: App.backCanvas,
cascade: cascade,
interval: 4,
min_neighbors: 1
});
if (comp.length) {
App.comp = comp;
}
for (i = App.comp.length; i--; ) {
ctx.strokeRect(App.glasses, (App.comp[i].x - w / 2) * m, (App.comp[i].y - w / 2) * m, (App.comp[i].width + w) * m, (App.comp[i].height + w) * m);
}
}
};
App.glasses = new Image();
App.glasses.src = 'glasses.png';
App.init = function() {
App.video = document.createElement('video');
App.backCanvas = document.createElement('canvas');
App.canvas = document.querySelector('#output');
App.canvas.style.display = 'none';
App.context = App.canvas.getContext('2d');
App.info = document.querySelector('#info');
navigator.getUserMedia_ = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
try {
navigator.getUserMedia_({
video: true,
audio: false
}, App.start, App.denied);
} catch (e) {
try {
navigator.getUserMedia_('video', App.start, App.denied);
} catch (e) {
App.error(e);
}
}
App.video.loop = App.video.muted = true;
App.video.load();
};
App.init();
</script>
</body>
</html>
</pre>
Any ideas?
var x_offset = 0, y_offset = 0, x_scale = 1, y_scale = 1;
if (App.video.Width * App.video.Height > localVideo.videoWidth * localVideo.clientHeight) {
x_offset = (localVideo.clientWidth - localVideo.clientHeight * localVideo.videoWidth / localVideo.videoHeight) / 2;
} else {
y_offset = (localVideo.clientHeight - localVideo.clientWidth * localVideo.videoHeight / localVideo.videoWidth) / 2;
}
x_scale = (localVideo.clientWidth - x_offset * 2) / localVideo.videoWidth;
y_scale = (localVideo.clientHeight - y_offset * 2) / localVideo.videoHeight;
for (var i = 0; i < comp.length; i++) {
comp[i].x = comp[i].x * x_scale + x_offset;
comp[i].y = comp[i].y * y_scale + y_offset;
comp[i].width = comp[i].width * x_scale;
comp[i].height = comp[i].height * y_scale;
and then use the line
ctx.strokeRect(comp[i].x, comp[i].y, comp[i].width, comp[i].height);
replace all localvideo.clientwidth by App.video.width and ocalvideo.clientheight by App.video.height