how to make javascript game touch friendly? - javascript

I created flappy bird by following a youtube tutorial. Inside Bird.js there is a function called handleJump, inside that function when i put "Space", the bird jumps whenever i press space key on keyboard, but when i change it to "touchstart" the bird doesn't jump when i touch the screen! what am i doing wrong? what should i do?
The main page ( f.js ):
import { updateBird, setupBird, getBirdRect } from "./Bird.js";
import {
updatePipes,
setupPipes,
getPassedPipesCount,
getPipesRects,
} from "./Pipe.js";
//document.addEventListener("keypress", handleStart, { once: true });
document.addEventListener("touchstart", handleStart, { once: true });
const title = document.querySelector("[data-title]");
const subtitle = document.querySelector("[data-subtitle]");
let lastTime;
function updateLoop(time) {
if (lastTime == null) {
lastTime = time;
window.requestAnimationFrame(updateLoop);
return;
}
const delta = time - lastTime;
updateBird(delta);
updatePipes(delta);
if (checkLose()) return handleLose();
lastTime = time;
window.requestAnimationFrame(updateLoop);
}
function checkLose() {
const birdRect = getBirdRect();
const insidePipe = getPipesRects().some((rect) =>
isCollision(birdRect, rect)
);
const outsideWorld = birdRect.top < 0 || birdRect.bottom > window.innerHeight;
return outsideWorld || insidePipe;
}
function isCollision(rect1, rect2) {
return (
rect1.left < rect2.right &&
rect1.top < rect2.bottom &&
rect1.right > rect2.left &&
rect1.bottom > rect2.top
);
}
function handleStart() {
title.classList.add("hide");
setupBird();
setupPipes();
lastTime = null;
window.requestAnimationFrame(updateLoop);
}
function handleLose() {
setTimeout(() => {
title.classList.remove("hide");
subtitle.classList.remove("hide");
subtitle.textContent = `${getPassedPipesCount()} Pipes`;
document.addEventListener("touchstart", handleStart, { once: true });
}, 100);
}
Bird.js :
const birdElem = document.querySelector("[data-bird");
const BIRD_SPEED = 0.5;
const JUMP_DURATION = 120;
let timeSinceLastJump = Number.POSITIVE_INFINITY;
export function setupBird() {
setTop(window.innerHeight / 2);
document.removeEventListener("touchstart", handleJump); //keydown
document.addEventListener("touchstart", handleJump); //keydown
}
export function updateBird(delta) {
if (timeSinceLastJump < JUMP_DURATION) {
setTop(getTop() - BIRD_SPEED * delta);
} else {
setTop(getTop() + BIRD_SPEED * delta);
}
timeSinceLastJump += delta;
}
export function getBirdRect() {
return birdElem.getBoundingClientRect();
}
function setTop(top) {
birdElem.style.setProperty("--bird-top", top);
}
function getTop() {
return parseFloat(getComputedStyle(birdElem).getPropertyValue("--bird-top"));
}
function handleJump(e) {
if (e.code !== "touchstart") return;
timeSinceLastJump = 0;
}

I fixed it by removing the return
Before:
function handleJump(e) {
if (e.code !== "touchstart") return;
timeSinceLastJump = 0;
}
After:
function handleJump(e) {
if (e.code !== "touchstart");
timeSinceLastJump = 0;
}

Related

Changing photos in the gallery using touchMove and click event

I'm building a website and I have a problem in one of the steps. I display the photo gallery, after click the button the photo resize to the whole page, then I use the buttons to move the previous and next photos, everything works. I want to add functionality on a mobile device in swapping photo, but I have a problem with that.
If I select photo [2] I can only scroll pictures forward [3] and back [1]. I can't even display the selected photo[2].
Can someone help and point out what I'm doing wrong?
I’ve just started learning JavaScript.
[1]: https://codepen.io/AdamXodeo/pen/rNrgmom
https://codepen.io/AdamXodeo/pen/rNrgmom
const photos = Array.from(document.querySelectorAll(".gallery_item img"));
const popup = document.querySelector(".popup");
const popup_close = document.querySelector(".popup_close");
const popup_img = document.querySelector(".popup_img");
const arrow_left = document.querySelector(".popup_arrow--left");
const arrow_right = document.querySelector(".popup_arrow--right");
let currentImgIndex=0;
let isDragging=false;
let startPos=0;
let currentTranslate=0;
let prevTranslate=0;
let animationID=0;
photos.forEach((photo, index) => {
const showPopup = (e) => {
popup.classList.remove("hidden");
popup_img.src = e.target.src;
currentImgIndex = index;
};
photo.addEventListener("click", showPopup);
// touch events
popup_img.addEventListener("touchstart", touchStart(index));
popup_img.addEventListener("touchend", touchEnd);
popup_img.addEventListener("touchmove", touchMove);
});
const showNextImg = () => {
if (currentImgIndex === photos.length - 1) {
currentImgIndex = 0;
} else {
currentImgIndex++;
}
popup_img.src = photos[currentImgIndex].src;
};
const showPreviousImg = () => {
if (currentImgIndex === 0) {
currentImgIndex = photos.length - 1;
} else {
currentImgIndex--;
}
popup_img.src = photos[currentImgIndex].src;
};
const closePopup = () => {
popup.classList.add("fade-out");
setTimeout(() => {
popup.classList.add("hidden");
popup.classList.remove("fade-out");
}, 300);
};
document.addEventListener("keydown", (e) => {
if (!popup.classList.contains("hidden")) {
if (e.code === "ArrowRight" || e.keyCode === 39) {
showNextImg();
}
if (e.code === "ArrowLeft" || e.keyCode === 37) {
showPreviousImg();
}
if (e.code === "Escape" || e.keyCode === 27) {
closePopup();
}
}
});
popup_close.addEventListener("click", closePopup);
arrow_right.addEventListener("click", showNextImg);
arrow_left.addEventListener("click", showPreviousImg);
function touchStart(index){
return function (event) {
currentImgIndex = index;
startPos = getPositionX(event);
isDragging = true;
popup.classList.add("grabbing");
}
}
function touchMove(event){
if(isDragging){
const currentPosition = getPositionX(event);
currentTranslate = prevTranslate + currentPosition - startPos;
}
}
function touchEnd(){
isDragging = false;
const movedBy = currentTranslate - prevTranslate;
if(movedBy < -30 && currentImgIndex < photos.length - 1) currentImgIndex += 1 ;
if(movedBy > 30 && currentImgIndex > 0) currentImgIndex -= 1;
changePhotoByIndex();
popup.classList.remove("grabbing");
}
function getPositionX(event){
return event.type.includes("mouse") ? event.pageX : event.touches[0].clientX;
}
function animation() {
if (isDragging) requestAnimationFrame(animation);
}
function changePhotoByIndex() {
popup_img.src = photos[currentImgIndex].src;
prevTranslate = currentTranslate;
}
const prevButton = document.querySelector('#prev');
const nextButton = document.querySelector('#next');
const images = document.querySelectorAll('.gallery img');
let currentImage = 0;
images[currentImage].classList.add('active');
prevButton.addEventListener('click', function() {
images[currentImage].classList.remove('active');
currentImage--;
if (currentImage < 0) {
currentImage = images.length - 1;
}
images[currentImage].classList.add('active');
});
nextButton.addEventListener('click', function() {
images[currentImage].classList.remove('active');
currentImage++;
if (currentImage >= images.length) {
currentImage = 0;
}
images[currentImage].classList.add('active');
});
.gallery {
display: flex;
}
.gallery img {
width: 100%;
height: auto;
display: none;
}
.gallery .active {
display: block;
}
<div class="gallery">
<img src="https://www.pakainfo.com/wp-content/uploads/2021/09/dummy-user-image-url-300x200.jpg" class="active">
<img src="https://www.pakainfo.com/wp-content/uploads/2021/09/live-image-link-300x157.jpg">
<img src="https://www.pakainfo.com/wp-content/uploads/2021/09/online-dummy-image-url-300x201.jpg">
<img src="https://www.pakainfo.com/wp-content/uploads/2021/09/test-image-online-300x148.jpg">
<img src="https://www.pakainfo.com/wp-content/uploads/2021/09/sample-image-url-link-300x300.png">
</div>
<button id="prev">Previous</button>
<button id="next">Next</button>

Tree.js ';' expected. ts(1005)

I'm working on putting together a tutorial that I'm following on three.js and Vanilla.js I have this problem with the first line onscroll(){ is expected a ';', but doesn't make any sense to me. It seems that there is a problem with Typescript or something. I really appreciate your help.
onscroll(){
window.addEventListener("wheel", (e) => {
if (e.deltaY > 0) {
this.lerp.target += 0.01;
this.back = true;
} else {
this.lerp.target -= 0.01;
this.back = false;
}
});
}
You're missing function in front of onscroll()
function onscroll() {
window.addEventListener("wheel", (e) => {
if (e.deltaY > 0) {
this.lerp.target += 0.01;
this.back = true;
} else {
this.lerp.target -= 0.01;
this.back = false;
}
});
}
If you want to define a function without function key, you can use an arrow function
const onscroll = () => {
window.addEventListener("wheel", (e) => {
if (e.deltaY > 0) {
this.lerp.target += 0.01;
this.back = true;
} else {
this.lerp.target -= 0.01;
this.back = false;
}
});
};

Why object property undefined in another method from the same object but not undefined in other? [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 8 months ago.
Ok, so I've been struggling with something I think it's pretty simple. Not sure if it's the Babel compiler or what. So I've got this class:
export default class animateFormClass {
constructor(formSelector, buttonElement = null, currentCard = null, prevCard = null, nextCard = null) {
this.form = document.querySelector(formSelector);
this.direction = 'forward';
this.progressBar = document.getElementById('progressbar');
this.opacity = this.opacityLeft = 0;
this.buttonElement = buttonElement;
this.currentCard = currentCard;
this.prevCard = prevCard;
this.nextCard = nextCard;
}
animateForm() {
if (this.direction === 'forward') {
if (this.nextCard !== null) {
this.fadeOut = setInterval(this.fadeOutAnimation, 10);
this.updateProgressBar;
}
} else if (this.direction === 'back') {
if (this.prevCard !== null) {
this.fadeOut = setInterval(this.fadeOutAnimation, 10);
this.updateProgressBar;
}
}
}
fadeOutAnimation() {
this.opacity = this.opacity - 0.05;
console.log(this.opacity, this.currentCard);
if (this.opacity >= 0) {
this.currentCard.style.opacity = this.opacity;
} else {
this.currentCard.classList.add('d-none');
this.fadeIn = setInterval(this.fadeInAnimation, 10);
clearInterval(this.fadeOut);
}
}
fadeInAnimation() {
this.opacityLeft = this.opacityLeft + 0.1;
let cardElement;
if (this.direction === 'forward') {
cardElement = this.nextCard;
} else if (this.direction === 'back') {
cardElement = this.prevCard;
}
cardElement.classList.remove('d-none');
if (this.opacityLeft <= 1) {
cardElement.style.opacity = this.opacityLeft;
} else {
clearInterval(this.fadeIn);
}
}
updateProgressBar() {
let activeElement = this.progressBar.querySelector('.active');
let nextListElement = activeElement.nextElementSibling;
let prevListElement = activeElement.previousElementSibling;
if (this.direction === 'forward') {
if (nextListElement !== null) {
activeElement.classList.remove('active');
activeElement.classList.add('step-completed');
nextListElement.classList.add('active');
}
} else if (this.direction === 'back') {
if (prevListElement !== null) {
activeElement.classList.remove('active');
prevListElement.classList.remove('step-completed');
prevListElement.classList.add('active');
}
}
}
}
and from another file I'm importing the class like this:
import animateFormClass from './animateForm';
Ok so in this file I've got some code in which I update some of the object properties but in the animateForm() method the properties seem to be OK BUT when those same object properties are used by the other method called fadeOutAnimation() I've got this message of undefined in the this.currentCard property.
Here's the code in which I make the class instance:
if (document.getElementById('register')) {
let animate = new animateFormClass('#register');
let currentCard, prevCard, nextCard;
document.getElementById('register').addEventListener('click', function(e) {
if (e.target.classList.contains('next')) {
animate.direction = 'forward';
animate.currentCard = e.target.closest('fieldset');
animate.nextCard = animate.currentCard.nextElementSibling;
animate.animateForm();
} else if (e.target.classList.contains('prev')) {
animate.direction = 'back';
animate.animateForm(e.target);
}
});
}
I get the error when the animate.animateForm() method is called. My environment is working on a PHP web app using Laravel and using the watch task that Laravel has out of the box.
EDIT:
Thank you for your help, I was able to fix it. If anyone was wondering, I changed all the methods of the class as properties and used the arrow function syntax. So thanks again!!!
When you're doing setInterval(this.fadeOutAnimation, 10), 'this' inside 'fadeOutAnimation' is binded by window. Use setInterval(() => { this.fadeOutAnimation() }, 10); It preserves 'this' context.
Thank you for your help, I was able to fix it. If anyone was wondering, I changed all the methods of the class as properties and used the arrow function syntax. So thanks again!!!
Here's the new code:
export default class animateFormClass {
constructor(formSelector) {
this.form = document.querySelector(formSelector);
this.direction = null;
this.progressBar = document.getElementById('progressbar');
this.opacity = this.opacityLeft = 0;
this.buttonElement = null;
this.currentCard = null;
this.prevCard = null;
this.nextCard = null;
this.animateForm = (buttonElement) => {
this.buttonElement = buttonElement;
this.currentCard = this.buttonElement.closest('fieldset');
this.nextCard = this.currentCard.nextElementSibling;
this.prevCard = this.currentCard.previousElementSibling;
if(this.direction === 'forward') {
if(this.nextCard !== null) {
this.fadeOut = setInterval(() => { this.fadeOutAnimation() }, 10);
this.updateProgressBar();
}
}
else if(this.direction === 'back') {
if(this.prevCard !== null) {
this.fadeOut = setInterval(() => { this.fadeOutAnimation() }, 10);
this.updateProgressBar();
}
}
}
this.fadeOutAnimation = () => {
this.opacity = this.opacity - 0.05;
if(this.opacity >= 0) {
this.currentCard.style.opacity = this.opacity;
}
else {
this.currentCard.classList.add('d-none');
this.fadeIn = setInterval(this.fadeInAnimation, 10);
clearInterval(this.fadeOut);
}
}
this.fadeInAnimation = () => {
this.opacityLeft = this.opacityLeft + 0.1;
let cardElement;
if(this.direction === 'forward') {
cardElement = this.nextCard;
}
else if(this.direction === 'back') {
cardElement = this.prevCard;
}
cardElement.classList.remove('d-none');
if(this.opacityLeft <= 1) {
cardElement.style.opacity = this.opacityLeft;
}
else {
clearInterval(this.fadeIn);
}
}
this.updateProgressBar = () => {
let activeElement = this.progressBar.querySelector('.active');
let nextListElement = activeElement.nextElementSibling;
let prevListElement = activeElement.previousElementSibling;
if(this.direction === 'forward') {
if(nextListElement !== null) {
activeElement.classList.remove('active');
activeElement.classList.add('step-completed');
nextListElement.classList.add('active');
}
}
else if(this.direction === 'back') {
if(prevListElement !== null) {
activeElement.classList.remove('active');
prevListElement.classList.remove('step-completed');
prevListElement.classList.add('active');
}
}
}
}
}

up/down arrow scroll not working

up/down arrow scroll not working in jquery scrolify plugin.I want to do the scroll with both page up/down button and in up/down arrow button click.
page up/down arrow working fine as I expect.up/down button click not scroll as page scroll
if(e.keyCode==33 ) { //working
if(index>0) {
if(atTop()) {
e.preventDefault();
index--;
//index, instant, callbacks
animateScroll(index,false,true);
}
}
} else if(e.keyCode==34) { //working
if(index<heights.length-1) {
if(atBottom()) {
e.preventDefault();
index++;
//index, instant, callbacks
animateScroll(index,false,true);
}
}
}
if(e.keyCode==38) { //not working
if(index>0) {
if(atTop()) {
e.preventDefault();
index--;
//index, instant, callbacks
animateScroll(index,false,true);
console.log('up arrow');
}
}
} else if(e.keyCode==40) { //not working
if(index<heights.length-1) {
if(atBottom()) {
e.preventDefault();
index++;
//index, instant, callbacks
animateScroll(index,false,true);
console.log('down arrow');
}
}
}
/*!
* jQuery Scrollify
* Version 1.0.5
*
* Requires:
* - jQuery 1.7 or higher
*
* https://github.com/lukehaas/Scrollify
*
* Copyright 2016, Luke Haas
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
If section being scrolled to is an interstitialSection and the last section on page
then value to scroll to is current position plus height of interstitialSection
*/
(function (global,factory) {
"use strict";
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], function($) {
return factory($, global, global.document);
});
} else if (typeof module === 'object' && module.exports) {
// Node/CommonJS
module.exports = function( root, jQuery ) {
if ( jQuery === undefined ) {
// require('jQuery') returns a factory that requires window to
// build a jQuery instance, we normalize how we use modules
// that require this pattern but the window provided is a noop
// if it's defined (how jquery works)
if ( typeof window !== 'undefined' ) {
jQuery = require('jquery');
} else {
jQuery = require('jquery')(root);
}
}
factory(jQuery, global, global.document);
return jQuery;
};
} else {
// Browser globals
factory(jQuery, global, global.document);
}
}(typeof window !== 'undefined' ? window : this, function ($, window, document, undefined) {
"use strict";
var heights = [],
names = [],
elements = [],
overflow = [],
index = 0,
currentIndex = 0,
interstitialIndex = 1,
hasLocation = false,
timeoutId,
timeoutId2,
$window = $(window),
top = $window.scrollTop(),
scrollable = false,
locked = false,
scrolled = false,
manualScroll,
swipeScroll,
util,
disabled = false,
scrollSamples = [],
scrollTime = new Date().getTime(),
firstLoad = true,
initialised = false,
wheelEvent = 'onwheel' in document ? 'wheel' : document.onmousewheel !== undefined ? 'mousewheel' : 'DOMMouseScroll',
settings = {
//section should be an identifier that is the same for each section
section: ".section",
//sectionName: "section-name",
interstitialSection: "",
easing: "easeOutExpo",
scrollSpeed: 500,
offset : 0,
scrollbars: true,
target:"html,body",
standardScrollElements: false,
setHeights: true,
overflowScroll:true,
before:function() {},
after:function() {},
afterResize:function() {},
afterRender:function() {}
};
function animateScroll(index,instant,callbacks) {
if(currentIndex===index) {
callbacks = false;
}
if(disabled===true) {
return true;
}
if(names[index]) {
scrollable = false;
if(callbacks) {
settings.before(index,elements);
}
interstitialIndex = 1;
if(settings.sectionName && !(firstLoad===true && index===0)) {
if(history.pushState) {
try {
history.replaceState(null, null, names[index]);
} catch (e) {
if(window.console) {
console.warn("Scrollify warning: This needs to be hosted on a server to manipulate the hash value.");
}
}
} else {
window.location.hash = names[index];
}
}
if(instant) {
$(settings.target).stop().scrollTop(heights[index]);
if(callbacks) {
settings.after(index,elements);
}
} else {
locked = true;
if( $().velocity ) {
$(settings.target).stop().velocity('scroll', {
duration: settings.scrollSpeed,
easing: settings.easing,
offset: heights[index],
mobileHA: false
});
} else {
$(settings.target).stop().animate({
scrollTop: heights[index]
}, settings.scrollSpeed,settings.easing);
}
if(window.location.hash.length && settings.sectionName && window.console) {
try {
if($(window.location.hash).length) {
console.warn("Scrollify warning: There are IDs on the page that match the hash value - this will cause the page to anchor.");
}
} catch (e) {
console.warn("Scrollify warning:", window.location.hash, "is not a valid jQuery expression.");
}
}
$(settings.target).promise().done(function(){
currentIndex = index;
locked = false;
firstLoad = false;
if(callbacks) {
settings.after(index,elements);
}
});
}
}
}
function isAccelerating(samples) {
function average(num) {
var sum = 0;
var lastElements = samples.slice(Math.max(samples.length - num, 1));
for(var i = 0; i < lastElements.length; i++){
sum += lastElements[i];
}
return Math.ceil(sum/num);
}
var avEnd = average(10);
var avMiddle = average(70);
if(avEnd >= avMiddle) {
return true;
} else {
return false;
}
}
$.scrollify = function(options) {
initialised = true;
$.easing['easeOutExpo'] = function(x, t, b, c, d) {
return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
};
manualScroll = {
/*handleMousedown:function() {
if(disabled===true) {
return true;
}
scrollable = false;
scrolled = false;
},*/
handleMouseup:function() {
if(disabled===true) {
return true;
}
scrollable = true;
if(scrolled) {
//instant,callbacks
manualScroll.calculateNearest(false,true);
}
},
handleScroll:function() {
if(disabled===true) {
return true;
}
if(timeoutId){
clearTimeout(timeoutId);
}
timeoutId = setTimeout(function(){
scrolled = f;
if(scrollable===false) {
return false;
}
scrollable = false;
//instant,callbacks
manualScroll.calculateNearest(false,false);
}, 200);
},
calculateNearest:function(instant,callbacks) {
top = $window.scrollTop();
var i =1,
max = heights.length,
closest = 0,
prev = Math.abs(heights[0] - top),
diff;
for(;i<max;i++) {
diff = Math.abs(heights[i] - top);
if(diff < prev) {
prev = diff;
closest = i;
}
}
if(atBottom() || atTop()) {
index = closest;
//index, instant, callbacks
animateScroll(closest,instant,callbacks);
}
},
/*wheel scroll*/
wheelHandler:function(e) {
if(disabled===true) {
return true;
} else if(settings.standardScrollElements) {
if($(e.target).is(settings.standardScrollElements) || $(e.target).closest(settings.standardScrollElements).length) {
return true;
}
}
if(!overflow[index]) {
e.preventDefault();
}
var currentScrollTime = new Date().getTime();
e = e || window.event;
var value = e.originalEvent.wheelDelta || -e.originalEvent.deltaY || -e.originalEvent.detail;
var delta = Math.max(-1, Math.min(1, value));
//delta = delta || -e.originalEvent.detail / 3 || e.originalEvent.wheelDelta / 120;
if(scrollSamples.length > 149){
scrollSamples.shift();
}
//scrollSamples.push(Math.abs(delta*10));
scrollSamples.push(Math.abs(value));
if((currentScrollTime-scrollTime) > 200){
scrollSamples = [];
}
scrollTime = currentScrollTime;
if(locked) {
return false;
}
if(delta<0) {
if(index<heights.length-1) {
if(atBottom()) {
if(isAccelerating(scrollSamples)) {
e.preventDefault();
index++;
locked = true;
//index, instant, callbacks
animateScroll(index,false,true);
} else {
return false;
}
}
}
} else if(delta>0) {
if(index>0) {
if(atTop()) {
if(isAccelerating(scrollSamples)) {
e.preventDefault();
index--;
locked = true;
//index, instant, callbacks
animateScroll(index,false,true);
} else {
return false
}
}
}
}
},
/*end of wheel*/
keyHandler:function(e) {
if(disabled===true) {
return true;
}
if(locked===true) {
return false;
}
if(e.keyCode==33 ) {
if(index>0) {
if(atTop()) {
e.preventDefault();
index--;
//index, instant, callbacks
animateScroll(index,false,true);
}
}
} else if(e.keyCode==34) {
if(index<heights.length-1) {
if(atBottom()) {
e.preventDefault();
index++;
//index, instant, callbacks
animateScroll(index,false,true);
}
}
}
if(e.keyCode==38) {
if(index>0) {
if(atTop()) {
e.preventDefault();
index--;
//index, instant, callbacks
animateScroll(index,false,true);
console.log('up arrow');
}
}
} else if(e.keyCode==40) {
if(index<heights.length-1) {
if(atBottom()) {
e.preventDefault();
index++;
//index, instant, callbacks
animateScroll(index,false,true);
console.log('down arrow');
}
}
}
/*home, end button testing*/
if(e.keyCode==35) {
for(index=6;index<1;index--)
{
console.log("worked on end button");
}
}
else if(e.keyCode==36) {
for(index=0;intex<1;index++)
{
console.log("worked on home button");
}
}
/*home,end button end*/
},
init:function() {
if(settings.scrollbars) {
$window.on('mousedown', manualScroll.handleMousedown);
$window.on('mouseup', manualScroll.handleMouseup);
$window.on('scroll', manualScroll.handleScroll);
} else {
$("body").css({"overflow":"hidden"});
}
$window.on(wheelEvent,manualScroll.wheelHandler);
$(document).bind(wheelEvent,manualScroll.wheelHandler);
$window.on('keydown', manualScroll.keyHandler);
}
};
swipeScroll = {
touches : {
"touchstart": {"y":-1,"x":-1},
"touchmove" : {"y":-1,"x":-1},
"touchend" : false,
"direction" : "undetermined"
},
options:{
"distance" : 30,
"timeGap" : 800,
"timeStamp" : new Date().getTime()
},
touchHandler: function(event) {
if(disabled===true) {
return true;
} else if(settings.standardScrollElements) {
if($(event.target).is(settings.standardScrollElements) || $(event.target).closest(settings.standardScrollElements).length) {
return true;
}
}
var touch;
if (typeof event !== 'undefined'){
if (typeof event.touches !== 'undefined') {
touch = event.touches[0];
switch (event.type) {
case 'touchstart':
swipeScroll.touches.touchstart.y = touch.pageY;
swipeScroll.touches.touchmove.y = -1;
swipeScroll.touches.touchstart.x = touch.pageX;
swipeScroll.touches.touchmove.x = -1;
swipeScroll.options.timeStamp = new Date().getTime();
swipeScroll.touches.touchend = false;
case 'touchmove':
swipeScroll.touches.touchmove.y = touch.pageY;
swipeScroll.touches.touchmove.x = touch.pageX;
if(swipeScroll.touches.touchstart.y!==swipeScroll.touches.touchmove.y && (Math.abs(swipeScroll.touches.touchstart.y-swipeScroll.touches.touchmove.y)>Math.abs(swipeScroll.touches.touchstart.x-swipeScroll.touches.touchmove.x))) {
//if(!overflow[index]) {
event.preventDefault();
//}
swipeScroll.touches.direction = "y";
if((swipeScroll.options.timeStamp+swipeScroll.options.timeGap)<(new Date().getTime()) && swipeScroll.touches.touchend == false) {
swipeScroll.touches.touchend = true;
if (swipeScroll.touches.touchstart.y > -1) {
if(Math.abs(swipeScroll.touches.touchmove.y-swipeScroll.touches.touchstart.y)>swipeScroll.options.distance) {
if(swipeScroll.touches.touchstart.y < swipeScroll.touches.touchmove.y) {
swipeScroll.up();
} else {
swipeScroll.down();
}
}
}
}
}
break;
case 'touchend':
if(swipeScroll.touches[event.type]===false) {
swipeScroll.touches[event.type] = true;
if (swipeScroll.touches.touchstart.y > -1 && swipeScroll.touches.touchmove.y > -1 && swipeScroll.touches.direction==="y") {
if(Math.abs(swipeScroll.touches.touchmove.y-swipeScroll.touches.touchstart.y)>swipeScroll.options.distance) {
if(swipeScroll.touches.touchstart.y < swipeScroll.touches.touchmove.y) {
swipeScroll.up();
} else {
swipeScroll.down();
}
}
swipeScroll.touches.touchstart.y = -1;
swipeScroll.touches.touchstart.x = -1;
swipeScroll.touches.direction = "undetermined";
}
}
default:
break;
}
}
}
},
down: function() {
if(index<=heights.length-1) {
if(atBottom() && index<heights.length-1) {
index++;
//index, instant, callbacks
animateScroll(index,false,true);
} else {
if(Math.floor(elements[index].height()/$window.height())>interstitialIndex) {
interstitialScroll(parseInt(heights[index])+($window.height()*interstitialIndex));
interstitialIndex += 1;
} else {
interstitialScroll(parseInt(heights[index])+(elements[index].height()-$window.height()));
}
}
}
},
up: function() {
if(index>=0) {
if(atTop() && index>0) {
index--;
//index, instant, callbacks
animateScroll(index,false,true);
} else {
if(interstitialIndex>2) {
interstitialIndex -= 1;
interstitialScroll(parseInt(heights[index])+($window.height()*interstitialIndex));
} else {
interstitialIndex = 1;
interstitialScroll(parseInt(heights[index]));
}
}
}
},
init: function() {
if (document.addEventListener) {
document.addEventListener('touchstart', swipeScroll.touchHandler, false);
document.addEventListener('touchmove', swipeScroll.touchHandler, false);
document.addEventListener('touchend', swipeScroll.touchHandler, false);
}
}
};
util = {
refresh:function(withCallback) {
clearTimeout(timeoutId2);
timeoutId2 = setTimeout(function() {
sizePanels();
calculatePositions(true);
if(withCallback) {
settings.afterResize();
}
},400);
},
handleUpdate:function() {
util.refresh(false);
},
handleResize:function() {
util.refresh(true);
}
};
settings = $.extend(settings, options);
sizePanels();
calculatePositions(false);
if(true===hasLocation) {
//index, instant, callbacks
animateScroll(index,false,true);
} else {
setTimeout(function() {
//instant,callbacks
manualScroll.calculateNearest(true,false);
},200);
}
if(heights.length) {
manualScroll.init();
swipeScroll.init();
$window.on("resize",util.handleResize);
if (document.addEventListener) {
window.addEventListener("orientationchange", util.handleResize, false);
}
}
function interstitialScroll(pos) {
if( $().velocity ) {
$(settings.target).stop().velocity('scroll', {
duration: settings.scrollSpeed,
easing: settings.easing,
offset: pos,
mobileHA: false
});
} else {
$(settings.target).stop().animate({
scrollTop: pos
}, settings.scrollSpeed,settings.easing);
}
}
function sizePanels() {
var selector = settings.section;
overflow = [];
if(settings.interstitialSection.length) {
selector += "," + settings.interstitialSection;
}
$(selector).each(function(i) {
var $this = $(this);
if(settings.setHeights) {
if($this.is(settings.interstitialSection)) {
overflow[i] = false;
} else {
if(($this.css("height","auto").outerHeight()<$window.height()) || $this.css("overflow")==="hidden") {
$this.css({"height":$window.height()});
overflow[i] = false;
} else {
$this.css({"height":$this.height()});
if(settings.overflowScroll) {
overflow[i] = true;
} else {
overflow[i] = false;
}
}
}
} else {
if(($this.outerHeight()<$window.height()) || (settings.overflowScroll===false)) {
overflow[i] = false;
} else {
overflow[i] = true;
}
}
});
}
function calculatePositions(resize) {
var selector = settings.section;
if(settings.interstitialSection.length) {
selector += "," + settings.interstitialSection;
}
heights = [];
names = [];
elements = [];
$(selector).each(function(i){
var $this = $(this);
if(i>0) {
heights[i] = parseInt($this.offset().top) + settings.offset;
} else {
heights[i] = parseInt($this.offset().top);
}
if(settings.sectionName && $this.data(settings.sectionName)) {
names[i] = "#" + $this.data(settings.sectionName).replace(/ /g,"-");
} else {
if($this.is(settings.interstitialSection)===false) {
names[i] = "#" + (i + 1);
} else {
names[i] = "#";
if(i===$(selector).length-1 && i>1) {
heights[i] = heights[i-1]+parseInt($this.height());
}
}
}
elements[i] = $this;
try {
if($(names[i]).length && window.console) {
console.warn("Scrollify warning: Section names can't match IDs on the page - this will cause the browser to anchor.");
}
} catch (e) {}
if(window.location.hash===names[i]) {
index = i;
hasLocation = true;
}
});
if(true===resize) {
//index, instant, callbacks
animateScroll(index,false,false);
} else {
settings.afterRender();
}
}
function atTop() {
if(!overflow[index]) {
return true;
}
top = $window.scrollTop();
if(top>parseInt(heights[index])) {
return false;
} else {
return true;
}
}
function atBottom() {
if(!overflow[index]) {
return true;
}
top = $window.scrollTop();
if(top<parseInt(heights[index])+(elements[index].outerHeight()-$window.height())-28) {
return false;
} else {
return true;
}
}
}
function move(panel,instant) {
var z = names.length;
for(;z>=0;z--) {
if(typeof panel === 'string') {
if (names[z]===panel) {
index = z;
//index, instant, callbacks
animateScroll(z,instant,true);
}
} else {
if(z===panel) {
index = z;
//index, instant, callbacks
animateScroll(z,instant,true);
}
}
}
}
$.scrollify.move = function(panel) {
if(panel===undefined) {
return false;
}
if(panel.originalEvent) {
panel = $(this).attr("href");
}
move(panel,false);
};
$.scrollify.instantMove = function(panel) {
if(panel===undefined) {
return false;
}
move(panel,true);
};
$.scrollify.next = function() {
if(index<names.length) {
index += 1;
animateScroll(index,false,true);
}
};
$.scrollify.previous = function() {
if(index>0) {
index -= 1;
//index, instant, callbacks
animateScroll(index,false,true);
}
};
$.scrollify.instantNext = function() {
if(index<names.length) {
index += 1;
//index, instant, callbacks
animateScroll(index,true,true);
}
};
$.scrollify.instantPrevious = function() {
if(index>0) {
index -= 1;
//index, instant, callbacks
animateScroll(index,true,true);
}
};
$.scrollify.destroy = function() {
if(!initialised) {
return false;
}
if(settings.setHeights) {
$(settings.section).each(function() {
$(this).css("height","auto");
});
}
$window.off("resize",util.handleResize);
if(settings.scrollbars) {
$window.off('mousedown', manualScroll.handleMousedown);
$window.off('mouseup', manualScroll.handleMouseup);
$window.off('scroll', manualScroll.handleScroll);
}
$window.off(wheelEvent,manualScroll.wheelHandler);
$window.off('keydown', manualScroll.keyHandler);
if (document.addEventListener) {
document.removeEventListener('touchstart', swipeScroll.touchHandler, false);
document.removeEventListener('touchmove', swipeScroll.touchHandler, false);
document.removeEventListener('touchend', swipeScroll.touchHandler, false);
}
heights = [];
names = [];
elements = [];
overflow = [];
};
$.scrollify.update = function() {
if(!initialised) {
return false;
}
util.handleUpdate();
};
$.scrollify.current = function() {
return elements[index];
};
$.scrollify.disable = function() {
disabled = true;
};
$.scrollify.enable = function() {
disabled = false;
if (initialised) {
//instant,callbacks
manualScroll.calculateNearest(false,false);
}
};
$.scrollify.isDisabled = function() {
return disabled;
};
$.scrollify.setOptions = function(updatedOptions) {
if(!initialised) {
return false;
}
if(typeof updatedOptions === "object") {
settings = $.extend(settings, updatedOptions);
util.handleUpdate();
} else if(window.console) {
console.warn("Scrollify warning: Options need to be in an object.");
}
};
}));
I think you are listening wrong event. Use keydown event this will work.
working fiddle

how to programming the code in Xcalc.js

function Operator(input) {
this.operator = input;
if (!input) {
console.log("Operator has no input.");
}
this.solve = function(segment1, segment2, x) {
var v1 = segment1.coefficient;
if (segment1.type=="variable") {
v1 = x;
}
var v2 = segment2.coefficient;
if (segment2.type=="variable") {
v2 = x;
}
if (this.operator=="+") {
return new Segment(v1 + v2);
} else if (this.operator=="-") {
return new Segment(v1 - v2);
} else if (this.operator=="*") {
return new Segment(v1 * v2);
} else if (this.operator=="/") {
return new Segment(v1 / v2);
} else if (this.operator=="^") {
return new Segment(Math.pow(v1, v2));
}
};
}//Class for special functions
function MathFunction(input) {
this.f=input;
if (!input) {
console.log("Math function has no input.");
}
this.solve = function(segment) {
var v = segment.coefficient;
if (this.f=="sin") {
return new Segment(Math.sin(v));
} else if (this.f=="cos") {
return new Segment(Math.cos(v));
} else if (this.f=="tan") {
return new Segment(Math.tan(v));
} else if (this.f=="asin") {
return new Segment(Math.asin(v));
} else if (this.f=="acos") {
return new Segment(Math.acos(v));
} else if (this.f=="atan") {
return new Segment(Math.atan(v));
} else if (this.f=="abs") {
return new Segment(Math.abs(v));
}
};
}
//Class for a segment of math (a container)
function Segment(input) {
this.sections = [];
this.type="section";
this.operator=0;
this.coefficient=0;
this.mathFunction=0;
this.variable="";
var removeBrackets = function(value) {
if (!value) return "";
//While there are brackets around the string
while (value.substr(0, 1)=="(" && value.substr(value.length-1, 1)==")") { var openBrackets=1;
//See if the end bracket closes the opening bracket or not
for (var i=1; i<value.length&&openBrackets>0; i++) {
if (value.substr(i, 1)=="(") openBrackets++;
if (value.substr(i, 1)==")") openBrackets--;
}
i-=1;
//If it corresponds to different brackets, do nothing
if (openBrackets!==0 || i!=value.length-1) {
break
pue.substr(i, 1)=="(") {
openBrackets++;
} else if (value.substr(i, 1)==")") {
openBrackets--;
}
if (i==index) {
//If no brackets are open (and if the operator is actually - and not just a minus sign), break the loop.
var r=0;
if (trig=="sin") {
r=/(a)?sin/g;
} else if (trig=="cos") {
r=/(a)?cos/g;
} else if (trig=="tan") {
r=/(a)?tan/g;
} else {
return -1;
}
for (matches=r.exec(value); matches; matches=r.exec(value)) if (RegExp.$1 != "a") index=matches.index;
var inBrackets=true;
while (inBrackets && index!=-1) {
var openBrackets=0;
//Find how many brackets are opened or closed at a given point in the string
for (var i=0; i<value.length; i++) {
if (value.substr(i, 1)=="(") {
openBrackets++;
} else if (value.substr(i, 1)==")") {
openBrackets--;
}
if (i==index) {
//If no brackets are open (and if the operator is actually - and not just a minus sign), break the loop.
if (openBrackets===0) {
inBrackets=false;
break;
}
}
str+="<div class='answer'>= " + this.solve().coefficient + "</div>";
str+="</div>";
return str;
};
//constructor
if (input!==undefined) {
if (typeof(input)=="string") {
//Remove excess whitespace
input = input.replace(/\s/g, "");
//get rid of unnecessary brackets surrounding the section
input = removeBrackets(input);
//Find the last instance of each operator in the string
var addition = findLast("+", input);
var subtraction = findLast("-", input);
var division = findLast("/", input);
var exponent = findLast("^", input); //Find the first exponent, since those work in reverse
var bracket1 = findLast("(", input);
var sin = findLastTrig("sin", input);
var cos = findLastTrig("cos", input);
var tan = findLastTrig("tan", input);
var asin = findLast("asin", input);
var acos = findLast("acos", input);
var atan = findLast("atan", input);
var abs = findLast("abs", input);
var multiplication = findLast("*", input);
var multiplication2 = findMultiplicationBrackets(input); //Find brackets that are the same as multiplication
var functionMultiplication = -1;
if (sin>multiplication) functionMultiplication=sin;
if (cos>multiplication) functionMultiplication=cos;
if (tan>multiplication) functionMultiplication=tan;
if (asin>multiplication) functionMultiplication=asin;
if (acos>multiplication) functionMultiplication=acos;
if (atan>multiplication) functionMultiplication=atan;
if (abs>multiplication) functionMultiplication=abs;
//Push back each half of the equation into a section, in reverse order of operations
if (addition != -1 && (subtraction == -1 || addition>subtraction)) {
this.sections.push(new Segment(input.substring(0, addition)));
this.sections.push(new Segment(input.substring(addition+1)));
this.operator = new Operator("+");
} else if (subtraction != -1) {
if (subtraction>0) {
this.sections.push(new Segment(input.substring(0, subtraction)));
} else {
this.sections.push(new Segment(0));
}
this.sections.push(new Segment(input.substring(subtraction+1)));
this.operator = new Operator("-");
} else if (functionMultiplication >0 && functionMultiplication > multiplication && functionMultiplication > division) {
this.sections.push(new Segment(input.substring(0, functionMultiplication)));
this.sections.push(new Segment(input.substring(functionMultiplication)));
this.operator = new Operator("*");
} else if (multiplication2 != -1 && (division == -1 || multiplication>division) && (multiplication == -1 || multiplication2>multiplication)) {
this.sections.push(new Segment(input.substring(0, multiplication2)));
this.sections.push(new Segment(input.substring(multiplication2)));
this.operator = new Operator("*");
} else if (multiplication != -1 && (division == -1 || multiplication>division)) {
this.sections.push(new Segment(input.substring(0, multiplication)));
this.sections.push(new Segment(input.substring(multiplication+1)));
this.operator = new Operator("*");
} else if (division != -1) {
this.sections.push(new Segment(input.substring(0, division)));
this.sections.push(new Segment(input.substring(division+1)));
this.operator = new Operator("/");
} else if (exponent != -1) {
this.sections.push(new Segment(input.substring(0, exponent)));
this.sections.push(new Segment(input.substring(exponent+1)));
this.operator = new Operator("^");
} else if (sin != -1 && (cos == -1 || sin>cos) && (tan == -1 || sin>tan) && (asin == -1 || sin>asin) && (acos == -1 || sin>acos) && (atan == -1 || sin>atan) && (abs == -1 || sin>abs)) {
this.sections.push(new Segment(input.substring(sin+3)));
this.mathFunction = new MathFunction("sin");
this.type = "function";
} else if (cos != -1 && (tan == -1 || cos>tan) && (asin == -1 || cos>asin) && (acos == -1 || cos>acos) && (atan == -1 || cos>atan) && (abs == -1 || cos>abs)) {
this.sections.push(new Segment(input.substring(cos+3)));
this.mathFunction = new MathFunction("cos");
this.type = "function";
} else if (tan != -1 && (asin == -1 || tan>asin) && (acos == -1 || tan>acos) && (atan == -1 || tan>atan) && (abs == -1 || tan>abs)) {
this.sections.push(new Segment(input.substring(tan+3)));
this.mathFunction = new MathFunction("tan");
this.type = "function";
} else if (asin != -1 && (acos == -1 || asin>acos) && (atan == -1 || asin>atan) && (abs == -1 || asin>abs)) {
this.sections.push(new Segment(input.substring(asin+4)));
this.mathFunction = new MathFunction("asin");
this.type = "function";
} else if (acos != -1 && (atan == -1 || acos>atan) && (abs == -1 || acos>abs)) {
this.sections.push(new Segment(input.substring(acos+4)));
this.mathFunction = new MathFunction("acos");
this.type = "function";
} else if (atan != -1 && (abs == -1 || atan>abs)) {
this.sections.push(new Segment(input.substring(atan+4)));
this.mathFunction = new MathFunction("atan");
this.type = "function";
} else if (abs != -1) {
this.sections.push(new Segment(input.substring(abs+3)));
this.mathFunction = new MathFunction("abs");
this.type = "function";
} else if (bracket1 != -1) {
var openBrackets=1;
for (var i=bracket1+1; i<input.length&&openBrackets>0; i++) {
if (input.substr(i, 1)=="(") openBrackets++;
if (input.substr(i, 1)==")") openBrackets--;
}
if (openBrackets===0) {
var bracket2=i-1;
if (bracket1>0) this.sections.push(new Segment(input.substring(0, bracket1)));
if (bracket2-bracket1!=1) this.sections.push(new Segment(input.substring(bracket1+1, bracket2)));
if (bracket2!=input.length-1) this.sections.push(new Segment(input.substring(bracket2+1)));
this.operator = new Operator("*");
} else {
console.log("Brackets nesting error: " + input);
}
//If there are no operators, just push the input itself
} else {
var xLocation=input.toLowerCase().indexOf("x");
if (xLocation!=-1) {
if (xLocation>0) {
this.sections.push(new Segment(input.substring(0, xLocation)));
this.sections.push(new Segment("x"));
this.operator=new Operator("*");
} else {
this.variable="x";
this.type="variable";
}
} else {
this.coefficient = parseFloat(input);
this.type = "value";
}
}
} else if (typeof(input)=="number") {
this.coefficient = input;
this.type = "value";
}
} else {
console.log("Segment has no input.");
}
}
//One point on a graph
function Point(x, y) {
this.x = x || 0;
this.y = y || 0;
}
//MathFunction to create graphs
function Graph(value, width, height, rangeX, rangeY) {
var autoRange=false;
//Default params
if (rangeX===undefined) {
rangeX=10;
}
if (rangeY===undefined) {
autoRange = true;
}
//Properties
this.expression = new Segment(value);
this.points = [];
this.canvas = document.createElement("canvas");
this.canvas.width=width || 400;
this.canvas.height=height || 400;
this.min=undefined;
this.max=undefined;
this.x1 = 0-Math.abs(rangeX);
this.x2 = 0+Math.abs(rangeX);
this.y1 = 0-Math.abs(rangeY);
this.y2 = 0+Math.abs(rangeY);
var startMouse = new Point(0, 0);
var mousePos = new Point(0, 0);
var timer=0;
var stage=0;
var img=0;
var magnitudeX = 0;
var magnitudeY = 0;
//Gets minimum y value in the set of points
this.getMin = function() {
if (this.min===undefined) {
if (this.points.length>0) {
var min = this.points[0].y;
for (var i=1; i<this.points.length; i++) {
if (this.points[i].y<min) min = this.points[i].y;
}
this.min=min;
return min;
} else {
return 0;
}
} else {
return this.min;
}
};
//Gets maximum y value in the set of points
this.getMax = function() {
if (this.max===undefined) {
if (this.points.length>0) {
var max = this.points[0].y;
for (var i=1; i<this.points.length; i++) {
if (this.points[i].y>max) max = this.points[i].y;
}
this.max=max;
return max;
} else {
return 0;
}
} else {
return this.max;
}
};
//Updates the points and graph
this.update = function() {
var accuracy = (this.x2-this.x1)/this.canvas.width;
this.points = [];
for (var i=this.x1; i<=this.x2; i+=accuracy) {
this.points.push(new Point(i, this.expression.result(i)));
}
if (autoRange) {
if (this.getMax()-this.getMin()>100000) {
this.y1=-100;
this.y2=100;
} else {
this.y1=this.getMin()-5;
this.y2=this.getMax()+5;
}
autoRange = false;
}
magnitudeX = Math.ceil(Math.log(this.x2-this.x1));
magnitudeY = Math.ceil(Math.log(this.y2-this.y1));
this.redraw();
};
var drawAxes = function(_x1, _x2, _y1, _y2, redraw) {
stage.strokeStyle="#bdc3c7";
stage.fillStyle="#bdc3c7";
var limit=0;
var i=0;
//Draw the y axis if it is in the view
if (0>=_x1-30 && 0<=_x2+30) {
stage.lineWidth=2;
stage.beginPath();
stage.moveTo(this.canvas.width/2-(((_x2+_x1)/2)/(_x2-_x1))*this.canvas.width, 0);
stage.lineTo(this.canvas.width/2-(((_x2+_x1)/2)/(_x2-_x1))*this.canvas.width, this.canvas.height);
stage.closePath();
stage.stroke();
stage.textAlign = "right";
stage.textBaseline="middle";
stage.lineWidth=1;
limit = (Math.abs(_y2)>Math.abs(_y1))?Math.abs(_y2):Math.abs(_y1);
for (i=0; i<=limit; i+=Math.pow(10, Math.floor(Math.log(_y2-_y1) / Math.LN10))/4) {
if (i===0) continue;
if (i<=_y2+50) {
if (redraw || (i>=this.y2-50)) {
stage.beginPath();
stage.moveTo(this.canvas.width/2-(((_x2+_x1)/2)/(_x2-_x1))*this.canvas.width-5, this.canvas.height-((i-_y1)/(_y2-_y1))*this.canvas.height);
stage.lineTo(this.canvas.width/2-(((_x2+_x1)/2)/(_x2-_x1))*this.canvas.width+5, this.canvas.height-((i-_y1)/(_y2-_y1))*this.canvas.height);
stage.closePath();
stage.stroke();
stage.fillText(""+(Math.round(i*100)/100), this.canvas.width/2-(((_x2+_x1)/2)/(_x2-_x1))*this.canvas.width-8, this.canvas.height-((i-_y1)/(_y2-_y1))*this.canvas.height);
}
}
if (i>=_y1-50) {
if (redraw || (-i<=this.y1+50)) {
stage.beginPath();
stage.moveTo(this.canvas.width/2-(((_x2+_x1)/2)/(_x2-_x1))*this.canvas.width-5, this.canvas.height-((-i-_y1)/(_y2-_y1))*this.canvas.height);
stage.lineTo(this.canvas.width/2-(((_x2+_x1)/2)/(_x2-_x1))*this.canvas.width+5, this.canvas.height-((-i-_y1)/(_y2-_y1))*this.canvas.height);
stage.closePath();
stage.stroke();
stage.fillText(""+(Math.round(-i*100)/100), this.canvas.width/2-(((_x2+_x1)/2)/(_x2-_x1))*this.canvas.width-8, this.canvas.height-((-i-_y1)/(_y2-_y1))*this.canvas.height);
}
}
}
}
//Draw the x axis if it is in the view
if (0>=_y1-50 && 0<=_y2+50) {
stage.lineWidth=2;
stage.beginPath();
stage.moveTo(0, this.canvas.height/2+(((_y2+_y1)/2)/(_y2-_y1))*this.canvas.height);
stage.lineTo(this.canvas.width, this.canvas.height/2+(((_y2+_y1)/2)/(_y2-_y1))*this.canvas.height);
stage.closePath();
stage.stroke();
stage.textAlign = "center";
stage.textBaseline="top";
stage.lineWidth=1;
limit = (Math.abs(_x2)>Math.abs(_x1))?Math.abs(_x2):Math.abs(_x1);
for (i=0; i<=limit; i+=Math.pow(10, Math.floor(Math.log(_x2-_x1) / Math.LN10))/4) {
if (i===0) continue;
if (i<=_x2+50) {
if (redraw || (i>=this.x2-50)) {
stage.beginPath();
stage.moveTo(((i-_x1)/(_x2-_x1))*this.canvas.width, this.canvas.height/2+(((_y2+_y1)/2)/(_y2-_y1))*this.canvas.height-5);
stage.lineTo(((i-_x1)/(_x2-_x1))*this.canvas.width, this.canvas.height/2+(((_y2+_y1)/2)/(_y2-_y1))*this.canvas.height+5);
stage.closePath();
stage.stroke();
stage.fillText(""+(Math.round(i*100)/100), ((i-_x1)/(_x2-_x1))*this.canvas.width, this.canvas.height/2+(((_y2+_y1)/2)/(_y2-_y1))*this.canvas.height+8);
}
}
if (i>=_x1-50) {
if (redraw || (-i<=this.x1+50)) {
stage.beginPath();
stage.moveTo(((-i-_x1)/(_x2-_x1))*this.canvas.width, this.canvas.height/2+(((_y2+_y1)/2)/(_y2-_y1))*this.canvas.height-5);
stage.lineTo(((-i-_x1)/(_x2-_x1))*this.canvas.width, this.canvas.height/2+(((_y2+_y1)/2)/(_y2-_y1))*this.canvas.height+5);
stage.closePath();
stage.stroke();
stage.fillText(""+(Math.round(-i*100)/100), ((-i-_x1)/(_x2-_x1))*this.canvas.width, this.canvas.height/2+(((_y2+_y1)/2)/(_y2-_y1))*this.canvas.height+8);
}
}
}
}
}.bind(this);
//Updates the canvas
this.redraw = function() {
if (this.points.length>1) {
stage.clearRect(0, 0, this.canvas.width, this.canvas.height);
stage.lineCap="round";
var offsetY = -this.y1;
drawAxes(this.x1, this.x2, this.y1, this.y2, true);
//Draw all the points
stage.strokeStyle="#2980b9";
stage.lineWidth=1;
stage.beginPath();
stage.moveTo(0, this.canvas.height-((this.points[0].y+offsetY)/(this.y2-this.y1))*this.canvas.height);
for (var i=1; i<this.points.length; i++) {
if (Math.abs((this.canvas.height-((this.points[i].y+offsetY)/(this.y2-this.y1))*this.canvas.height)-(this.canvas.height-((this.points[i-1].y+offsetY)/(this.y2-this.y1))*this.canvas.height))<=this.canvas.height) {
stage.lineTo((i/this.points.length)*this.canvas.width, this.canvas.height-((this.points[i].y+offsetY)/(this.y2-this.y1))*this.canvas.height);
}
stage.moveTo((i/this.points.length)*this.canvas.width, this.canvas.height-((this.points[i].y+offsetY)/(this.y2-this.y1))*this.canvas.height);
}
stage.closePath();
stage.stroke();
img = stage.getImageData(0, 0, this.canvas.width, this.canvas.height);
} else {
console.log("Not enough points to graph.");
}
};
this.setRange = function(_x1, _x2, _y1, _y2) {
this.x1=_x1;
this.x2=_x2;
this.y1=_y1;
this.y2=_y2;
this.update();
};
var getMousePos = function(evt) {
var rect = this.canvas.getBoundingClientRect();
var root = document.documentElement;
// return relative mouse position
var mouseX = evt.clientX - rect.left - root.scrollLeft;
var mouseY = evt.clientY - rect.top - root.scrollTop;
return new Point(mouseX, mouseY);
}.bind(this);
var startDrag = function(event) {
document.addEventListener("mousemove", dragMouse, false);
document.addEventListener("mouseup", endDrag, false);
this.canvas.removeEventListener("mouseover", startMouseOver, false);
this.canvas.removeEventListener("mousemove", moveMouse, false);
startMouse = getMousePos(event);
}.bind(this);
var redrawLine = function() {
var offsetX = ((mousePos.x-startMouse.x)/this.canvas.width)*(this.x2-this.x1);
var offsetY = ((mousePos.y-startMouse.y)/this.canvas.height)*(this.y2-this.y1);
this.setRange(this.x1-offsetX, this.x2-offsetX, this.y1+offsetY, this.y2+offsetY);
startMouse = mousePos;
}.bind(this);
var dragMouse = function(event) {
stage.clearRect(0, 0, this.canvas.width, this.canvas.height);
mousePos = getMousePos(event);
var newx1 = this.x1-((mousePos.x-startMouse.x)/this.canvas.width)*(this.x2-this.x1);
var newx2 = this.x2-((mousePos.x-startMouse.x)/this.canvas.width)*(this.x2-this.x1);
var newy1 = this.y1+((mousePos.y-startMouse.y)/this.canvas.height)*(this.y2-this.y1);
var newy2 = this.y2+((mousePos.y-startMouse.y)/this.canvas.height)*(this.y2-this.y1);
if (Math.abs(newx1-this.x1)>this.canvas.width/2 || Math.abs(newy1-this.y1)>this.canvas.height/2) {
redrawLine();
} else {
drawAxes(newx1, newx2, newy1, newy2, false);
stage.putImageData(img, mousePos.x-startMouse.x, mousePos.y-startMouse.y);
}
}.bind(this);
var endDrag = function(event) {
document.removeEventListener("mousemove", dragMouse, false);
document.removeEventListener("mouseup", endDrag, false);
this.canvas.addEventListener("mouseover", startMouseOver, false);
this.canvas.addEventListener("mousemove", moveMouse, false);
mousePos = getMousePos(event);
var offsetX = ((mousePos.x-startMouse.x)/this.canvas.width)*(this.x2-this.x1);
var offsetY = ((mousePos.y-startMouse.y)/this.canvas.height)*(this.y2-this.y1);
this.setRange(this.x1-offsetX, this.x2-offsetX, this.y1+offsetY, this.y2+offsetY);
}.bind(this);
var startMouseOver = function(event) {
this.canvas.addEventListener("mousemove", moveMouse, false);
this.canvas.addEventListener("mouseout", endMouseOver, false);
}.bind(this);
var moveMouse = function(event) {
stage.clearRect(0, 0, this.canvas.width, this.canvas.height);
stage.putImageData(img, 0, 0);
mousePos = getMousePos(event);
var offsetY = -this.y1;
//Draw the coordinate
stage.fillStyle="#2980b9";
stage.beginPath();
stage.arc(mousePos.x, this.canvas.height-((this.points[Math.round(mousePos.x/this.canvas.width*this.points.length)].y+offsetY)/(this.y2-this.y1))*this.canvas.height, 4, 0, 2*Math.PI);
stage.closePath();
stage.fill();
stage.fillStyle="#000";
stage.strokeStyle="#FFF";
stage.lineWidth=4;
stage.textBaseline="alphabetic";
var txt="(" + (Math.round(this.points[Math.round(mousePos.x/this.canvas.width*this.points.length)].x*100)/100).toFixed(2) + ", " + (Math.round(this.points[Math.round(mousePos.x/this.canvas.width*this.points.length)].y*100)/100).toFixed(2) + ")";
if (mousePos.x<stage.measureText(txt).width/2+2) {
stage.textAlign = "left";
} else if (mousePos.x>this.canvas.width-stage.measureText(txt).width/2-2) {
stage.textAlign = "right";
} else {
stage.textAlign = "center";
}
stage.strokeText(txt, mousePos.x, -10+this.canvas.height-((this.points[Math.round(mousePos.x/this.canvas.width*this.points.length)].y+offsetY)/(this.y2-this.y1))*this.canvas.height);
stage.fillText(txt, mousePos.x, -10+this.canvas.height-((this.points[Math.round(mousePos.x/this.canvas.width*this.points.length)].y+offsetY)/(this.y2-this.y1))*this.canvas.height);
}.bind(this);
var endMouseOver = function(event) {
this.canvas.removeEventListener("mousemove", moveMouse, false);
this.canvas.removeEventListener("mouseout", endMouseOver, false);
stage.clearRect(0, 0, this.canvas.width, this.canvas.height);
stage.putImageData(img, 0, 0);
}.bind(this);
//Returns the canvas element
this.getCanvas = function() {
return this.canvas;
};
//If canvas drawing is supported
if (this.canvas.getContext) {
//Get the canvas context to draw onto
stage = this.canvas.getContext("2d");
stage.font = "12px sans-serif";
this.canvas.style.backgroundColor="#FFF";
//Make points
this.update();
this.canvas.addEventListener("mousedown", startDrag, false);
this.canvas.addEventListener("mouseover", startMouseOver, false);
} else {
console.log("Canvas not supported in this browser.");
this.canvas = document.createElement("div");
this.canvas.innerHTML="Canvas is not supported in this browser.";
}
}
ntById("wrapper").className="";
var timer = setTimeout(function() {
var graph = XCalc.graphExpression(input, 400, 400);
document.getElementById("result").innerHTML = "";
document.getElementById("result").appendChild(graph.getCanvas());
document.getElementById("wrapper").className="solved";
}, 800);
} else {
document.getElementById("result").innerHTML = "<div class='error'>Error: Improperly nested brackets. Remember to only use round brackets and close all opened brackets.</div>";
}
}
window.onload = function() {
document.getElementById("simplify").addEventListener("click", simplifyText);
simplifyText();
};
<html>
<head>
<script src="exmath.js"></script>
</head>
<body>
<div id="top"><h1>Maths equation plotter</h1>
f(x) = <input type="text" value="(x+4)^2*(x-6)+60sinx" id="input" /><input type="button" value="Graph" id="simplify" />
</div>
<div id="wrapper">
<div id="result"></div>
</div>
</body>
</html>
I have some code in XCalc.js i want to support particular equation in(algebra equation,quadratic,linear,nonlinear equation) in based on equation how to programming in XCalc.js and how to show the steps based on equation so please help me to improve my code.refer this link:https://github.com/davepagurek/XCalc

Categories

Resources