i cant get the clicked elements child and change the div's background to that image - javascript

index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF[![enter image description here][1]][1]-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Cubix Worlds Planner</title>
</head>
<body>
<div class="navbar">
<button class="btn">Reset</button>
</div>
<div class="blocks">
<button class="block"><img src="assets/blocks/items3.png"></button>
<button class="block"><img src="assets/blocks/items4.png"></button>
<button class="block"><img src="assets/blocks/items5.png"></button>
<button class="block"><img src="assets/blocks/items6.png"></button>
<button class="block"><img src="assets/blocks/items8.png"></button>
<button class="block"><img src="assets/blocks/items10.png"></button>
</div>
<div class="container">
</div>
<script src="main.js"></script>
</body>
</html>
main.js
const container = document.querySelector('.container');
const resetBtn = document.querySelector('.btn');
const { body } = document;
const blocklist = document.querySelector('.blocks');
const block = document.querySelector('.block');
let draw = false;
let blockimg = '';
function populate(size) {
document.querySelector('.block').addEventListener('click', e=>{
if (e.target.classList.contains('img')) {
blockimg = e.target.querySelector('img').getAttribute('src');
}
});
container.style.setProperty('--size', size);
for (let i = 0; i < size * size; i++) {
const div = document.createElement('div');
div.classList.add('pixel');
div.addEventListener('mouseover', function(){
if(!draw) return;
div.style.backgroundColor = blockimg;
});
div.addEventListener('mousedown', function(){
div.style.backgroundColor = blockimg;
});
container.appendChild(div);
}
}
window.addEventListener("mousedown", function(){
draw = true;
});
window.addEventListener("mouseup", function(){
draw = false;
});
function reset() {
container.innerHTML = '';
populate(100);
}
resetBtn.addEventListener('click', reset);
populate(100);
let zoomActivate = false;
window.addEventListener('keydown', (e) => {
if(e.key === 'z') {
zoomActivate = !zoomActivate;
}
});
window.addEventListener("mousemove", (e) => {
const { clientX: x, clientY: y } = e;
if(zoomActivate) {
body.style.transform = 'scale(2)';
body.style.transformOrigin = `${x}px ${y}px`;
} else {
body.style.transform = 'none';
}
});
Over the past few days, I have been attempting to create a website for pixel art. However, instead of using colors, I have opted to use blocks that can be placed on a canvas. Unfortunately, I have encountered an issue with the code I have written, as it does not allow me to select the specific block that I wish to place on the canvas. As a result, I am unable to properly generate the desired pixel art.
website preview
https://i.stack.imgur.com/ydp8M.png

Related

How to make newly cloned buttons work with an existing eventlistener?

On the press of the button 'leave' I want 10 new 'leave' buttons to be displayed on the screen. Each one of these buttons needs to display 10 new buttons on the screen when clicked.
But only the original 'leave' button displays 10 new buttons, the newly cloned ones don't.
Javascript code:
const container = document.querySelector('.container');
const leaveButton = document.querySelector('#leave');
leaveButton.addEventListener('click', () => {
for (let i = 0; i < 10; i++) {
const newButton = document.createElement('button');
newButton.innerHTML = leaveButton.innerHTML;
newButton.style.top = Math.random() * window.innerHeight + 'px';
newButton.style.left = Math.random() * window.innerWidth + 'px';
newButton.setAttribute("id", "leave");
container.appendChild(newButton);
}
});
HTML code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>PressTheButton</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<button id="leave">Leave</button>
<h1>It's simple</h1>
<p>Just click the buttons</p>
</div>
<script src="script.js"></script>
</body>
</html>
Instead of adding the event listener to a fixed button you should work with delegated event listening. In the snippet below I added the click event to the parent container. Inside the event listener callback function I briefly check, wether the .textContent of the clicked element is equal to "Leave" and, if not, I return immediately without carrying out any action.
const container = document.querySelector('.container');
const leaveButton = document.querySelector('#leave');
container.addEventListener('click', ev => {
if (ev.target.textContent!=="Leave") return;
for (let i = 0; i < 10; i++) {
const newButton = document.createElement('button');
newButton.innerHTML = leaveButton.innerHTML;
newButton.style.top = Math.random() * window.innerHeight + 'px';
newButton.style.left = Math.random() * window.innerWidth + 'px';
newButton.setAttribute("id", "leave");
container.appendChild(newButton);
}
});
button {position:absolute}
<head>
<meta charset="UTF-8">
<title>PressTheButton</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<button id="leave">Leave</button>
<h1>It's simple</h1>
<p>Just click the buttons</p>
</div>

How to make canvas lines visible when dragging (no libraries, only vanilla JS, React.JS if necessary.)

I'd like to add lines by two clicks, when moving the mouse the line should be visible. When click left mouse button again the line should be added. Only left button should draw.
How should I change my code to do this? (for now it allows to create lines,
but they aren't visible before mouseup).
Any help is appreciated! Thanks!
const canvasEl = document.getElementById('drawContainer')
canvasEl.style.position = 'absolute'
canvasEl.style.top = '12%'
canvasEl.style.left = '32%'
var lines = [], line;
const context = canvasEl.getContext('2d')
const collapseLinesBtn = document.getElementById('collapse_lines')
let startPosition = {x: 0, y: 0}
let lineCoordinates = {x: 0, y: 0}
let isDrawStart = false
const getClientOffset = (event) => {
const {pageX, pageY} = event.clicks ? event.clicks[0] : event
const x = pageX - canvasEl.offsetLeft
const y = pageY - canvasEl.offsetTop
return { x, y }
}
const initialDraw = () => {
context.beginPath() //allows to prevent previously created lines from delete
context.moveTo(startPosition.x, startPosition.y)
context.lineTo(lineCoordinates.x, lineCoordinates.y)
context.stroke()
line = [];
line.push([lineCoordinates.x, lineCoordinates.y]);
console.log(line)
}
const mouseDownListener = (e) => {
startPosition = getClientOffset(e)
//isDrawStart = true // isDrawStart = true + clearCanvas() + initialDraw() from const mouseMoveListener = one visible line when dragging + coordinates
context.beginPath();
context.moveTo(e.offsetX, e.offsetY);
context.lineTo(e.offsetX, e.offsetY);
}
const mouseMoveListener = (event) => {
if(!isDrawStart)
return
lineCoordinates = getClientOffset(event)
//clearCanvas()
//initialDraw()
//initialDraw(!isDrawStart())
}
const mouseUpListener = (e) => {
isDrawStart = false
context.lineTo(e.offsetX, e.offsetY);
context.stroke();
}
const clearCanvas = () => {
context.clearRect(0, 0, canvasEl.width, canvasEl.height)
}
canvasEl.addEventListener('mousedown', mouseDownListener)
canvasEl.addEventListener('mousemove', mouseMoveListener)
canvasEl.addEventListener('mouseup', mouseUpListener)
collapseLinesBtn.addEventListener('click', function clear() {
context.clearRect(0, 0, window.innerWidth, window.innerHeight);
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
#collapse_lines {
position: absolute;
bottom: 75px;
left: 47%;
padding: 10px 25px;
font-size: 1rem;
}
</style>
<title>Test Task</title>
</head>
<body>
<div id="main_container">
<canvas id="drawContainer" width="700" height="700" style="border: 1px solid rgb(10, 10, 10)" ></canvas>
<button id="collapse_lines">collapse lines</button>
</div>
<script src="./app.js"></script>
</body>
</html>
In your mouseMoveListener just do something similar as you do in your mouseUpListener, without setting isDrawStart = false:
const mouseMoveListener = (event) => {
if(!isDrawStart)
return
lineCoordinates = getClientOffset(event)
// Clear the canvas each frame
clearCanvas()
// Similar to mouseUpListener
context.lineTo(lineCoordinates.x, lineCoordinates.y);
context.stroke();
}

I want to convert paper.js Examples from paperscript to javascript

I am Japanese and I apologize for my unnatural English, but I would appreciate it if you could read it.
I learned how to convert paperscript to javascript from the official documentation.
Its means are as follows
Change the type attribute of the script tag to text/paperscript. <script type="text/paperscript" src="./main.js"></script>
Enable Paperscope for global use.  paper.install(window)
Specify the target of the canvas. paper.setup(document.getElementById("myCanvas"))
Write the main code in the onload window.onload = function(){ /* add main code */ }
Finally, add paper.view.draw()
The onFrame and onResize transforms as follows. view.onFrame = function(event) {}
onMouseDown, onMouseUp, onMouseDrag, onMouseMove, etc. are converted as follows. var customTool = new Tool(); customTool.onMouseDown = function(event) {};
I have tried these methods, but applying these to the Examples on the paper.js official site does not work correctly.
The following code is the result of trying these.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="https://unpkg.com/paper"></script>
<script type="text/javascript" src="./main.js"></script>
<title>Document</title>
</head>
<body>
<canvas id="myCanvas"></canvas>
</body>
</html>
paper.install(window);
console.log("run test")
var myCanvas = document.getElementById("myCanvas")
var customTool = new Tool();
window.onload = function(){
paper.setup(myCanvas)
var points = 25;
// The distance between the points:
var length = 35;
var path = new Path({
strokeColor: '#E4141B',
strokeWidth: 20,
strokeCap: 'round'
});
var start = view.center / [10, 1];
for (var i = 0; i < points; i++)
path.add(start + new Point(i * length, 0));
customTool.onMouseMove=function(event) {
path.firstSegment.point = event.point;
for (var i = 0; i < points - 1; i++) {
var segment = path.segments[i];
var nextSegment = segment.next;
var vector = segment.point - nextSegment.point;
vector.length = length;
nextSegment.point = segment.point - vector;
}
path.smooth({ type: 'continuous' });
}
customTool.onMouseDown=function(event) {
path.fullySelected = true;
path.strokeColor = '#e08285';
}
customTool.onMouseUp=function(event) {
path.fullySelected = false;
path.strokeColor = '#e4141b';
}
view.draw();
}
The original paperscript can be found here.
What is the problem with this code?
Thank you for reading to the end!
The var vector in the for loop is not getting the correct values in your code. Change the math operators and it will work like the paperjs demo.
Math operators (+ - * /) for vector only works in paperscript. In Javascript, use .add() .subtract() .multiply() .divide(). see http://paperjs.org/reference/point/#subtract-point
// paperscript
segment.point - nextSegment.point
// javascript
segment.point.subtract(nextSegment.point)
Here's a working demo of your example
paper.install(window);
console.log("run test")
var myCanvas = document.getElementById("myCanvas")
var customTool = new Tool();
window.onload = function() {
paper.setup(myCanvas)
var points = 15; //25
// The distance between the points:
var length = 20; //35
var path = new Path({
strokeColor: '#E4141B',
strokeWidth: 20,
strokeCap: 'round'
});
var start = view.center / [10, 1];
for (var i = 0; i < points; i++) {
path.add(start + new Point(i * length, 0));
}
customTool.onMouseMove = function(event) {
path.firstSegment.point = event.point;
for (var i = 0; i < points - 1; i++) {
var segment = path.segments[i];
var nextSegment = segment.next;
//var vector = segment.point - nextSegment.point;
var vector = segment.point.subtract(nextSegment.point);
vector.length = length;
//nextSegment.point = segment.point - vector;
nextSegment.point = segment.point.subtract(vector);
}
path.smooth({
type: 'continuous'
});
}
customTool.onMouseDown = function(event) {
path.fullySelected = true;
path.strokeColor = '#e08285';
}
customTool.onMouseUp = function(event) {
path.fullySelected = false;
path.strokeColor = '#e4141b';
}
view.draw();
}
html,
body {
margin: 0
}
canvas {
border: 1px solid red;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="https://unpkg.com/paper"></script>
<!-- you can add this back in -->
<!-- <script type="text/javascript" src="./main.js"></script> -->
<title>Document</title>
</head>
<body>
<!-- set any size you want, or use CSS/JS to make this resizable -->
<canvas id="myCanvas" width="600" height="150"></canvas>
</body>
</html>

How to make a button move?

I'm going to make 8 buttons move down to the bottom of screen one by one but I have a problem
here is my code :
var i = 0;
var j = 0;
while(i < 7){
i++;
interval[i] = setInterval(interval(), 10);
function interval(){
y[j]++;
if (parseInt(y[j]) >= window.innerHeight) {
if(j == y.length - 1){
debugger;
return clearInterval(interval[j]);
}
j++;
return interval();
}
button[j].style.top = y[j] + "px";
}
console.log(i);
}
var body = document.getElementById("body");
var button = [];
body.style.position = "relative";
var y = [];
for (var i = 0; i < 8; i++) {
y[i] = 0;
button[i] = document.createElement("button");
button[i].onclick = clickme();
button[i].innerHTML = "بازی";
button[i].style.fontFamily = "b nazanin";
button[i].style.fontSize = "32pt";
button[i].style.position = "absolute";
body.appendChild(button[i]);
}
var i = 0;
var j = 0;
var Interval = setInterval(interval(), 10);
function interval(){
y[j]++;
if (parseInt(y[j]) >= window.innerHeight) {
if(j == y.length - 1){
debugger;
return clearInterval(Interval[j]);
}
j++;
return interval();
}
button[j].style.top = y[j] + "px";
}
/*
var button2 = document.createElement("button");
button2.onclick = clickme();
button2.innerHTML = "بازی";
button2.style.fontFamily = "b nazanin";
button2.style.fontSize = "32pt";
body.appendChild(button);
body.appendChild(button2);
body.style.position = "relative";
button2.style.position = "absolute";
button.style.position = "absolute";
*/
function clickme() {
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="index.css">
</head>
<body id="body">
</body>
<script src="index.js"></script>
</html>
Code explained :
button is my buttons element array.
y is my button's Tops array.
My problem is that the first button will move 7 times(Number of Is) and anything stop.I don't know what to do.
Please help me.
Ok, I did it with just 2 buttons and it worked :
var button1 = document.getElementById("button1");
var button2 = document.getElementById("button2");
var startNext = false;
var y1 = 0;
var y2 = 0;
var interval1 = setInterval(function(){
y1++;
button1.style.top = y1 + "px";
if(y1>= window.innerHeight){
startNext = true;
return clearInterval(interval1);
}
},10);
var interval2 = setInterval(function(){
if(startNext){
y2++;
button2.style.top = y2 + "px";
if(y2 >= window.innerHeight){
return clearInterval(interval2);
}
}
},10);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="index.css">
</head>
<body id="body" style="position: relative;">
<button id="button1" style="position: absolute;">graege</button>
<button id="button2" style="position: absolute;">ges</button>
</body>
<script src="index.js"></script>
</html>

How can I let the user choose a background color using hex and css gradients

I would like to make it so that the user can input a hex into one text box and another hex into a different text box. This would then use linear-gradient so that it would gradient the first color to the second color. In the code snippet is an example of what it may produce. I would prefer to only use css and html but can use javascript if neccessary. Thanks to anyone who attempts to solve this problem any bit. I will respond to any questions in case I am being vague.
body {
background: linear-gradient(to right, #ffb6ce, #ff00ea);
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
I created an example.
const body = document.querySelector("body");
const startInput = document.querySelector("#start");
const endInput = document.querySelector("#end");
let startHex = "#fff";
let endHex = "#fff";
let gradient;
function styleBody(){
gradient = `linear-gradient(to right, ${startHex}, ${endHex})`;
body.style.background = gradient;
}
startInput.addEventListener("input", () => {
startHex = event.target.value;
styleBody();
});
endInput.addEventListener("input", () => {
endHex = event.target.value;
styleBody();
});
<input type="color" id="start">
<input type="color" id="end">
const colorPicker1 = document.querySelector("#picker1");
const colorPicker2 = document.querySelector("#picker2");
var firstColor = '#0F0';
var secondColor = '#F00'
document.body.addEventListener("input", gradientPick);
function gradientPick(event) {
if(event.target === colorPicker1){
firstColor = event.target.value;
}
if(event.target === colorPicker2){
secondColor = event.target.value;
}
document.body.style.background = `linear-gradient(${firstColor}, ${secondColor})`;
document.body.style.backgroundSize = "contain";
document.body.style.height = "100vh";
}
<input id="picker1" type="color" value="#ff0000">
<input id="picker2" type="color" value="#00ff00">

Categories