I want to add Mouseover effect on my Canvas using JavaScript - javascript

Mouseover effect should be created only on specific canvas location.
In addition I've created the MousePosition function(See below).
commands for Mouseover effect should be on the MouseOverButton function.
But still It can't seems to work.
My code:
function init() {
var can=document.getElementById("SnakeCanvas");
var ctx=can.getContext("2d");
can.addEventListener('mouseover',MouseOverButton, false);
}
function getPosition(event) {
var x = new Number();
var y = new Number();
var can = document.getElementById("SnakeCanvas");
if (event.x != undefined && event.y != undefined) {
x = event.x;
y = event.y;
} else {//Firefox Compatability//
x = event.clientX + document.body.scrollLeft +
document.documentElement.scrollLeft;
y = event.clientY + document.body.scrollTop +
document.documentElement.scrollTop;
}
x -= can.offsetLeft;
y -= can.offsetTop;
return {mx:x, my:y};
}
function MouseOverButton(e) {
var can=document.getElementById("SnakeCanvas");
var ctx=can.getContext("2d");
var cell=getPosition(event);
if ((cell.mx > 854 && cell.mx < 985) && (cell.my > 256 && cell.my < 315)) {
ReplaceImage(ctx,'Images/New_Game_Hover.png',570,100,140,70);
}
}

Your event parameter in function MouseOverButton(e) is called e but you use event when passing it to getPosition:
var cell=getPosition(event); should be var cell=getPosition(e);

Try this:
function MouseOverButton(e) {
e = e || window.event; // Compatibility
var can = document.getElementById("SnakeCanvas");
var ctx = can.getContext("2d");
var cell = getPosition(e);
// ^ That was `event`, breaking your code.
if ((cell.mx > 854 && cell.mx < 985) && (cell.my > 256 && cell.my < 315)) {
ReplaceImage(ctx,'Images/New_Game_Hover.png',570,100,140,70);
}
}

Related

JavaScript: Simple subtraction returns NaN

I have a problem,
my collision detection function sometimes sets entity position to NaN.
When I open console (on chrome) position of entity and collision are valid numbers but subtracting them from each other sometimes returns NaN.
updateCollision = function(entity,rect) {
var a = entity.x - rect.x; // a = NaN , entity.x = 3117.2646499953607 , rect.x = 3296.976967651385
var b = entity.y - rect.y; // b = NaN , entity.y = 3024.105915848102 , rect.y = 3144.4270586199345
if( isNaN(a) ) // isNaN(a) = true
{
console.log("not again >:("); // but console doesn't log
}
//the code continues but its not important
screenshot of console:
So I am really confused, and don't know what to do with this issue.
I have rewriten the code one more time and I dont get the NaN values anymore
Fixed function:
updateCollision = function(entity,rect) {
var a = entity.x - rect.x;
var b = entity.y - rect.y;
var unrotatedCircleY = Math.sin((-rect.angle)/180*Math.PI)*a + Math.cos((-rect.angle)/180*Math.PI)*b +rect.y;
var unrotatedCircleX = Math.cos((-rect.angle)/180*Math.PI)*a - Math.sin((-rect.angle)/180*Math.PI)*b +rect.x;
var r = entity.collRad/2;
var closestX, closestY, aX, aY;
if (unrotatedCircleX < rect.x - rect.width/2 )
{
closestX = rect.x - rect.width/2;
aX = closestX;
}
else if (unrotatedCircleX > rect.x + rect.width/2 )
{
closestX = rect.x + rect.width/2;
aX = closestX;
}
else
{
closestX = unrotatedCircleX;
aX=rect.x;
}
if (unrotatedCircleY < rect.y - rect.height/2 )
{
closestY = rect.y - rect.height/2;
aY = closestY;
}
else if (unrotatedCircleY > rect.y + rect.height/2 )
{
closestY = rect.y + rect.height/2;
aY = closestY;
}
else
{
closestY = unrotatedCircleY;
aY = rect.y;
}
var collision = false;
var distance = getDistance(unrotatedCircleX , unrotatedCircleY, closestX, closestY);
if (distance < r)
collision = true;
else
collision = false;
if( collision && entity.type == "bullet")
{
entity.hp = 0;
}
else if(collision)
{
if( entity.type == "bullet")
{
DeleteEntity(entity);
return;
}
if( rect.collType == "solid" )
{
var positionAngle = Math.atan2( -closestY + unrotatedCircleY , -closestX + unrotatedCircleX );
var y_vel = Math.sin((-rect.angle)/180*Math.PI)*entity.x_vel + Math.cos((-rect.angle)/180*Math.PI)*entity.y_vel;
var x_vel = Math.cos((-rect.angle)/180*Math.PI)*entity.x_vel - Math.sin((-rect.angle)/180*Math.PI)*entity.y_vel;
y_vel *= 0.9;
x_vel *= 0.9;
unrotatedCircleX = closestX + Math.cos(positionAngle)*(r);
unrotatedCircleY = closestY + Math.sin(positionAngle)*(r);
a = unrotatedCircleX - rect.x;
b = unrotatedCircleY - rect.y;
entity.y = Math.sin((rect.angle)/180*Math.PI)*a + Math.cos((rect.angle)/180*Math.PI)*b + rect.y;
entity.x = Math.cos((rect.angle)/180*Math.PI)*a - Math.sin((rect.angle)/180*Math.PI)*b + rect.x;
entity.y_vel = Math.sin((rect.angle)/180*Math.PI)*x_vel + Math.cos((rect.angle)/180*Math.PI)*y_vel;
entity.x_vel = Math.cos((rect.angle)/180*Math.PI)*x_vel - Math.sin((rect.angle)/180*Math.PI)*y_vel;
}
if( rect.collType == "trigger" )
{
if( level["commandList"][rect.data].command == "tp" )
{
entity.x = level["commandList"][rect.data].x;
entity.y = level["commandList"][rect.data].y;
}
if( level["commandList"][rect.data].command == "loadLevel" )
{
levelToLoad = level["commandList"][rect.data].x;
}
}
}
But thanks for the help :)
I need to see more of your code, to see what is actually wrong, but surely NaN is a result of math operations on an undefined type, so take a good look if something is undefined

Drawing with sugar

I want to create a drawing in sugar thing, much the same as you would throw some sugar on a table and using your fingers to "erase" the sugar particles to form an image.
Does anyone know of a js type tool I can use to make this happen?
I suppose I can take a photo of a desk, and a photo of desk with some sugar on it, and then just erase the top layer, but I'm worried that this won't give a real effect.
I'm currently thinking of having a photo of desk, and then using JS to generate a lot of "sugary" particles, which I can then erase. This sounds incredibly hard to do though. Is it? Can someone point me in a good direction?
Sand or is it sugar?
An interesting problem that I had to give a little time.
This works by creating several buffers to hold grains of sand (sugar) and give them life when they need to move.
There is no way that Javascript could do a whole screen of a million plus grains so this demo cheats by only updating a very few and prioritising for new movement rather than allow older moving grains to hog CPU time.
The arrays active, sandStatus, holds the sand gains. active has the pixel address as a 32Bit int and sandStatus has age. The Array sand holds the amount of sand at each pixel and is used to calculate the shadow effect (shadow could be much better using a webGL shader) and to work out which direction sand should slide if disturbed or dropped to the surface.
the var activeMax holds the max number of active sand grains. Increase for a better effect, decrease if the sim runs to slow.
To drop sand use the right mouse button. Hold at one spot to make a pile. Left button pushes the sand about. When you hit a bigger pile the machine may lag (depending on CPU power and browser (best in firefox)).
The push function checks the sand array for any sand. If found it pushes the sand away from the center and piles it up around the edge. Some sand will fall back.
The function sprinkle adds grains of sand (one are a time by pixel coordinate or by index). The function push does the sand drawing FX. update moves the sand grains by checking surrounding pixels heights and moving grains down hill. renderPix handles rendering grains, creating the shadows and deactivating sand grains. The Array shadowChange holds the index of pixels that have had changes so that the shadows can be updated.
Bottom half of the demo is just boilerplate for mouse and canvas setup. All the code in regard to the answer is in the first half.
"use strict";
var activeMax = 2280; // this is the number of sand grains that are processed at
// at time. Increase for better looking effect. decrease
// if the machine is not keeping up with the load
var cw;
var ch;
var w; //
var h;
var canvasBuf = document.createElement("canvas");
var ctxB
var globalTime; // global to this
var pixels
var sand;
var sandToFall;
var sandToFallCount = 36000;
var shadow; // shadow pixels
var activeMax = 2280;
var active; // index of pixel for active grain
var sandStatus; // status of active grain
var shadowChange; // holds index of pixels that have a shadow change
var pixels;
var buf;
var grain = 0xFFFFFFFF;
var shadowGrain = 0x00000000;
var ready = false;
var sandReady = 0;
var nextActive = 0;
var nextActiveShadow = 0;
var onResize = function(){
cw = canvas.width;
ch = canvas.height;
w = cw; //
h = ch;
pixels = w*h;
canvasBuf.width = w;
canvasBuf.height = h;
ctxB = canvasBuf.getContext("2d");
sand = new Uint8ClampedArray(pixels);
shadow = new Uint8ClampedArray(pixels); // shadow pixels
sandToFall = new Uint32Array(sandToFallCount);
activeMax = 2280;
active = new Uint32Array(activeMax); // index of pixel for active grain
sandStatus = new Uint16Array(activeMax); // status of active grain
shadowChange= new Uint32Array(activeMax); // holds index of pixels that have a shadow change
sandStatus.fill(0); // clear
active.fill(0);
shadowChange.fill(0);
ctxB.clearRect(0,0,w,h);
ctxB.fillStyle = "white";
ctxB.font = "84px arial";
ctxB.textAlign = "center";
ctxB.globalAlpha = 0.01;
for(var i = 0; i < 12; i ++){
ctxB.fillText("Sand Doodler!",w/2 + (Math.random()-0.5)*5,h/2 + (Math.random()-0.5)*5);
}
ctxB.globalAlpha = 1;
pixels = ctxB.getImageData(0,0,w,h);
buf = new Uint32Array(pixels.data.buffer);
for(i = 0; i < buf.length; i += 3){
if(buf[i] !== 0){
var c = buf[i] >>> 24;
buf[i] = 0;
while(c > 0){
var ind = Math.floor(Math.random()*sandToFallCount);
if(sandToFall[ind] === 0){
sandToFall[ind] = i;
}
c = c >>> 1;
}
}
}
buf.fill(0);
offsets = [1,w-1,w,w+1,-w-1,-w,-w+1,-1];
shadowOffsets = [-w-1,-w,-1];
ready = true;
sandReady=0;
}
function sprinkle(x,y){
var ind;
if(y === undefined){
ind = x;
}else{
ind = x + y*w;
}
var alreadyExists = active.indexOf(ind);
var ac = nextActive;
if(alreadyExists > -1){
sand[ind] += 1;
shadow[ind] = 0;
sandStatus[alreadyExists] = 66;
}else{
active[nextActive] = ind;
sandStatus[nextActive] = 66;
shadowChange[nextActiveShadow];
nextActiveShadow = (nextActiveShadow+1)%activeMax;
nextActive = (nextActive +1)%activeMax;
sand[ind] += 1;
shadow[ind] = 0;
}
return ac;
}
var offsets = [1,w-1,w,w+1,-w-1,-w,-w+1,-1];
var offsetCount = 8;
function update(){
var min,max,minDir,maxDir,dir,start,jj,j,ind,level,i,l1;
for( i = 0; i <activeMax; i ++){
if(sandStatus[i] !== 0){
ind = active[i];
level = sand[ind];
if(level === 1){
sandStatus[i] = 1; // deactive is cant move (level ground)
}else{
min = level;
var d;
minDir = offsets[Math.floor(Math.random()*16)];
dir = null;
start = Math.floor(Math.random()*16); // start at a random direction
for(j=0;j < offsetCount; j++){
jj = offsets[(j + start)%offsetCount];
l1 = sand[ind+jj];
if(l1 < min){
min = l1;
minDir = jj;
d = (j + start)%offsetCount;
}
}
dir = null;
if(min >= level - 1){ // nowhere to move
sandStatus[i] = 1;
}else
if(min < level-1){ // move to lowest
dir = minDir
}
if(dir !== null){
var lv = level-min;
while(lv > 2){
active[i] = ind + dir;
if(sand[ind] > 1){
sand[ind] -= 2;
sprinkle(ind)
}else{
sand[ind] -=1;
}
ind = ind+dir;
sand[active[i]] += 1;
if(sand[active[i] + offsets[d]] >=level){
d+= Math.random()<0.5? 1 : offsetCount -1;
d %=offsetCount;
}
lv -= 1;
}
if(sand[ind]>0){
active[i] = ind + dir;
sand[ind] -= 1;
}
sand[active[i]] += 1;
}
}
}
}
}
var shadowOffsets = [-w-1,-w,-1];
var shadowCols = [0xFFf0f0f0,0xFFd0d0d0,0xFFb0b0b0,0xFF909090];
var shadowDist = [0xf0000000,0xd0000000,0xb0000000,0x90000000]; // shadow col no sand
// renders grains and adds shadows. Deactivates gains when they are done
function renderPix(){
var ac = 0;
for(var i = 0; i < activeMax; i ++){
if(sandStatus[i] !== 0){
ac += 1;
var ind = active[i];
buf[ind] = grain;
}
}
for(var i = 0; i < activeMax; i ++){
if(sandStatus[i] !== 0){
var ind = active[i];
var level = sand[ind];
var col =0;
if(sand[ind + shadowOffsets[0]] > level ){
col = 2;
}else
if(sand[ind + shadowOffsets[1]] > level ){
col =1;
}else
if(sand[ind + shadowOffsets[2]] > level ){
col = 1;
}
buf[ind] = grain; // add a sand grain to the image
shadow[ind] = col;
shadowChange[nextActiveShadow] = ind;
nextActiveShadow = (nextActiveShadow + 1)%activeMax;
var c = 4;
while(c > 0){
c-=1;
ind += w + 1;
var s = sand[ind];
var dif = level - s;
if(dif > 0){
c-= dif;
}
shadow[ind] += 1;
shadowChange[nextActiveShadow] = ind;
nextActiveShadow = (nextActiveShadow + 1)%activeMax;
}
sandStatus[i] -= 1;
if(sandStatus[i] === 1){
sandStatus[i] = 0;
active[i] = 0;
}
}
}
// add calculated shadows
for(var i = 0; i < activeMax; i ++){
if(shadowChange[i] !== 0){
var ind = shadowChange[i];
var s = shadow[ind] <4 ? shadow[ind]-1:3;
if(sand[ind] > 0){
buf[ind]=shadowCols[s];
}else{
buf[ind]=shadowDist[s];
}
shadowChange[i] = 0;
}
}
}
// push sand about
function push(x,y,radius){
var iyy,iny
var rr = radius * radius ;
x = Math.floor(x);
y = Math.floor(y);
for(var iy = -radius + 1; iy < radius; iy ++){
iyy = iy * iy;
iny = (y+iy) * w;
for(var ix = -radius + 1; ix < radius; ix ++){
if(ix*ix + iyy <= rr){ // is inside radius
var ind = (x + ix) + iny;
if(sand[ind] > 0){
var dir = Math.random() * Math.PI * 2;
dir = Math.atan2(iy,ix)
var r = radius + Math.random() * radius *0.2
var xx = Math.cos(dir) * r;
var yy = Math.sin(dir) * r;
buf[ind] = 0x000000;
sand[ind] = 0;
ind = Math.floor(xx + x) + Math.floor(yy + y) * w;
sprinkle(ind);
}else{
buf[ind] = 0;
}
}
}
}
}
function showHeight(){ // for debugging only
for(var i = 0; i < sand.length; i ++){
buf[i] = 0xff000000;
var k = sand[i];
buf[i] +=(k <<16) + (k<<8) + (k);
}
}
// main update function
function display(){
if(!ready){ // only when ready
return;
}
//ctx.setTransform(1,0,0,1,0,0); // reset transform
ctx.clearRect(0,0,cw,ch);
var mx = Math.floor((mouse.x/cw)*w); // canvas buf mouse pos
var my = Math.floor((mouse.y/ch)*h);
// drop sand
if(mouse.buttonRaw & 4){
for(var i = 0; i < 120; i ++){
var dir = Math.random()*Math.PI;
var dist = ((Math.random()+Math.random()+Math.random())/3-0.5) * 62;
var x = Math.cos(dir) * dist;
var y = Math.sin(dir) * dist;
x += mx;
y += my;
x = Math.floor(x); // floor
y = Math.floor(y); // floor
sprinkle(x,y);
}
}else{
// drop sand for intro FX
if(sandReady <sandToFallCount){
for(var i = 0; i < 120; i ++){
if(sandToFall[sandReady] !== 0){
sprinkle(sandToFall[sandReady] + offsets[Math.floor(Math.random()*8)%offsets.length]);
}
sandReady += 1;
}
}
}
// push sand about.
if(mouse.buttonRaw & 1){
push(((mouse.x/cw)*w),((mouse.y/ch)*h),32); // scale mouse to canvasBuf size
}
update();
renderPix();
//showHeight();
ctxB.putImageData(pixels,0,0);
ctx.drawImage(canvasBuf,0,0,cw,ch);
}
//==================================================================================================
// The following code is support code that provides me with a standard interface to various forums.
// It provides a mouse interface, a full screen canvas, and some global often used variable
// like canvas, ctx, mouse, w, h (width and height), globalTime
// This code is not intended to be part of the answer unless specified and has been formated to reduce
// display size. It should not be used as an example of how to write a canvas interface.
// By Blindman67
const U = undefined;const RESIZE_DEBOUNCE_TIME = 100;
var canvas,ctx,mouse,createCanvas,resizeCanvas,setGlobals,globalTime=0,resizeCount = 0;
createCanvas = function () { var c,cs; cs = (c = document.createElement("canvas")).style; cs.position = "absolute"; cs.top = cs.left = "0px"; cs.zIndex = 1000; document.body.appendChild(c); return c;}
resizeCanvas = function () {
if (canvas === U) { canvas = createCanvas(); } canvas.width = window.innerWidth; canvas.height = window.innerHeight; ctx = canvas.getContext("2d");
if (typeof setGlobals === "function") { setGlobals(); } if (typeof onResize === "function"){ resizeCount += 1; setTimeout(debounceResize,RESIZE_DEBOUNCE_TIME);}
}
function debounceResize(){ resizeCount -= 1; if(resizeCount <= 0){ onResize();}}
setGlobals = function(){ cw = w = canvas.width; ch = h = canvas.height; mouse.updateBounds(); }
mouse = (function(){
function preventDefault(e) { e.preventDefault(); }
var mouse = {
x : 0, y : 0, w : 0, alt : false, shift : false, ctrl : false, buttonRaw : 0, over : false, bm : [1, 2, 4, 6, 5, 3],
active : false,bounds : null, crashRecover : null, mouseEvents : "mousemove,mousedown,mouseup,mouseout,mouseover,mousewheel,DOMMouseScroll".split(",")
};
var m = mouse;
function mouseMove(e) {
var t = e.type;
m.x = e.clientX - m.bounds.left; m.y = e.clientY - m.bounds.top;
m.alt = e.altKey; m.shift = e.shiftKey; m.ctrl = e.ctrlKey;
if (t === "mousedown") { m.buttonRaw |= m.bm[e.which-1]; }
else if (t === "mouseup") { m.buttonRaw &= m.bm[e.which + 2]; }
else if (t === "mouseout") { m.buttonRaw = 0; m.over = false; }
else if (t === "mouseover") { m.over = true; }
else if (t === "mousewheel") { m.w = e.wheelDelta; }
else if (t === "DOMMouseScroll") { m.w = -e.detail; }
if (m.callbacks) { m.callbacks.forEach(c => c(e)); }
if((m.buttonRaw & 2) && m.crashRecover !== null){ if(typeof m.crashRecover === "function"){ setTimeout(m.crashRecover,0);}}
e.preventDefault();
}
m.updateBounds = function(){
if(m.active){
m.bounds = m.element.getBoundingClientRect();
}
}
m.addCallback = function (callback) {
if (typeof callback === "function") {
if (m.callbacks === U) { m.callbacks = [callback]; }
else { m.callbacks.push(callback); }
} else { throw new TypeError("mouse.addCallback argument must be a function"); }
}
m.start = function (element, blockContextMenu) {
if (m.element !== U) { m.removeMouse(); }
m.element = element === U ? document : element;
m.blockContextMenu = blockContextMenu === U ? false : blockContextMenu;
m.mouseEvents.forEach( n => { m.element.addEventListener(n, mouseMove); } );
if (m.blockContextMenu === true) { m.element.addEventListener("contextmenu", preventDefault, false); }
m.active = true;
m.updateBounds();
}
m.remove = function () {
if (m.element !== U) {
m.mouseEvents.forEach(n => { m.element.removeEventListener(n, mouseMove); } );
if (m.contextMenuBlocked === true) { m.element.removeEventListener("contextmenu", preventDefault);}
m.element = m.callbacks = m.contextMenuBlocked = U;
m.active = false;
}
}
return mouse;
})();
function main(timer){ // Main update loop
globalTime = timer;
display(); // call demo code
requestAnimationFrame(main);
}
resizeCanvas();
mouse.start(canvas,true);
window.addEventListener("resize",resizeCanvas);
requestAnimationFrame(main);
body {
background:#49D;
}
.help {
text-align : center;
font-family : Arial,"Helvetica Neue",Helvetica,sans-serif;
font-size : 18px;
}
<div class="help">Right mouse to drop sand, left button to push it around.</div>

Using fixPageXY(e) and onmousemove() and the image wont move?

Is there something im missing here? I just want to select the image by clicking on it, it should drag with the mouse(no mouse key held down) until its clicked onto I different part of the screen. Ive used function fixPageXY(e) with a onmousemove function, followed a tutorial and still nothing.
<script type="text/javascript">
function fixPageXY(e) {
if (e.pageX == null && e.clientX != null ) {
var html = document.documentElement;
var body = document.body;
e.pageX = e.clientX + (html.scrollLeft || body && body.scrollLeft || 0);
e.pageX -= html.clientLeft || 0;
e.pageY = e.clientY + (html.scrollTop || body && body.scrollTop || 0);
e.pageY -= html.clientTop || 0;
}
}
}
document.getElementById('ball').onmousedown = function() {
this.style.position = 'absolute';
var self = this;
document.onmousemove = function(e) {
e = e || event;
fixPageXY(e);
// put ball center under mouse pointer. 25 is half of width/height
self.style.left = e.pageX-25+'px';
self.style.top = e.pageY-25+'px';
}
this.onmouseup = function() {
document.onmousemove = null;
}
}
</script>
My image is simply,
<body onload="onmousemove();onmouseup();">
<img id="ball" src="ball.png" style="width:100px;height:100px;"/>
</body>
Im using google chrome, could this be an issue? many thanks for your help in advance.
There were a few syntax errors within your code, which if you are running Chrome you can just hit F12 on your keyboard and it will bring up the console allowing you to read whatever errors may be there. Here's a fiddle with just a few tweaks made to your code that allows it to run smoothly... and by tweaks, I mean there was an extra closing bracket after defining the function and the functions you called in body onload cannot me accessed that way so I deleted that and it worked.
This code work fine :
function fixPageXY(e) {
if(e.pageX == null && e.clientX != null ) {
var html = document.documentElement, body = document.body;
e.pageX = e.clientX + (html.scrollLeft || body && body.scrollLeft || 0);
e.pageX -= html.clientLeft || 0;
e.pageY = e.clientY + (html.scrollTop || body && body.scrollTop || 0);
e.pageY -= html.clientTop || 0;
}
}
document.getElementById("ball2").onmousedown = function () {
this.style.position = "absolute";
var self = this;
document.onmousemove = function (e) {
e = e || event;
fixPageXY (e);
self.style.left = e.pageX-25+'px';
self.style.top = e.pageY-25+'px';
}
this.onmouseup = function () {
document.onmousemove = null;
}
}
document.getElementById("ball2").ondragstart = function () { return false; }

Parallax Background Positioning Scrolling

I have just developed a new parallax scrolling script. I have it working just the way I want however there is just 1 issue with it currently.
I want the script to start scrolling the background image at the y coord that is specified in the css stylesheet by default. Instead my script seems to be resetting the CSS y coord to 0 before scrolling the image. This is obviously undesired behavior.
// Parallax scripting starts here
$.prototype.jpayParallax = function(userOptions){
var _api = {};
_api.utils = {};
_api.utils.isElementInViewport = function(el){
if (typeof jQuery === "function" && el instanceof jQuery) {
el = el[0];
}
var rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
);
}
_api.utils.debounceScrollWheel = (function(){
$(function(){
var $window = $(window); //Window object
var scrollTime = 0.3; //Scroll time
var scrollDistance = 50; //Distance. Use smaller value for shorter scroll and greater value for longer scroll
$window.on("mousewheel DOMMouseScroll", function(event){
event.preventDefault();
var delta = event.originalEvent.wheelDelta/120 || -event.originalEvent.detail/3;
var scrollTop = $window.scrollTop();
var finalScroll = scrollTop - parseInt(delta*scrollDistance);
TweenMax.to($window, scrollTime, {
scrollTo : { y: finalScroll, autoKill:true },
ease: Power1.easeOut, //For more easing functions see http://api.greensock.com/js/com/greensock/easing/package-detail.html
autoKill: true,
overwrite: 5
});
});
});
})();
_api.selector = 'data-jpay-parallax';
_api.methods = {};
_api.methods.checkForVisibleParallaxEls = function(){
$('['+_api.selector+']').each(function(){
var instanceObject = $(this);
var origBgPos = $(this).css('backgroundPosition').split(' ');
var options = $(this).data('jpay-parallax');
console.log(origBgPos)
if (_api.utils.isElementInViewport(instanceObject)){
_api.methods.doParallax(instanceObject, options);
}
});
}
_api.methods.doParallax = function(instanceToManip, userOptions){
var direction = userOptions.settings.direction;
var orientation = userOptions.settings.orientation;
var speed = userOptions.settings.speed;
var type = userOptions.settings.type;
var speedInt;
var getSpeed = (function(){
if (speed){
switch(speed){
case 'slow':
speedInt = 10;
break;
case 'fast':
speedInt = 5;
break;
case 'faster':
speedInt = 1;
break;
default:
throw new TypeError('Unknown speed parameter added to module instructions');
}
}
})();
var distToTopInt = function(){
if (typeof speedInt === 'number'){
return $(window).scrollTop()/speedInt;
}
else {
return $(window).scrollTop();
}
}
var origPos = instanceToManip.css('backgroundPosition').split(' ');
var origPosX = parseInt(origPos[0]);
var origPosY = parseInt(origPos[1]);
var newPosY = origPosY += distToTopInt();
var newPosX = origPosX += distToTopInt();
if (orientation === 'vertical' && direction !== 'reverse'){
instanceToManip.css('backgroundPositionY', newPosX+'px');
}
else if (orientation === 'vertical' && direction === 'reverse'){
instanceToManip.css('backgroundPositionY', -newPosX+'px');
}
else if (orientation == 'horizontal' && direction !== 'reverse'){
instanceToManip.css('backgroundPositionX', newPosX+'px');
}
else if (orientation == 'horizontal' && direction === 'reverse'){
instanceToManip.css('backgroundPositionX', -newPosY+'px');
}
}
$(window).on('scroll', _api.methods.checkForVisibleParallaxEls)
};
$.fn.jpayParallax();
Here is the pen:
http://codepen.io/nicholasabrams/pen/OPxKXm/?editors=001
BONUS: Why does this script also mess with the css set backgroundSize property when the script never accesses it?
I am looking for advice in where in the script to cache the original CSS background image y coord value so that it becomes incremented from there instead of starting at 0px /0 for each instance. Thanks again for the help!

Trying to find javascript element's position on screen....Not working properly on webkit browsers

This is the code i'm using right now. On webkit browsers (Chrome and Safari Specifically) if the page is scrolled, it doesn't take into account the amount that page has been scrolled. I need help redesigning the function to work for Webkit browsers. And I don't want to be loading up jQuery as this will be used on a web widget and I need to keep the file size down. Thanks guys!
function __getIEVersion() {
var rv = -1; // Return value assumes failure.
if (navigator.appName == 'Microsoft Internet Explorer') {
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null)
rv = parseFloat(RegExp.$1);
}
return rv;
}
function __getOperaVersion() {
var rv = 0; // Default value
if (window.opera) {
var sver = window.opera.version();
rv = parseFloat(sver);
}
return rv;
}
var __userAgent = navigator.userAgent;
var __isIE = navigator.appVersion.match(/MSIE/) != null;
var __IEVersion = __getIEVersion();
var __isIENew = __isIE && __IEVersion >= 8;
var __isIEOld = __isIE && !__isIENew;
var __isFireFox = __userAgent.match(/firefox/i) != null;
var __isFireFoxOld = __isFireFox && ((__userAgent.match(/firefox\/2./i) != null) ||
(__userAgent.match(/firefox\/1./i) != null));
var __isFireFoxNew = __isFireFox && !__isFireFoxOld;
var __isWebKit = navigator.appVersion.match(/WebKit/) != null;
var __isChrome = navigator.appVersion.match(/Chrome/) != null;
var __isOpera = window.opera != null;
var __operaVersion = __getOperaVersion();
var __isOperaOld = __isOpera && (__operaVersion < 10);
function __parseBorderWidth(width) {
var res = 0;
if (typeof(width) == "string" && width != null && width != "" ) {
var p = width.indexOf("px");
if (p >= 0) {
res = parseInt(width.substring(0, p));
}
else {
//do not know how to calculate other values
//(such as 0.5em or 0.1cm) correctly now
//so just set the width to 1 pixel
res = 1;
}
}
return res;
}
//returns border width for some element
function __getBorderWidth(element) {
var res = new Object();
res.left = 0; res.top = 0; res.right = 0; res.bottom = 0;
if (window.getComputedStyle) {
//for Firefox
var elStyle = window.getComputedStyle(element, null);
res.left = parseInt(elStyle.borderLeftWidth.slice(0, -2));
res.top = parseInt(elStyle.borderTopWidth.slice(0, -2));
res.right = parseInt(elStyle.borderRightWidth.slice(0, -2));
res.bottom = parseInt(elStyle.borderBottomWidth.slice(0, -2));
}
else {
//for other browsers
res.left = __parseBorderWidth(element.style.borderLeftWidth);
res.top = __parseBorderWidth(element.style.borderTopWidth);
res.right = __parseBorderWidth(element.style.borderRightWidth);
res.bottom = __parseBorderWidth(element.style.borderBottomWidth);
}
return res;
}
//returns the absolute position of some element within document
function getElementAbsolutePos(element) {
var res = new Object();
res.x = 0; res.y = 0;
if (element !== null) {
if (element.getBoundingClientRect) {
var viewportElement = document.documentElement;
var box = element.getBoundingClientRect();
var scrollLeft = viewportElement.scrollLeft;
var scrollTop = viewportElement.scrollTop;
res.x = box.left + scrollLeft;
res.y = box.top + scrollTop;
}
else { //for old browsers
res.x = element.offsetLeft;
res.y = element.offsetTop;
var parentNode = element.parentNode;
var borderWidth = null;
while (offsetParent != null) {
res.x += offsetParent.offsetLeft;
res.y += offsetParent.offsetTop;
var parentTagName =
offsetParent.tagName.toLowerCase();
if ((__isIEOld && parentTagName != "table") ||
((__isFireFoxNew || __isChrome) &&
parentTagName == "td")) {
borderWidth = kGetBorderWidth
(offsetParent);
res.x += borderWidth.left;
res.y += borderWidth.top;
}
if (offsetParent != document.body &&
offsetParent != document.documentElement) {
res.x -= offsetParent.scrollLeft;
res.y -= offsetParent.scrollTop;
}
//next lines are necessary to fix the problem
//with offsetParent
if (!__isIE && !__isOperaOld || __isIENew) {
while (offsetParent != parentNode &&
parentNode !== null) {
res.x -= parentNode.scrollLeft;
res.y -= parentNode.scrollTop;
if (__isFireFoxOld || __isWebKit)
{
borderWidth =
kGetBorderWidth(parentNode);
res.x += borderWidth.left;
res.y += borderWidth.top;
}
parentNode = parentNode.parentNode;
}
}
parentNode = offsetParent.parentNode;
offsetParent = offsetParent.offsetParent;
}
}
}
var scrOfX = 0, scrOfY = 0;
if( typeof( window.pageYOffset ) == 'number' ) {
//Netscape compliant
scrOfY = window.pageYOffset;
scrOfX = window.pageXOffset;
} else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
//DOM compliant
scrOfY = document.body.scrollTop;
scrOfX = document.body.scrollLeft;
} else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
//IE6 standards compliant mode
scrOfY = document.documentElement.scrollTop;
scrOfX = document.documentElement.scrollLeft;
}
return res;
}
if (element.getBoundingClientRect) {
var viewportElement = document.documentElement;
var box = element.getBoundingClientRect();
var scrollLeft = viewportElement.scrollLeft;
var scrollTop = viewportElement.scrollTop;
res.x = box.left + scrollLeft;
res.y = box.top + scrollTop;
}
I'm concerned that this code block only uses one way of attempting to detect the scroll position. I would move the bottom block of code to the top of the function and use scrOfX/Y instead of scrollLeft and scrollTop.

Categories

Resources