I'm trying to emulate how smooth this website is: http://material.cmiscm.com/ (You may have seen it before)
So, I'm starting very very small and simply trying to emulate the way the gradient in the purple section fades from the box. His gradient is diagonal -- for simplicity, mine is horizontal.
But, my problem is my gradient comes in very choppily, even when I try changing the value of RECT_INCREMENT
Fiddle: https://jsfiddle.net/16he6jfu/
Raw code (ctrl +v'able):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<style>
#canvas {
padding: 0;
margin: 0;
}
body {
background: #6D00D0;
}
</style>
<body>
<canvas id="canvas" width="900" height="555">
</canvas>
</body>
<script>
var MAX_RECT_LENGTH = 800;
var RECT_INCREMENT = 50;
var RECT_X_ORIG = 0;
var RECT_Y_ORIG = 100;
var RECT_Y_MIN = 0;
var RECT_Y_MAX = 100;
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var gra = context.createLinearGradient(0, 0, 800, 0);
gra.addColorStop(0, 'rgba(229, 88, 95, .6)');
gra.addColorStop(1, 'rgba(255, 255, 255, 0)');
var path = 0;
function draw(){
if (path < MAX_RECT_LENGTH) {
context.beginPath();
// 1
context.moveTo(RECT_X_ORIG + path, RECT_Y_ORIG);
//console.log('1) ' + (RECT_X_ORIG + path) + ', ' + RECT_Y_ORIG);
// 2
path = path+RECT_INCREMENT;
context.lineTo(RECT_X_ORIG + path, RECT_Y_ORIG);
//console.log('2) ' + (RECT_X_ORIG + path) + ', ' + RECT_Y_ORIG);
// 3
context.lineTo(RECT_X_ORIG + path, RECT_Y_MIN);
//console.log('3) ' + (RECT_X_ORIG + path) + ', ' + RECT_Y_MIN);
// 4
context.lineTo(RECT_X_ORIG + path - RECT_INCREMENT, RECT_Y_MIN);
//console.log('4) ' + (RECT_X_ORIG + path - RECT_INCREMENT) + ', ' + RECT_Y_MIN);
// 5
context.lineTo(RECT_X_ORIG + path - RECT_INCREMENT, RECT_Y_MAX);
//console.log('5) ' + (RECT_X_ORIG + path - RECT_INCREMENT) + ', ' + RECT_Y_MAX);
context.closePath();
context.fillStyle=gra;
context.fill();
}
window.requestAnimationFrame(draw);
}
window.onload = function() {
window.requestAnimationFrame(draw);
}
</script>
</html>
Gradients are somewhat expensive to create. Instead of recreating a gradient on every animation loop, just create the full gradient rect at the start of your app and incrementally display it in the loop.
Here's example code and a Demo
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var rect=createRectCanvas();
var width=1;
requestAnimationFrame(draw);
function draw(){
ctx.clearRect(0,0,cw,ch);
ctx.drawImage(rect,0,0,width,rect.height,0,0,width,rect.height);
width+=10;
if(width<cw && width<rect.width){
requestAnimationFrame(draw);
}
}
function createRectCanvas(){
var c=document.createElement('canvas');
var context=c.getContext('2d');
c.width=800;
c.height=100;
var gra = context.createLinearGradient(0, 0, 800, 0);
gra.addColorStop(0, 'rgba(229, 88, 95, .6)');
gra.addColorStop(1, 'rgba(255, 255, 255, 0)');
context.fillStyle=gra;
context.fillRect(0,0,800,100);
return(c);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=900 height=500></canvas>
Related
I was trying to use this tutorial to make a color picker. I am not very familiar with the canvas element, so I am just testing with the code from that link. I set the image src with a few different images, and none of them are appearing.
I'm not sure what i'd have to change to make it appear, but I tried changing the src, and that is not the problem. Basically when you click on the color wheel (the image on the canvas) an alert should pop up with the rgba value.
If I had to guess, maybe the problem is here? I would think you need an src before telling it what to do when it loads.
image.onload = () => canvasContext.drawImage(image, 0, 0, image.width, image.height);
image.src="https://i.stack.imgur.com/flqeC.jpg?s=256";
This is a jsfiddle with the code I have. I'm not the most experienced so this may be silly fix, but I appreciate any help!
In local its working fine here is full code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
body {
background-color: red;
}
#colorCanvas {
border: 1px solid #000000;
background-color:blue
}
</style>
</head>
<body>
<h1>Test</h1>
<canvas id="colorCanvas" class="color-canvas" width="250" height="250"></canvas>
</body>
<script type="text/javascript">
function initColorPicker() {
var canvasEl = document.getElementById('colorCanvas');
var canvasContext = canvasEl.getContext('2d');
var image = new Image(250, 250);
image.onload = () => canvasContext.drawImage(image, 0, 0, image.width, image.height);
image.src = "http://localhost/test/assets/img/color.jpg";
canvasEl.addEventListener('click', function (mouseEvent) {
{
var imgData = canvasContext.getImageData(mouseEvent.offsetX, mouseEvent.offsetY, 1, 1);
var rgba = imgData.data;
alert("rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ", " + rgba[3] + ")");
}
})
}
initColorPicker();
</script>
</html>
Use Local Path of Image save that image in your local server otherwise you will get cross origin issue and then use this code
function initColorPicker()
{
var canvasEl = document.getElementById('colorCanvas');
var canvasContext = canvasEl.getContext('2d');
var image = new Image(250, 250);
image.onload = () => canvasContext.drawImage(image, 0, 0, image.width, image.height);
image.src="https://i.stack.imgur.com/flqeC.jpg?s=256";
canvasEl.addEventListener('click', function(mouseEvent) {
{
var imgData = canvasContext.getImageData(mouseEvent.offsetX, mouseEvent.offsetY, 1, 1);
var rgba = imgData.data;
alert("rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ", " + rgba[3] + ")");
}
})
}
initColorPicker();
I'm using a event handler on a HTML canvas to track the coordinates of where a user clicks, and my idea is to connect coordinates together with a line.
The code below creates an Array and keeps a list of coordinates within the canvas element that the user has clicked on, and also contains logic to draw a line between the currently clicked point and the point that's been previously clicked on.
The problem I'm encountering is that, no matter how many times I click, even though my Array is being populated with coordinates, the lines are not being drawn between the points.
I'm not entirely sure what I am doing wrong, or if there is some re-rendering being done that might be wiping away the drawings I make on the canvas.
var coords = [];
var canvas = document.getElementById('canvas');
canvas.addEventListener('click', function (event) {
var coord = { "x": event.screenX, "y": event.screenY };
document.getElementById("coords").innerText = "{" + coord.x + ", " + coord.y + "}";
coords.push(coord);
var max = coords.length - 1;
if (typeof coords[max - 1] !== "undefined") {
var curr = coords[max], prev = coords[max - 1];
var context = canvas.getContext("2d");
context.beginPath();
context.moveTo(prev.x, prev.y);
context.lineTo(curr.x, curr.y);
context.stroke();
}
});
<!doctype html>
</html>
<head>
<title>Drawing canvas</title>
<style>
canvas {
width: 200px;
height: 200px;
border: 2px solid black;
border-radius: 5px;
}
</style>
</head>
<body>
<p id='coords'></p>
<canvas id='canvas'></canvas>
</body>
</html>
Move your context outside the click event and use canvas coordinates instead of screen one: event.x and event.y
Do not use CSS dimensions for the canvas. Check this post
var coords = [];
var canvas = document.getElementById('canvas');
var context = canvas.getContext("2d");
canvas.addEventListener('click', function (event) {
var coord = { "x": event.x, "y": event.y};
document.getElementById("coords").innerText = "{" + coord.x + ", " + coord.y + "}";
coords.push(coord);
var max = coords.length - 1;
if (typeof coords[max - 1] !== "undefined") {
var curr = coords[max], prev = coords[max - 1];
context.beginPath();
context.moveTo(prev.x, prev.y);
context.lineTo(curr.x, curr.y);
context.stroke();
}
});
<style>
canvas {
border: 1px solid black;
border-radius: 0px;
}
body {
margin: 0;
padding: 0;
}
</style>
<canvas id='canvas' width="200" height="200"></canvas>
<p id='coords'></p>
In javascript I am trying to extract the (R, G, B) value of a clicked pixel from the following image:
http://map1.vis.earthdata.nasa.gov/wmts-webmerc/MODIS_Terra_Snow_Cover/default/2015-05-25/GoogleMapsCompatible_Level8/8/97/49.png
I am using the element and I set the crossOrigin="anonymous" attribute so that I can work with the data.
Here is my html and javascript code:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
<img src="http://map1.vis.earthdata.nasa.gov/wmts-webmerc/MODIS_Terra_Snow_Cover/default/2015-05-25/GoogleMapsCompatible_Level8/8/97/49.png"
crossOrigin="anonymous" width="256" height="256">
<pre id="output"></pre>
<script>
$(function() {
$('img').click(function(e) {
if(!this.canvas) {
this.canvas = $('<canvas/>').css({width:256 + 'px', height: 256 + 'px'})[0];
this.canvas.getContext('2d').drawImage(this, 0, 0, 256, 256);
}
var offX = (e.offsetX || e.clientX - $(e.target).offset().left);
var offY = (e.offsetY || e.clientY - $(e.target).offset().top);
console.log(offX + ' ' + offY);
var pixelData = this.canvas.getContext('2d').getImageData(offX, offY, 1, 1).data;
$('#output').html('offX:' + offX + ' offY:' + offY +
'<br>R: ' + pixelData[0] +
'<br>G: ' + pixelData[1] +
'<br>B: ' + pixelData[2] +
'<br>A: ' + pixelData[3]);
});
});
</script>
</body>
</html>
I've also put my code on jsfiddle:
http://jsfiddle.net/32beaobL/
The problem is that this code gets the correct RGB value of the clicked pixel only until around row 149 of the image. for rows 149 and greater, it returns (0,0,0) for any pixel even though the pixel has a non-white color.
Any idea what's going on?
You resized the canvas with CSS, so the canvas was never over 150px tall (default canvas size is 300 x 150).
Here is your example fixed: http://jsfiddle.net/32beaobL/1/
This is the code that changed
if(!this.canvas) {
this.canvas = document.createElement('canvas');
this.canvas.width = 256;
this.canvas.height = 256;
this.canvas.getContext('2d').drawImage(this, 0, 0, 256, 256);
}
I'm using the following code to generate a Pythagoras fractal tree using HTML5 canvas element:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script src="jquery.js" type="text/javascript"></script>
<style>
#sketch
{
border: 1px solid black;
}
</style>
<script type="text/javascript">
window.onload = function()
{
var canvas = document.getElementById("sketch");
var context = canvas.getContext("2d");
context.fillStyle = "rgba(0, 0, 200, 0.5)";
context.beginPath();
context.moveTo(450,550);
context.lineTo(450,450);
context.lineTo(550,450);
context.lineTo(550,550);
context.fill();
fractal(context,[450,550],[450,450],[550,450],[550,550],5);
};
function fractal(context,P1,P2,P3,P4,depth)
{
context.fillStyle = "rgba(0,0,200,"+(depth/8).toString()+")";
context.save();
if(depth < 0)
{
return null;
}
/*Find C*/
C = divide(add(divide(add(P1,P2),2),divide(add(P3,P4),2)),2);
var V1 = divide(minus(C,P1),length(C,P1));
var V2 = divide(minus(C,P4),length(C,P4));
var P6 = add(P2,multiply(V2,length(P1,P2)/Math.sqrt(2)));
var P7 = add(P6,multiply(V1,length(P1,P2)/Math.sqrt(2)));
var P5 = add(P2,multiply(V1,length(P1,P2)/Math.sqrt(2)));
var P9 = add(P3,multiply(V1,length(P1,P2)/Math.sqrt(2)));
var P8 = add(P9,multiply(V2,length(P1,P2)/Math.sqrt(2)));
context.moveTo(P2[0],P2[1]);
context.lineTo(P6[0],P6[1]);
context.lineTo(P7[0],P7[1]);
context.lineTo(P5[0],P5[1]);
context.fill();
context.moveTo(P5[0],P5[1]);
context.lineTo(P8[0],P8[1]);
context.lineTo(P9[0],P9[1]);
context.lineTo(P3[0],P3[1]);
context.fill();
fractal(context,P2,P6,P7,P5,depth-1);
fractal(context,P5,P8,P9,P3,depth-1);
}
function multiply(v, num){
return [v[0]*num, v[1]*num];
}
function divide(v, num){
return [v[0]/num, v[1]/num];
}
function add(a, b){
return [a[0]+b[0], a[1]+b[1]];
}
function minus(a, b){
return [a[0]-b[0], a[1]-b[1]];
}
function length(a, b){
return Math.sqrt(Math.pow(a[0] - b[0],2) +
Math.pow(a[1] - b[1],2));
}
</script>
<title>Square</title>
</head>
<body>
<canvas id="sketch" height="1000" width="1000"></canvas>
</body>
</html>
I'm changing the opacity value with every iteration. But I don't see it in the result.
How can this be fixed??
You were really close to the right solution. Look here:
http://jsfiddle.net/mbessey/Wj4VH/
The key difference here is calling beginPath() before starting the moveTo() and lineTo() for each square. So, instead of:
context.moveTo(P2[0],P2[1]);
context.lineTo(P6[0],P6[1]);
context.lineTo(P7[0],P7[1]);
context.lineTo(P5[0],P5[1]);
context.fill();
context.moveTo(P5[0],P5[1]);
context.lineTo(P8[0],P8[1]);
context.lineTo(P9[0],P9[1]);
context.lineTo(P3[0],P3[1]);
context.fill();
You want:
context.beginPath()
context.moveTo(P2[0],P2[1]);
context.lineTo(P6[0],P6[1]);
context.lineTo(P7[0],P7[1]);
context.lineTo(P5[0],P5[1]);
context.fill();
context.beginPath()
context.moveTo(P5[0],P5[1]);
context.lineTo(P8[0],P8[1]);
context.lineTo(P9[0],P9[1]);
context.lineTo(P3[0],P3[1]);
context.fill();
What you were doing was essentially creating one large path with all the squares in it and then filling it all with the same color.
Check This I have changed the opacity of the canvas itself ,making it simple and easy to achieve the target.
Adding rgba(0, 0, 200, 1) and
#sketch
{
border: 1px solid black;
opacity: 0.3;
}
will suffice what you want
I'm trying to use <canvas> to construct a grid. Please note - the code below is not my code and I remember finding it on stack overflow somewhere:
Here is my error:
Cannot call method 'getContext' of undefined
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body {
background: lightblue;
}
canvas {
background: #fff;
margin: 20px;
}
</style>
<!-- JQ Lib -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js"></script>
<script type="text/javascript">
//grid width and height
var bw = 400;
var bh = 400;
//padding around grid
var p = 10;
//size of canvas
var cw = bw + (p*2) + 1;
var ch = bh + (p*2) + 1;
var canvas = $('#canvas').attr({width: cw, height: ch}).appendTo('body');
var context = canvas.get(0).getContext("2d");
function drawBoard(){
for (var x = 0; x <= bw; x += 40) {
context.moveTo(0.5 + x + p, p);
context.lineTo(0.5 + x + p, bh + p);
}
for (var x = 0; x <= bh; x += 40) {
context.moveTo(p, 0.5 + x + p);
context.lineTo(bw + p, 0.5 + x + p);
}
context.strokeStyle = "black";
context.stroke();
}
drawBoard();
</script>
</head>
<body>
<canvas id="canvas"> </canvas>
</body>
</html>
The error is originating on this line:
var canvas = $('#canvas').attr({width: cw, height: ch}).appendTo('body');
I have tried many different ways of doing this, but I keep getting the above error. Am I just making a mindless mistake here?
You haven't defined $, which is a common (but meaningless) variable name used by a variety of different libraries including Protoype.js, Mootools and jQuery.
That syntax looks like jQuery so you will need to include the script for that library or rewrite it using built-in functions.