I am trying to get an HTML 5 slider working. I’m trying to get it to change the value of the variable moveX. Line 52 works but that is for static. Lines 53 and 54 are what I have tried, but it just creates erratic movement. could somebody help me?
Here is a link to the page:http://hyque.com/ani/drawImageBtnFwd.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>DrawImage with Buttons</title>
</head>
<body>
<button id="startBtn">Start</button>
<button id="stopBtn">Pause</button><br />
<p>
<strong>Speed</strong>
<input id="slider1" type="range" min="1" max="10" value="0" step="1">
</p>
<canvas id="myCanvas" width="1200" height="187" style="border:1px solid #d3d3d3;">
<script>
window.onload = function() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = new Image();
img.src = "http://hyque.com/ani/adam.png";
var xPos = 0;
var moveX = 0;
var scaleSlider = document.getElementById("slider1");
ctx.drawImage(img, 0, 0, 120, 182, 0, 0, 120, 182);
//number(scaleSlider);
var el = document.getElementById('startBtn');
el.addEventListener('click', strt, false);
var el2 = document.getElementById('stopBtn');
el2.addEventListener('click', stopIt, false);
function imageXPosition() {
ctx.clearRect(0, 0, 1200, 182); // This clears the canvas
ctx.drawImage(img, xPos, 0, 120, 182, moveX, 0, 120, 182); //Draws the individual frames
xPos += 120; //adds the width
//moveX += 5;
moveX += scaleSlider.value;
//scaleSlider.onchange = function(e){moveX = e.target.value;}
//This adds 1 to the second frame
if(xPos == 120){
xPos += 1;
}
if(xPos > 841){xPos = 0;} // This resets to 0 after the las frame
if(moveX >= 1200){moveX = 0;}
}
var intStp; // declared outside the strt() function, because
function strt(){
clearInterval(intStp); //without this lin the animation will speed up eachtime you click "Start Button"
intStp = setInterval(imageXPosition, 200);
}
function stopIt(){
clearInterval(intStp);
}
}
</script>
</body>
</html>
From what I see this line is problematic:
moveX += scaleSlider.value;
scaleSlider.value returns a string.
moveX is also a string.
When the line above is called you are having something like this
"0" += "1" this results is "01"
after it "01" += "2" which results in "012" etc.
Before solving anything else make sure you use parseInt(moveX, 10);
This will allow you to continue.
Related
Lately I learned a bit about strange attractors, and I created the following programm in JS:
var ctx, clock, width, height, pixSize;
var x,y,a,b,c,d;
window.onload = function(){
start();
};
function start(random=true){
window.cancelAnimationFrame(clock);
if(random){
a = 6*Math.random()-3;
b = 6*Math.random()-3;
c = 2*Math.random()-0.5;
d = 2*Math.random()-0.5;
}
canvasSetup();
clearCanvas();
x = Math.random()-Math.random();
y = Math.random()-Math.random();
clock = requestAnimationFrame(main);
}
function save(){
var text = JSON.stringify({
a:a,
b:b,
c:c,
d:d
});
window.prompt("Copy to clipboard: Ctrl+C", text);
}
function load(){
var input = JSON.parse(window.prompt("Import Save:"));
a = input.a;
b = input.b;
c = input.c;
d = input.d;
start(false);
}
function canvasSetup(){
canvas = document.getElementById('canvas');
width = window.innerWidth-5;
height = window.innerHeight-5;
canvas.width = width;
canvas.height = height;
ctx = canvas.getContext('2d');
var min = Math.min(width,height);
var scale = min/4;
ctx.translate(width/2, height/2);
ctx.scale(scale, scale);
pixSize = 1/scale/2;
ctx.globalCompositeOperation = "lighter";
}
function clearCanvas(){
ctx.save();
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0,0,width,height);
ctx.restore();
}
function main(){
for(var i=0;i<10000;i++){
var xnew = Math.sin(y*b)+c*Math.sin(x*b);
var ynew = Math.sin(x*a)+d*Math.sin(y*a);
x = xnew;
y = ynew;
plot(x,y,"rgb(50,5,1)");
}
clock = requestAnimationFrame(main);
}
function plot(x,y,color="white"){
ctx.fillStyle = color;
ctx.fillRect(x,-y,pixSize,pixSize);
}
body {
background-color: black;
color: white;
font-family: Consolas;
font-size: 13px;
margin: 0;
padding: 0;
}
#buttons{
position: absolute;
top: 0;
left: 0;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Strange Attractor</title>
<link rel="stylesheet" href="style.css">
<script src="rules.js"></script>
<script src="script.js"></script>
</head>
<body>
<div align="center">
<canvas id="canvas"></canvas>
</div>
<div id="buttons">
<button onclick="start()">New Attractor</button><br>
<button onclick="save()">Save</button><br>
<button onclick="load()">Load</button>
</div>
</body>
</html>
It's taking 4 random Parameters (a,b,c,d) and uses the formular
var xnew = Math.sin(y*b)+c*Math.sin(x*b);
var ynew = Math.sin(x*a)+d*Math.sin(y*a);
x = xnew;
y = ynew;
for the new point. In some cases this indeed creates a fancy strange sttractor:
But in other cases I only get a single line or a few points. Is there a simple way to look at the parameters and find out, if the attrator they create will be strange?
I know, that I could save a bunch of values, compare them with each other and test in that way, if the picture might be intresting, but I'd love a different solution...
I hope you can help :)
EDIT:
To look at speccific values you can simply use the save and load buttons in the js sketch above...
I tried to make it so that when my 'Player' reaches a jumpDistance of 50, it falls down, so he makes a small ' jump ' .
The code might not be exactly "clean" at this point, but I'm getting started with Javascript.
I made the player jump by using a for loop with a delay. I tried to make him go down the same way, but this didn't work out the way I planned.
Fiddle demo
** NOTE : Press space to start!
<!DOCTYPE html>
<html>
<style>
#canvas {
background-color: rgba(177, 177, 177, 1);
}
</style>
<body>
<div>
<p id="jumpDistance"></p>
<p id="jumpDirection"></p>
</div>
<canvas id="canvas" width="800" height="400"></canvas>
<script>
var canvas = document.querySelector('#canvas');
var context = canvas.getContext('2d');
var xPos = 150;
var yPos = 375;
var jumpDistance = 0;
function spelerObj() {
canvas.width=canvas.width;
context.rect(xPos, yPos, 25, 25);
context.stroke();
context.fillStyle = "#FF0000";
context.fillRect(xPos, yPos, 25, 25);
}
function jump(e) { //Here the player jumps, with a loop that calculates it's jump-distance.
//alert(e.keyCode);
if (e.keyCode == 32) {//
function upLoop() {
setTimeout(function () {
if(jumpDistance < 50) {
yPos -= 1;
jumpDistance++;
upLoop();
spelerObj();
document.getElementById("jumpDistance").innerHTML = jumpDistance.toString();
}
}, 1)
}
upLoop();
spelerObj();
}
}
document.onkeydown = jump;
</script>
</body>
</html>
You'd need a downloop that you can switch to at the top of the jump:
function upLoop() {
setTimeout(function() {
if (jumpDistance < 50) {
yPos -= 1;
jumpDistance++;
upLoop();
} else {
downLoop();
}
spelerObj();
document.getElementById("jumpDistance").innerHTML = jumpDistance.toString();
}, 1)
}
function downLoop() {
setTimeout(function() {
if (jumpDistance > 0) {
yPos += 1;
jumpDistance--;
downLoop();
}
spelerObj();
document.getElementById("jumpDistance").innerHTML = jumpDistance.toString();
}, 1)
}
Demo 1
You could also vary the timeout duration to add a pseudo-gravity effect.
Demo 2
Can anybody help me with clearInterval? I have been working with it for hours and can't seem to get it to work. I am using a very similar code to what I found on W3 schools as follows:
Here is also a link to see in action: http://hyque.com/ani/drawImageBtn.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>DrawImage with Buttons</title>
</head>
<body>
<button id="startBtn">Start</button>
<button id="stopBtn">Stop</button><br />
<canvas id="myCanvas" width="125" height="187" style="border:1px solid #d3d3d3;">
<script>
window.onload = function() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = new Image();
img.src = "http://hyque.com/ani/adam.png";
var xPos = 0;
ctx.drawImage(img, 0, 0, 120, 182, 0, 0, 120, 182);
var el = document.getElementById('startBtn');
el.addEventListener('click', strt, false);
var el2 = document.getElementById('stopBtn');
el2.addEventListener('click', stopIt, false);
function imageXPosition() {
ctx.clearRect(0, 0, 120, 182); // This clears the canvas
ctx.drawImage(img, xPos, 0, 120, 182, 0, 0, 120, 182); //Draws the individual frames
xPos += 120; //adds the width
//This adds 1 to the second frame
if(xPos == 120){
xPos += 1;
}
if(xPos > 841){xPos = 0;} // This resets to 0 after the las frame
}
function strt(){
var intStp = setInterval(imageXPosition, 200);
}
function stopIt(){
clearInterval(intStp);
}
}
</script>
</body>
</html>
You may have a look at scoping:
var intStp;
function strt(){
intStp = setInterval(imageXPosition, 200);
}
function stopIt(){
clearInterval(intStp);
}
A variable inside of a function only exists until the function ended, unless it isnt bound to inner functions (see Closure).
function(){
var a;//a is declared
}
//a is deleted
And functions cannot access other functions properties, unless it is accessing a variable of an outer function.
You may read on MDN : JS Scoping, Functions, Variables (mainly : the basics)
IntStp variable in local scope start function. Just omit the var keyword
I have a canvas element. I have a few troubles, how to draw to user canvas in "realtime",.. So, that my drawing is not already there when they open the site, but rather to draw to the canvas like somebody is actually drawing... So looping through the coordinates.
That's what I tried so far but it's BAAD! It's drawing slowly and it takes a lot of CPU.
// Pencil Points
var ppts = [];
/* Drawing on Paint App */
tmp_ctx.lineWidth = 4;
tmp_ctx.lineJoin = 'round';
tmp_ctx.lineCap = 'round';
tmp_ctx.strokeStyle = '#4684F6';
tmp_ctx.fillStyle = '#4684F6';
// Tmp canvas is always cleared up before drawing.
tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);
tmp_ctx.beginPath();
var timer = 0;
$.timer(500, function() {
ppts.push({x: 10*timer, y: 5*timer});
timer++;
})
$.timer(10, function() {
if (timer > 250) {
timer = 0;
clearTempCanvas();
} else {
for (var i = 1; i < ppts.length - 2; i++) {
var c = (ppts[i].x + ppts[i + 1].x) / 2;
var d = (ppts[i].y + ppts[i + 1].y) / 2;
tmp_ctx.quadraticCurveTo(ppts[i].x, ppts[i].y, c, d);
}
console.log(i);
tmp_ctx.stroke();
}
})
function clearTempCanvas() {
// Writing down to real canvas now
ctx.drawImage(tmp_canvas, 0, 0);
// Clearing tmp canvas
tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);
// Emptying up Pencil Points
ppts = [];
}
Here's an example for you to learn from: http://jsfiddle.net/m1erickson/j4HWS/
It works like this:
define some points to animate along and put those points in an array points.push({x:25,y:50})
use requestAnimationFrame to create an animation loop
break each line segment into 100 sub-segments and animate along those sub-segments
Example code:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" />
<script src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
ctx.lineWidth=2;
ctx.strokeStyle="blue";
var points=[];
points.push({x:125,y:125});
points.push({x:250,y:200});
points.push({x:125,y:200});
points.push({x:125,y:125});
var pointIndex=1;
var linePct=0;
var continueAnimating=true;
var img=new Image();img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/pen.png";
function start(){
animate();
}
function draw(pointIndex,linePct){
// clear the canvas
ctx.clearRect(0,0,canvas.width,canvas.height);
// draw fully completed lines
ctx.beginPath();
ctx.moveTo(points[0].x,points[0].y);
for(var i=1;i<pointIndex;i++){
ctx.lineTo(points[i].x,points[i].y);
}
// draw current line-in-process
var pos=getLineXYatPercent(points[pointIndex-1],points[pointIndex],linePct/100);
ctx.lineTo(pos.x,pos.y);
ctx.stroke();
// draw the pen
ctx.drawImage(img,pos.x-93,pos.y-92);
}
function animate() {
if(!continueAnimating){return;}
requestAnimationFrame(animate);
// Drawing code goes here
draw(pointIndex,linePct);
if(++linePct>100){
linePct=1;
if(++pointIndex>points.length-1){
continueAnimating=false;
}
}
}
function getLineXYatPercent(startPt,endPt,percent) {
var dx = endPt.x-startPt.x;
var dy = endPt.y-startPt.y;
var X = startPt.x + dx*percent;
var Y = startPt.y + dy*percent;
return( {x:X,y:Y} );
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=350 height=350></canvas>
</body>
</html>
Simply put, I'm trying to toggle a button to make a line bold (or not). I read a few questions here similar to this problem, but the solutions haven't helped me. Here's my code:
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<div id="DrawLineDiv">
<canvas id="DrawLineCanvas" width="578" height="200"></canvas>
<script>
var canvas = document.getElementById('DrawLineCanvas');
var context = canvas.getContext('2d');
// Use beginPath() to declare that a new path is to be drawn
context.beginPath();
// Place the drawing cursor at the desired point
context.moveTo(100, 150);
// Determine where to stop drawing
context.lineTo(450,50);
//Draw the line
context.stroke();
</script>
</div>
<script>
var canvas = document.getElementById("DrawLineCanvas");
//var context = canvas.getContext('2d');
function toggleLineBold(button) {
var button;
if (button == "BoldNow") {
context.lineWidth = 15;
context.stroke();
document.getElementById("BoldLineButton").onclick = function(){
toggleLineBold('Regular');
};
} else {
context.lineWidth = 1;
context.stroke();
document.getElementById("BoldLineButton").onclick = function(){
toggleLineBold('BoldNow');
};
return;
};
};
</script>
<div id="BoldLineButton" style="height:50px; width:120px; border:2px solid #6495ed; background-color:#bcd2ee; border-radius:10px; margin-left: 5px; text-align:center" onclick="toggleLineBold('BoldNow')">
<br/>Toggle Bold Line<br/>
</div>
</body>
</html>
The line changes to bold, but triggers an error in the javascript at the line trying to change the onclick event. I know I've got something wrong, I'm just not sure what.
Thank's in advance for your assistance.
LIVE DEMO
HTML:
<canvas id="DrawLineCanvas" width="578" height="200"></canvas>
<button id="BoldLineButton">Line size: <b>1</b></button>
JS:
var doc = document,
canvas = doc.querySelector('#DrawLineCanvas'),
boldBtn = doc.querySelector('#BoldLineButton'),
ctx = canvas.getContext('2d'),
size = [1, 3, 5, 10, 15], // use only [1, 15] if you want
currSize = 0; // size[0] = 1 // Index pointer to get the value out of the
// size Array
function draw(){
canvas.width = canvas.width;
ctx.beginPath();
ctx.moveTo(100, 150);
ctx.lineTo(450,50);
ctx.lineWidth = size[currSize]; // Use currSize Array index
ctx.stroke();
}
draw();
function toggleLineBold() {
++currSize; // Increase size and
currSize %= size.length; // loop if needed.
boldBtn.getElementsByTagName('b')[0].innerHTML = size[currSize];
draw();
}
boldBtn.addEventListener("click", toggleLineBold);