I need some help increasing the height of HTML canvas lines - javascript

I am doing a project where the user selects what programming language they enjoy out of a radio box. It sets an object to the Local Storage and creates a bar graph and the bars go up depending on what choice the select. I'm having trouble though where if the user selects the language for the third time, it turns out what is in the image. I change the height each time and for some reason it also goes over the axis. I just want the height to change. I'm not super familiar with the canvas. Is there a way I could go about doing this? I just simply want the bar to start at the origin and go up, but not down.
Code below:
<!--
Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
Click nbfs://nbhost/SystemFileSystem/Templates/Other/html.html to edit this template
-->
<!DOCTYPE HTML>
<html>
<head>
<title>Extra Credit Challenge</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
#entryArea{
border: 1px solid black;
width: 30%;
border-radius: 100px;
text-align: center;
margin: auto;
}
#myCanvas{
border-radius: 25px;
border: 1px;
}
#submitButton{
border-radius: 15px;
background-color:lightblue;
font-size: 25px;
width: 30%;
}
input{
font-size: 25px;
}
#resetButton{
border-radius: 15px;
background-color:lightblue;
font-size: 25px;
width: 30%;
}
</style>
</head>
<body onload="init()">
<canvas id="myCanvas" width="500" height="450" style="border:1px solid #000000;"></canvas>
<div id="entryArea">
<p style="font-size: 20px">What is your favorite programming language?</p>
<p><input name="language" type="radio" value="Web Design">Web Design</p>
<p><input name="language" type="radio" value="Java">Java</p>
<p><input name="language" type="radio" value="Python">Python</p>
<p><input name="language" type="radio" value="Other">Other</p>
<button id="submitButton">Submit</button><br><br>
<button id="resetButton">Reset</button>
</div>
<script>
function init(){
unCheckItems();
drawAxes();
walkThroughStorage();
document.getElementById("submitButton").addEventListener("click", setItemToStorage);
document.getElementById("resetButton").addEventListener("click", clearCanvas);
}
function walkThroughStorage(){
var ele = document.getElementById("entryArea").querySelectorAll("input");
var curTextStorage = localStorage.getItem("ClickedBoxes");
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
curTextStorage = JSON.parse(curTextStorage);
if(curTextStorage !== null){
for(let i = 0; i<ele.length; i++){
let height = (curTextStorage[ele[i].value] || 0) * 40;
if(ele[i].value === "Web Design"){
if(curTextStorage[ele[i].value] > 1){
ctx.rect(80, 310-(height/2), 30, height);
ctx.lineWidth = 1;
ctx.stroke();
}
if(curTextStorage[ele[i].value] === 1){
ctx.rect(80, 310, 30, 40);
ctx.lineWidth = 1;
ctx.stroke();
}
}
else if(ele[i].value === "Java"){
if(curTextStorage[ele[i].value] > 1){
ctx.rect(180, 310-(height/2), 30, height);
ctx.lineWidth = 1;
ctx.stroke();
}
if(curTextStorage[ele[i].value] === 1){
ctx.rect(180, 310, 30, 40);
ctx.lineWidth = 1;
ctx.stroke();
}
}
else if(ele[i].value === "Python"){
if(curTextStorage[ele[i].value] > 1){
ctx.rect(255, 310-(height/2), 30, height);
ctx.lineWidth = 1;
ctx.stroke();
}
if(curTextStorage[ele[i].value] === 1){
ctx.rect(255, 310, 30, 40);
ctx.lineWidth = 1;
ctx.stroke();
}
}
else{
if(curTextStorage[ele[i].value] > 1){
ctx.rect(335, 310-(height/2), 30, height);
ctx.lineWidth = 1;
ctx.stroke();
}
if(curTextStorage[ele[i].value] === 1){
ctx.rect(335, 310, 30, 40);
ctx.lineWidth = 1;
ctx.stroke();
}
}
}
}
ctx.closePath();
}
function drawAxes(){
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
//draw x axis
ctx.moveTo(20,350);
ctx.lineTo(500,350);
ctx.lineWidth = 4;
ctx.stroke();
ctx.closePath();
//draw y axis
ctx.beginPath();
ctx.moveTo(40,400);
ctx.lineTo(40,0);
ctx.stroke();
ctx.closePath();
//draw names at the bottom
ctx.font = "15px Arial";
ctx.fillText("Web Design", 60,370);
ctx.fillText("Java", 180,370);
ctx.fillText("Python", 250,370);
ctx.fillText("Other", 330,370);
}
function unCheckItems(){
var ele = document.getElementById("entryArea").querySelectorAll("input");
for(let i = 0; i < ele.length; i++) {
if(ele[i].checked){
ele[i].checked = false;
}
}
}
function setItemToStorage(){
var savedClicks = localStorage.getItem("ClickedBoxes");
let clickDict = JSON.parse(savedClicks) || {};
var ele = document.getElementById("entryArea").querySelectorAll("input");
for(let i = 0; i < ele.length; i++){
if(ele[i].checked){
if(!clickDict[ele[i].value]){
clickDict[ele[i].value]=1;
}
else//the key of 1,2,3,4 or 5 (contents of curRandNum) exist in theDict so add one to its value
{
clickDict[ele[i].value] += 1;
}
}
localStorage.setItem("ClickedBoxes",JSON.stringify(clickDict));
}
drawBars();
}
function drawBars(){
var savedClicks = localStorage.getItem("ClickedBoxes");
savedClicks = JSON.parse(savedClicks);
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
var ele = document.getElementById("entryArea").querySelectorAll("input");
for(let i = 0; i < ele.length; i++) {
let height = (savedClicks[ele[i].value] || 0) * 40;
if(ele[i].checked){
if(ele[i].value === "Web Design"){
if(savedClicks[ele[i].value] > 1){
clearBar();
//ctx.clearRect(80, 300, 30, 40);
ctx.rect(80, 310-(height/2), 30, height);
ctx.lineWidth = 0;
ctx.stroke();
}
if(savedClicks[ele[i].value] === 1){
ctx.rect(80, 310, 30, 40);
ctx.lineWidth = 1;
ctx.stroke();
}
}
else if(ele[i].value === "Java"){
if(savedClicks[ele[i].value] > 1){
clearBar();
ctx.rect(180, 310-(height/2), 30, height);
ctx.lineWidth = 0;
ctx.stroke();
}
if(savedClicks[ele[i].value] === 1){
ctx.rect(180, 310, 30, 40);
ctx.lineWidth = 1;
ctx.stroke();
}
}
else if(ele[i].value === "Python"){
if(savedClicks[ele[i].value] > 1){
clearBar();
ctx.rect(255, 310-(height/2), 30, height);
ctx.lineWidth = 0;
ctx.stroke();
}
if(savedClicks[ele[i].value] === 1){
ctx.rect(255, 310, 30, 40);
ctx.lineWidth = 1;
ctx.stroke();
}
}
else{
if(savedClicks[ele[i].value] > 1){
clearBar();
ctx.rect(335, 310-(height/2), 30, height);
ctx.lineWidth = 0;
ctx.stroke();
}
if(savedClicks[ele[i].value] === 1){
ctx.rect(335, 310, 30, 40);
ctx.lineWidth = 1;
ctx.stroke();
}
}
}
}
ctx.closePath();
}
function clearBar(){
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.clearRect(0, 0, c.width, c.height);
init();
}
function clearCanvas(){
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.clearRect(0, 0, c.width, c.height);
localStorage.clear();
init();
}
</script>
</body>
</html>
Here is the image photo
Thanks in advance!

You have a miscalculation when drawing your rectanlges.
The lines
ctx.rect(255, 310-(height/2), 30, height);
should be changed to
ctx.rect(255, 350 - height, 30, height);

That's a bit too much copy-paste. The basic issue is what #Ruan shows: if you want to draw a rectangle which ends at y=350, you just subtract its height from 350, without any division.
Other things added/removed here are:
0-1-many are not handled separately any more, a zero-sized rectangle conveniently stays inside the horizontal axis, so you can draw it, and 40 doesn't differ from 1*40, so there is no need to draw it separately
the code parts for drawing the 4 bars differred in their x coordinates only, even if their spacing is irregular, they can be picked from an array, see the [80, 180, 255, 335][i] part - bit nasty, but does the job
walkwhatever was removed, it was doing the same as drawBars()
a single reDraw() method was added for handling redraw of everything
duplicated canvas clearing removed
instead a clear() method was added for clearing existing data and calling reDraw()
init() is not reused anymore, as that would add click handlers again, which usually leads to interesting behaviour.
(And a fake localStorage has been added, simply because it's disabled for snippets hosted here on StackOverflow)
// this is just for simulating localStorage here on StackOverflow
const localStorage = {m: new Map(),
getItem: function(k) {return this.m.has(k) ? this.m.get(k) : null;},
setItem: function(k, v) {this.m.set(k, v);},
clear: function() {this.m.clear();}};
function init() {
unCheckItems();
drawAxes();
drawBars();
document.getElementById("submitButton").addEventListener("click", setItemToStorage);
document.getElementById("resetButton").addEventListener("click", clear);
}
function drawAxes() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
//draw x axis
ctx.moveTo(20, 350);
ctx.lineTo(500, 350);
ctx.lineWidth = 4;
ctx.stroke();
ctx.closePath();
//draw y axis
ctx.beginPath();
ctx.moveTo(40, 400);
ctx.lineTo(40, 0);
ctx.stroke();
ctx.closePath();
//draw names at the bottom
ctx.font = "15px Arial";
ctx.fillText("Web Design", 60, 370);
ctx.fillText("Java", 180, 370);
ctx.fillText("Python", 250, 370);
ctx.fillText("Other", 330, 370);
}
function unCheckItems() {
var ele = document.getElementById("entryArea").querySelectorAll("input");
for (let i = 0; i < ele.length; i++) {
if (ele[i].checked) {
ele[i].checked = false;
}
}
}
function setItemToStorage() {
var savedClicks = localStorage.getItem("ClickedBoxes");
let clickDict = JSON.parse(savedClicks) || {};
var ele = document.getElementById("entryArea").querySelectorAll("input");
for (let i = 0; i < ele.length; i++) {
if (ele[i].checked) {
if (!clickDict[ele[i].value]) {
clickDict[ele[i].value] = 1;
} else //the key of 1,2,3,4 or 5 (contents of curRandNum) exist in theDict so add one to its value
{
clickDict[ele[i].value] += 1;
}
}
localStorage.setItem("ClickedBoxes", JSON.stringify(clickDict));
}
reDraw();
}
function drawBars() {
var savedClicks = localStorage.getItem("ClickedBoxes");
savedClicks = JSON.parse(savedClicks) || {};
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.lineWidth = 1;
var ele = document.getElementById("entryArea").querySelectorAll("input");
for (let i = 0; i < ele.length; i++) {
let height = (savedClicks[ele[i].value] || 0) * 40;
ctx.strokeRect([80, 180, 255, 335][i], 350 - height, 30, height);
}
}
function clearCanvas() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.clearRect(0, 0, c.width, c.height);
}
function reDraw() {
unCheckItems();
clearCanvas();
drawAxes();
drawBars();
}
function clear() {
localStorage.clear();
reDraw();
}
init(); // "onload"
#entryArea {
border: 1px solid black;
width: 30%;
border-radius: 100px;
text-align: center;
margin: auto;
}
#myCanvas {
border-radius: 25px;
border: 1px;
}
#submitButton {
border-radius: 15px;
background-color: lightblue;
font-size: 25px;
width: 30%;
}
input {
font-size: 25px;
}
#resetButton {
border-radius: 15px;
background-color: lightblue;
font-size: 25px;
width: 30%;
}
<canvas id="myCanvas" width="500" height="450" style="border:1px solid #000000;"></canvas>
<div id="entryArea">
<p style="font-size: 20px">What is your favorite programming language?</p>
<p><input name="language" type="radio" value="Web Design">Web Design</p>
<p><input name="language" type="radio" value="Java">Java</p>
<p><input name="language" type="radio" value="Python">Python</p>
<p><input name="language" type="radio" value="Other">Other</p>
<button id="submitButton">Submit</button><br><br>
<button id="resetButton">Reset</button>
</div>

Related

Need help writing a function to make any box inside the grid clickable and filled with colorwheel

I'm working on a pixel art project. What I was expecting to do here is be able to click any box inside the grid and render it with the the color from a color input.
I managed to understand how the loop works to create a grid using canvas and javascript. Next, I created a function called colorPicker() which allows me to click on any of the grid cells and take the value from the color input and render it that color. I used canvas.addEventListener("click", function(event) { ... })
and passed variables xCoord and yCoord with the value of event.x and event.y. This allows me to return the position of the mouse on click inside the grid.
The problem I'm running into right now is that it is only rendering 1 square out of all 400 I have drawn on the grid. The rendering works, it's just I can only click one box and render its color from the input.
Can anyone provide me with some help to solve this function just using the javascript logic I currently have right now?
var title = document.getElementById("title");
var canvas = document.getElementById("canvas");
var color = document.getElementById("color");
var btn = document.getElementById("btn");
var ctx = canvas.getContext("2d");
// The function that draws the grid
function drawGrid() {
ctx.fillStyle = "#009EFF";
ctx.fillRect(0, 0, 400, 400);
ctx.strokeStyle = "black";
ctx.lineWidth = 1;
// The for loop that draws the x-axis
for (x = 0; x <= 400; x += 20) {
ctx.moveTo(x, 0);
ctx.lineTo(x, 400);
ctx.stroke();
}
// The for loop that draws the y-axis
for (y = 0; y <= 400; y += 20) {
ctx.moveTo(0, y);
ctx.lineTo(400, y);
ctx.stroke();
}
}
drawGrid();
// Function that clicks and fill grid boxes w / color
function colorPicker() {
canvas.addEventListener("click", function(event) {
var newColor = color.value;
ctx.fillStyle = newColor;
xCoord = event.x;
yCoord = event.y;
ctx.fillRect(0, 0, 20, 20);
console.log(xCoord, yCoord);
console.log(newColor);
});
}
colorPicker();
#canvas {
border: 1px solid black;
background-size: 100%;
display: block;
margin-top: 50px;
margin-left: auto;
margin-right: auto;
padding-left: 0;
padding-right: 0;
}
<div class="color-wheel">
Color: <input type="color" id="color" />
</div>
<canvas id="canvas" width="400" height="400"></canvas>
Your problem is this line:
ctx.fillRect(0, 0, 20, 20);
Instead of filling the clicked cell, you’re filling only the upper left cell on every click.
Currently you’re just using (0, 0) here, when you should be calculating this position from the cursor. The coordinates used by the canvas and the cursor are different though, so you’ll need to write a conversion function:
function mousePosToCanvasPos(mouseX, mouseY) {
var canvasPos = canvas.getBoundingClientRect();
return {
x: Math.floor((mouseX - canvasPos.x) / 20) * 20,
y: Math.floor((mouseY - canvasPos.y) / 20) * 20,
};
}
The mousePosToCanvasPos() function gets the current rendered position of the canvas (canvasPos), and calculates the offset of the cursor from the upper left corner of the canvas (mouse_ - canvasPos._). It then rounds this value down to the nearest multiple of 20 to return the upper left corner of the clicked cell (Math.floor((mouse_ - canvasPos._) / 20) * 20). If you change your cell size to something other than 20, be sure to change it in this function too. Or better yet, extract the constant (var cellSize = 20).
Adding this function to your code gives us:
var title = document.getElementById("title");
var canvas = document.getElementById("canvas");
var color = document.getElementById("color");
var btn = document.getElementById("btn");
var ctx = canvas.getContext("2d");
// The function that draws the grid
function drawGrid() {
ctx.fillStyle = "#009EFF";
ctx.fillRect(0, 0, 400, 400);
ctx.strokeStyle = "black";
ctx.lineWidth = 1;
// The for loop that draws the x-axis
for (x = 0; x <= 400; x += 20) {
ctx.moveTo(x, 0);
ctx.lineTo(x, 400);
ctx.stroke();
}
// The for loop that draws the y-axis
for (y = 0; y <= 400; y += 20) {
ctx.moveTo(0, y);
ctx.lineTo(400, y);
ctx.stroke();
}
}
drawGrid();
function mousePosToCanvasPos(mouseX, mouseY) {
var canvasPos = canvas.getBoundingClientRect();
return {
x: Math.floor((mouseX - canvasPos.x) / 20) * 20,
y: Math.floor((mouseY - canvasPos.y) / 20) * 20,
};
}
// Function that clicks and fill grid boxes w / color
function colorPicker() {
canvas.addEventListener("click", function(event) {
var newColor = color.value;
ctx.fillStyle = newColor;
var canvasCellPos = mousePosToCanvasPos(event.x, event.y);
ctx.fillRect(canvasCellPos.x, canvasCellPos.y, 20, 20);
console.log(event.x, event.y);
console.log(newColor);
});
}
colorPicker();
#canvas {
border: 1px solid black;
background-size: 100%;
display: block;
margin-top: 50px;
margin-left: auto;
margin-right: auto;
padding-left: 0;
padding-right: 0;
}
<div class="color-wheel">
Color: <input type="color" id="color" />
</div>
<canvas id="canvas" width="400" height="400"></canvas>
You’ll notice that something’s still not quite right here: every time you fill a cell, it makes its border thinner. To solve this, you need to remove one pixel from each side of your fillRect:
ctx.fillRect(canvasCellPos.x + 1, canvasCellPos.y + 1, 18, 18);
var title = document.getElementById("title");
var canvas = document.getElementById("canvas");
var color = document.getElementById("color");
var btn = document.getElementById("btn");
var ctx = canvas.getContext("2d");
// The function that draws the grid
function drawGrid() {
ctx.fillStyle = "#009EFF";
ctx.fillRect(0, 0, 400, 400);
ctx.strokeStyle = "black";
ctx.lineWidth = 1;
// The for loop that draws the x-axis
for (x = 0; x <= 400; x += 20) {
ctx.moveTo(x, 0);
ctx.lineTo(x, 400);
ctx.stroke();
}
// The for loop that draws the y-axis
for (y = 0; y <= 400; y += 20) {
ctx.moveTo(0, y);
ctx.lineTo(400, y);
ctx.stroke();
}
}
drawGrid();
function mousePosToCanvasPos(mouseX, mouseY) {
var canvasPos = canvas.getBoundingClientRect();
return {
x: Math.floor((mouseX - canvasPos.x) / 20) * 20,
y: Math.floor((mouseY - canvasPos.y) / 20) * 20,
};
}
// Function that clicks and fill grid boxes w / color
function colorPicker() {
canvas.addEventListener("click", function(event) {
var newColor = color.value;
ctx.fillStyle = newColor;
var canvasCellPos = mousePosToCanvasPos(event.x, event.y);
ctx.fillRect(canvasCellPos.x + 1, canvasCellPos.y + 1, 18, 18);
console.log(event.x, event.y);
console.log(newColor);
});
}
colorPicker();
#canvas {
border: 1px solid black;
background-size: 100%;
display: block;
margin-top: 50px;
margin-left: auto;
margin-right: auto;
padding-left: 0;
padding-right: 0;
}
<div class="color-wheel">
Color: <input type="color" id="color" />
</div>
<canvas id="canvas" width="400" height="400"></canvas>

How to change the color of the circle on canvas every n seconds?

How could the size of the shadow change, every n seconds? I guess you have to constantly create a new circle and eliminate the previous one? How would this be done? And also, is not there a more optimal way?
function main() {
var canvas = document.getElementsByTagName("CANVAS")[0],
ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = document.documentElement.scrollHeight;
var cW = canvas.width,
cH = canvas.height;
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, cW, cH);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = "#FFF";
ctx.shadowBlur = 5;
ctx.shadowColor = "#FFF";
ctx.arc(cW/2, cH/2, 50, 0, 2 * Math.PI, false);
ctx.fill();
ctx.closePath();
}
window.addEventListener("load", main);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<canvas></canvas>
</body>
</html>
Create a setInterval & an array of colors. Use Math.random to randomly select any color.
Modify the main function to accept colors as two parameters.
function main(bckColor, circleColor) {
var canvas = document.getElementsByTagName("CANVAS")[0],
ctx = canvas.getContext("2d");
if (canvas.height) {
canvas.height = 0;
}
canvas.width = window.innerWidth;
canvas.height = document.documentElement.scrollHeight;
var cW = canvas.width,
cH = canvas.height;
ctx.fillStyle = bckColor || "#000";
//ctx.fillStyle = "red" ;
ctx.fillRect(0, 0, cW, cH);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = circleColor || "#FFF";
ctx.shadowBlur = 5;
ctx.shadowColor = "#FFF";
ctx.arc(cW / 2, cH / 2, 50, 0, 2 * Math.PI, false);
ctx.fill();
ctx.closePath();
}
var colorArray = ['red', 'green', 'yellow', 'blue', 'pink', 'brown', 'orange']
var changeColor = setInterval(function() {
let bckColor = colorArray[Math.floor(Math.random() * 7 + 1)];
let circleColor = colorArray[Math.floor(Math.random() * 7 + 1)];
main(bckColor, circleColor)
}, 2000)
window.addEventListener("load", main);
<canvas></canvas>
instead of animating the canvas itself with a redraw every x seconds, i would suggest using an overlay , create a circle div, position it over the canvas' circle and animate its shadow using css, you'll have all the controls you want like the shadow's color and distance, animation speed ..etc.
here's a fiddle ( the overlay is better positionned )
function main() {
var canvas = document.getElementsByTagName("CANVAS")[0],
ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = document.documentElement.scrollHeight;
var cW = canvas.width,
cH = canvas.height;
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, cW, cH);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = "#FFF";
ctx.shadowBlur = 5;
ctx.shadowColor = "#FFF";
ctx.arc(cW / 2, cH / 2, 50, 0, 2 * Math.PI, false);
ctx.fill();
ctx.closePath();
// position the overlay over the circle
overlay.style.top = (cH / 2 - 99) + 'px'
overlay.style.left = (cW / 2 - 50) + 'px'
}
window.addEventListener("load", main);
main()
const animationDuration = 2;
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
overlay.style.animationDuration = animationDuration + 's';
setInterval(function() {
overlay.style.color = getRandomColor()
}, animationDuration * 1000)
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
canvas {
width: 100vw;
height: 100vh;
display: block;
}
#overlay {
border-radius: 50%;
background: none;
animation: shadow linear infinite;
margin: auto;
transform: translate(0, 50%);
color: green;
position: absolute;
z-index: 99;
width: 100px;
height: 93px;
}
#keyframes shadow {
0% 100% {
box-shadow: 0 0 0
}
50% {
box-shadow: 0 0 50px 20px
}
}
<canvas></canvas>
<div id="overlay">
</div>

Apply shadowBlur only to only 1 element on HTML Canvas

In my HTML canvas, I'm trying to apply the style shadowBlur, ONLY to the text element that says 'Artwork 1'.
But current if you see by running the code snippet, the shadowBlur gets applied to every other element too.
I also tried using ctx.save() and ctx.restore() too but it doesnt seem to work.
Any help is appreciated
var container = 'body';
var size = {
x: $(container).width(),
y: $(container).height()
};
var canvas = $('<canvas/>').attr({width: size.x, height: size.y}).appendTo(container),
ctx = canvas.get(0).getContext("2d");
ctx.globalCompositeOperation = 'xor';
window.requestFrame = (function(){
return window.requestAnimationFrame
})();
function render(){
ctx.clearRect(0,0,size.x,size.y);
ctx.lineWidth = 10;
ctx.strokeStyle = '#fff';
ctx.shadowColor = '#fff';
ctx.beginPath();
ctx.moveTo(-20,size.y/2);
for(var x = 0; x < size.x; x++){
ctx.lineTo(x,size.y/2+0.6*(20),1,1);
if (x == 100.00) {
ctx.font = "20px Arial";
ctx.fillStyle = "red";
ctx.fillText("Artwork 1 ",x,(size.y/2+0.6*(20)- 25 ));
ctx.shadowBlur = 50; /* this is applied to all elements instead of just the text*/
ctx.save();
ctx.fillStyle = "red";
ctx.fillRect(x, (size.y/2+0.6*(20)- 10 ), 20, 20);
}
if (x == 300.00) {
ctx.font = "20px Arial";
ctx.fillStyle = "red";
ctx.fillText("Artwork 2 ",x,(size.y/2+0.6*(20)- 25 ));
ctx.fillStyle = "red";
ctx.fillRect(x, (size.y/2+0.6*(20)- 10 ), 20, 20);
}
}
ctx.stroke();
requestFrame(render);
} /* END fn render */
render();
html, body {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px;
overflow: hidden;
background-color: #000;
}
html canvas, body canvas {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
}
<div>test</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Set the shadow before rendering the text, then turn it off afterward:
ctx.shadowBlur = 20; // call before draw operation require shadow
ctx.fillText("Artwork 1 ",x,(size.y/2+0.6*(20)- 25 ));
ctx.shadowBlur = 0; // remove shadow
Notice since the shadow in the previous code is overdrawn several times the result of new code will make it appear "weaker" which either force you to use a smaller blur radius (as shown) or to overdraw the text a couple of times (will require a different composition mode than xor).
The save() call can be removed.
var container = 'body';
var size = {
x: $(container).width(),
y: $(container).height()
};
var canvas = $('<canvas/>').attr({width: size.x, height: size.y}).appendTo(container),
ctx = canvas.get(0).getContext("2d");
ctx.globalCompositeOperation = 'xor';
window.requestFrame = (function(){
return window.requestAnimationFrame
})();
function render(){
ctx.clearRect(0,0,size.x,size.y);
ctx.lineWidth = 10;
ctx.strokeStyle = '#fff';
ctx.shadowColor = '#fff';
ctx.beginPath();
ctx.moveTo(-20,size.y/2);
for(var x = 0; x < size.x; x++){
ctx.lineTo(x,size.y/2+0.6*(20),1,1);
if (x == 100.00) {
ctx.font = "20px Arial";
ctx.fillStyle = "red";
ctx.shadowBlur = 20; /* this is applied to all elements instead of just the text*/
ctx.fillText("Artwork 1 ",x,(size.y/2+0.6*(20)- 25 ));
ctx.shadowBlur = 0;
ctx.fillStyle = "red";
ctx.fillRect(x, (size.y/2+0.6*(20)- 10 ), 20, 20);
}
if (x == 300.00) {
ctx.font = "20px Arial";
ctx.fillStyle = "red";
ctx.fillText("Artwork 2 ",x,(size.y/2+0.6*(20)- 25 ));
ctx.fillStyle = "red";
ctx.fillRect(x, (size.y/2+0.6*(20)- 10 ), 20, 20);
}
}
ctx.stroke();
requestFrame(render);
} /* END fn render */
render();
html, body {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px;
overflow: hidden;
background-color: #000;
}
html canvas, body canvas {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
}
<div>test</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

(HTML5 Canvas) Fillstyle img doesnt move with my terrain path

I´m writting a canvas game. I have some random produced terrain made with lineTo(), closePath() and filled out with an img as fillStyle. So far so good. But when i move the terrain with js the img doesnt move with it and stays on the same place. Any Ideas? Tnx.
You need to translate the canvas with the movement before doing the fill. Also remember to beginPath before making your shape.
var pattern = document.getElementById('pattern');
var can = document.getElementById('can');
var ctx = can.getContext('2d');
var w = can.width = 300;
var h = can.height = 200;
pattern.width = pattern.height = 20;
var pctx = pattern.getContext('2d');
pctx.fillStyle = 'white';
pctx.fillRect(0, 0, 20, 20);
pctx.fillStyle = 'red';
pctx.fillRect(0, 0, 10, 10);
pctx.fillRect(10, 10, 10, 10);
pctx.fillRect(2, 12, 6, 6);
pctx.fillRect(12, 2, 6, 6);
var p = ctx.createPattern(pattern, 'repeat');
var x = 50;
var y = 50;
var radius = 50;
var xStep = 1;
var yStep = 2;
var trans = "on";
function ani() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, w, h);
ctx.moveTo(x, y);
// beginPath clears any existing path
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 20);
ctx.fillStyle = p;
if (trans == "on") {
ctx.save();
// translate will offset the fill pattern
ctx.translate(x, y);
ctx.fill();
ctx.restore();
} else {
ctx.fill();
}
x += xStep;
y += yStep;
if (x > (w - radius) || x < radius) xStep *= -1;
if (y > (h - radius) || y < radius) yStep *= -1;
requestAnimationFrame(ani);
}
ani();
var btnOff = document.getElementById('trans_off');
var btnOn = document.getElementById('trans_on');
btnOff.addEventListener('click',function(){
btnOff.className = "selected";
btnOn.className = "";
trans = "off";
});
btnOn.addEventListener('click',function(){
btnOff.className = "";
btnOn.className = "selected";
trans = "on";
});
body {
background-color: #555555;
color: #F0F0F0;
font-family: sans-serif;
}
button {
color: #cccccc;
background-color: #333333;
border: 1px solid #cccccc;
}
button.selected {
color: white;
font-weight: bold;
}
Translate
<button id="trans_off">off</button>
<button id="trans_on" class="selected">on</button>
<hr/>
<canvas id="pattern"></canvas>
<canvas id="can"></canvas>

CSS3: change the color of the ball every time it bounces off the canvas wall

I have to create a ball game in HTML5/CSS3. JSFiddle for the same could be seen.
Now what I want is to change the ball color every time it bounces off the wall.
var context;
var dx = 4;
var dy = 4;
var y = 150;
var x = 10;
function draw() {
context = myCanvas.getContext('2d');
context.clearRect(0, 0, 300, 300);
context.beginPath();
context.arc(x, y, 20, 0, Math.PI * 2, true);
context.closePath();
context.fill();
if (x < 0 || x > 300)
dx = -dx;
if (y < 0 || y > 300)
dy = -dy;
x += dx;
y += dy;
}
setInterval(draw, 10);
#container {
text-align: center;
}
#myCanvas {
background: #fff;
border: 1px solid #cbcbcb;
text-align: center;
}
<div id="container">
<div>
<canvas id="myCanvas" width="300" height="300"></canvas>
</div>
</div>
I don't know how to do it. Can css3 be used to do this?
The random color function comes from here: https://stackoverflow.com/a/1484514/2042240
This will make it change at every bounce.
https://jsfiddle.net/e0b1gkc4/4/
var context;
var dx= 4;
var dy=4;
var y=150;
var x=10;
function draw(){
context= myCanvas.getContext('2d');
context.clearRect(0,0,300,300);
context.beginPath();
context.arc(x,y,20,0,Math.PI*2,true);
context.closePath();
context.fill();
if( x<0 || x>300){
dx=-dx;
context.fillStyle = getRandomColor();
}
if( y<0 || y>300){
dy=-dy;
context.fillStyle = getRandomColor();
}
x+=dx;
y+=dy;
}
setInterval(draw,10);
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}

Categories

Resources