<!DOCTYPE html>
<html>
<head>
<meta lang="EN" />
<script type="text/javascript" src="jquery-1.4.4.min.js"></script>
<script type="text/javascript">
// Don't resize the window
function _(str){
return document.getElementById(str);
}
function incPixel(imageData, x, y){
var index = (x + y * imageData.width) * 4;
imageData.data[index + 0] = 155;
imageData.data[index + 1] = 155;
imageData.data[index + 2] = 155;
imageData.data[index + 3] = 155;
}
$(document).ready(function(){
// collect mouse position data
var history = [];
$(document).mousemove(function(e){
history.push([e.pageX, e.pageY]);
});
// when the button is clicked
$("#button").click(function(){
// 1. disable mouse position data collection
$(document).unbind("mousemove");
// 2. draw pixels on the canvas
var width = $(document).width();
var height = $(document).height();
$("#canvas").height(height).width(width);
var canvas = document.getElementById("canvas");
if(canvas.getContext){
var context = canvas.getContext("2d");
var imageData = context.createImageData(width, height);
for(var i=0; i<history.length; i++){
incPixel(imageData, history[i][0], history[i][1]);
}
context.putImageData(imageData, 0, 0);
alert(JSON.stringify(history));
}else{
alert("no context");
}
});
});
</script>
</head>
<body>
<h1>Hello, Worlds!</h1>
<div id="width"></div>
<div id="height"></div>
<input type="button" id="button" value="Click me" /><br />
<canvas id="canvas" />
</body>
</html>
You're missing the context type parameter from getContext(), it should be:
var context = canvas.getContext('2d');
You can test out a demo here with only the change above.
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...
Page for Example:
http://google.com/recaptcha/api2/demo
If i open the image 'myid' the frame will be - EXAMPLE:frame2
now what i want to do, is to draw canvas of 'myid' inside the 'frame2'.
here is the code that i have: (draw by element id)
var canvas = window.document.createElementNS('http://www.w3.org/1999/xhtml', 'html:canvas');
var selection_element = window.document.getElementById("myid");
var selection;
var de = window.document.documentElement;
var box = selection_element.getBoundingClientRect();
var new_top = box.top + window.pageYOffset - de.clientTop;
var new_left = box.left + window.pageXOffset - de.clientLeft;
var new_height = selection_element.offsetHeight;
var new_width = selection_element.offsetWidth;
selection={
top:new_top,
left:new_left,
width:new_width,
height:new_height,
};
canvas.height = selection.height;
canvas.width = selection.width;
var context = canvas.getContext('2d');
context.drawWindow(
window,
selection.left,
selection.top,
selection.width,
selection.height,
'rgba(255, 255, 255, 0)'
);
var canvasdata = canvas.toDataURL('','').split(',')[1];
To append item to frame you need to call that by id. In this HTML:
<iframe id="frm1"></iframe>
<iframe id="frm2"></iframe>
If you use this code:
$(document).ready(function ()
{
var frames = window.frames;
for (var i = 0; i < frames.length; i++)
{
var fi = frames[i]
$(fi).load(function ()
{
$(this).contents().find('body').append("<span>Hello World!</span>");
});
}
});
Does not work, But this one works:
<html>
<head>
<title></title>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
</head>
<body>
<iframe id="frm1"></iframe>
<iframe id="frm2"></iframe>
<script>
$(document).ready(function ()
{
var frm1 = window.frames["frm1"];
$(frm1).load(function ()
{
$(frm1).contents().find('body').append("<span>Hello World!</span>");
});
});
</script>
</body></html>
I tried to create a code snippet, but it seems it has problem with frames.
You can copy the exact HTML and test that.
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>
I'm making an javascript image converter, just a proof of concept(I know there are another better languages for doing it). My problem is that in the loop section I'm doing some variables don't evaluate to the ones that are in the function loops. The code should work this way:
The HTML button activates the parent function.
Some variables are stated.
The loop that should make a nice gradient all over the and those I'm having trouble with are defined.
A function that triggers the loops in intervals is stated, with some other counter variables.e
I think the problem is in the counter variables I use on the loop() but I can't figure them out.
Here is all my code:
<!DOCTYPE html>
<html>
<head>
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>CPBitmap to PNG</title>
<style>
#canvas {
width:512px;
height:384px;
background-color:black;
}
</style>
<script>
function convertir(){
var y =0;
vertC = 10;
var pixelConverter = function(){
for(;y<vertC;y++){
for(var x=0; x<2048;x++){
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var pixel = "rgb(" + y + "," + vertC + "," + x + ")";
ctx.fillStyle = pixel;
ctx.fillRect(x,y,100,100);
}
}
}
intervalos = setInterval(loops,1);
function loops(){
pixelConverter();
vertC = vertC + 10;
console.log("Y= " + y + "Linea " + vertC );
y = y + 10;
x = 0;
console.log(x);
if(x > 2047 && y > 1535)intervalos=window.clearInterval(intervalos);
else pixelConverter();
}
}
</script>
</head>
<body>
<input type="file" id="input" name="file" />
<button onclick=convertir() >¡Convertir!</button>
<button onclick="intervalos=window.clearInterval(intervalos)">Alto</button>
<canvas id="canvas" width="2048px" height="1536px"></canvas>
<div id="Hola"></div>
</body>
</html>
I'm currently working on an iOS app which uses HTML 5 and JavaScript for drawing Graphs.
I just did a sample App.
My Code:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var a = 0;
var b = 0;
function init()
{
var can = document.getElementById('can');
can.addEventListener("click",click, false);
}
function click(event)
{
var can = document.getElementById('can');
var c = can.getContext('2d');
var parentPosition = getPosition(event.currentTarget);
c.lineWidth = 1;
c.strokeStyle = '#FFFFFF';
c.beginPath();
c.moveTo(a, b);
a = event.clientX - parentPosition.x;
b = event.clientY - parentPosition.y;
c.lineTo(a, b);
c.stroke();
}
function getPosition(element)
{
var xPosition = 0;
var yPosition = 0;
while (element)
{
xPosition += (element.offsetLeft - element.scrollLeft + element.clientLeft);
yPosition += (element.offsetTop - element.scrollTop + element.clientTop);
element = element.offsetParent;
}
return { x: xPosition, y: yPosition };
}
</script>
</head>
<body oncopy='copy();' onpaste='paste();'onload ='init();'>
<canvas id="can" style="height:300px;width:300px;background-color:black;">Oops!</canvas>
</body>
</html>
My Issue:
When a user Taps on the screen, I'm drawing a line to that particular point from previous point.
But in my case when I tap on the screen the line is drawn to some other point. Say if I tapped on point (100,100) the line will be drawn to (100, some arbitrary value). Always the Y position is wrong.
What I did:
Tested it on simulator
Tested it on device
Tested it on Firefox
Tested it on Chrome
All results are same. I couldn't find the issue. I alerted the clicked x and y co-ordinate. It's coming correctly. Only problem is with the draw functionality.
Screenshots:
As you can see the X-coordinate is correct. But Y-coordinate is always coming wrong.
Please help me, Thanks in advance.
Can you please make these changes.
In html line#47,
<canvas id="can" height=300 width=300 style="background-color:red;">Oops!</canvas>
In script line#23,
c.beginPath();
c.moveTo(a, b);
a = event.clientX - parentPosition.x;
b = event.clientY - parentPosition.y;
console.log('a:'+a+'--b:'+b);
c.lineTo(a, b);
c.stroke();
TO CLEAR
This is the code that you have to change to have a reusable code:
c.moveTo(a/(can.clientWidth/can.width), b/(can.clientHeight/can.height));
a = event.clientX - parentPosition.x;
b = event.clientY - parentPosition.y;
console.log('a:'+a+'--b:'+b);
c.lineTo(a/(can.clientWidth/can.width), b/(can.clientHeight/can.height));
If you don't use this, the code below works only for 300x300 canvas size.
LAST EDIT:
By analyzing the 2d context (var c = can.getContext('2d');console.log(c);) you can easily understand this error: there is a relation (not explicit) from the canvas and it's 2d context.
As you can see from the image:
the height and the width of the canvas(this is 500*500) are differents from its offset,scroll and client size. So, before to draw, you need to calculate the ratio: 500/150 will be the height coefficient and 500/300 the width one, so a will be multiplied by 1.66667 and b will be multiplied by 3.33333.
Same for the old example (canvas 300*300) the coefficent are 300/300=1 (a:width) 300/150=2 (b:height)
OLD REPLY:
But now, you have to guess why..cause actually I have no time
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript">
var a = 0;
var b = 0;
function init()
{
var can = document.getElementById('can');
can.addEventListener("click",click, false);
}
function click(event)
{
var can = document.getElementById('can');
var c = can.getContext('2d');
var parentPosition = getPosition(event.currentTarget);
console.log(parentPosition);
console.log(event);
c.lineWidth = 1;
c.strokeStyle = '#FFFFFF';
c.beginPath();
c.moveTo(a, b/2);
a = event.clientX - parentPosition.x;
b = event.clientY - parentPosition.y;
console.log('a:'+a+'--b:'+b);
c.lineTo(a, b/2);
c.stroke();
}
function getPosition(element)
{
var xPosition = 0;
var yPosition = 0;
while (element)
{
xPosition += (element.offsetLeft - element.scrollLeft + element.clientLeft);
yPosition += (element.offsetTop - element.scrollTop + element.clientTop);
element = element.offsetParent;
}
return { x: xPosition, y: yPosition };
}
</script>
</head>
<body oncopy='copy();' onpaste='paste();'onload ='init();'>
<canvas id="can" style="height:300px;width:300px;background-color:black;">Oops!</canvas>
<br>
pagex<input type="text" id="ics">pagey<input type="text" id="ips"><br>
screenx<input type="text" id="ics2">screeny<input type="text" id="ips2">
<script>
$("#can").mousemove(function(event) {
var msg = "Handler for .mousemove() called at ";
document.getElementById('ics').value= event.pageX
document.getElementById('ips').value= event.pageY;
document.getElementById('ics2').value= event.screenX;
document.getElementById('ips2').value= event.screenY;
});
</script>
</body>
</html>