I have a html5 canvas. I need to show the fixed portion of it in the div(Div1). When I swipe inside Div1, I need to scroll the canvas. So as I scroll, I'll see corresponding part of the canvas.
I tried something like this:
<div id="Div1" style=" float: left; width: 50px; overflow:hidden; ">
<canvas id="myCanvas1" width="200px" style="border: 1px solid #ff0000; position: absolute;">
</canvas>
</div>
jsFiddled here
it won't work (scrolling canvas from inside div in some 'design' conditions), first your overflow is hidden. Try scrolling the content inside the canvas instead.
OR, try this : http://jsfiddle.net/9g3GG/2/
<div id="Div1" style=" float: left; width: 150px; overflow:scroll; ">
<canvas id="myCanvas1" width="200" style="border:1px solid #ff0000;">asdf asd as asfqwe asd asdfasdf asd as asfqwe asd asdfasdf asd as asfqwe asd asdf</canvas>
</div>
Here is a demo of using an oversize canvas, and scrolling with mouse movements by adjusting the CSS margin: https://jsfiddle.net/ax7n8944/
HTML:
<div id="canvasdiv" style="width: 500px; height: 250px; overflow: hidden">
<canvas id="canvas" width="10000px" height="250px"></canvas>
</div>
JS:
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
var dragging = false;
var lastX;
var marginLeft = 0;
for (var i = 0; i < 1000; i++) {
context.beginPath();
context.arc(Math.random() * 10000, Math.random() * 250, 20.0, 0, 2 * Math.PI, false);
context.stroke();
}
canvas.addEventListener('mousedown', function(e) {
var evt = e || event;
dragging = true;
lastX = evt.clientX;
e.preventDefault();
}, false);
window.addEventListener('mousemove', function(e) {
var evt = e || event;
if (dragging) {
var delta = evt.clientX - lastX;
lastX = evt.clientX;
marginLeft += delta;
canvas.style.marginLeft = marginLeft + "px";
}
e.preventDefault();
}, false);
window.addEventListener('mouseup', function() {
dragging = false;
}, false);
It is better to scroll inside the canvas, see this Phaser plugin to do that https://jdnichollsc.github.io/Phaser-Kinetic-Scrolling-Plugin/
"scroll" in canvas , you need to handle 2 case :
bind event "mousedown" in this canvas and bind event "mouseup" in "mousedown" binding function.
bind event " DOMmouseup" in this canvas . User can wheel button in mouse to scroll.
To show canvas like a scroll
Redraw canvas
Use clip() in canvas. Re-set the rectangle of this clip to show your canvas
Please remove "position:absolute" in your css of canvas . And set height for your "div"
Hope it'll help you
The lines of the div are drawn. set line size to 0:
DIVofCanvas {
line-height: 0px;
}
Related
I try to make drawing app on canvas. It works well in full screen but when I set its width and height according to a div container. It didn't work correctly. It starts painting from the right rather than the top left.
Here is my code pen link: https://codepen.io/pranaysharma995/pen/GRpGVmG.
div class="container">
<div class="col-md-4 col-md-offset-4 " id="canvas-container">
<canvas id="canvas">
</canvas></div>
#canvas-container{
position: relative;
width: 600px;
height: 600px;
background-color: #f3f6f7;
}
You have to offset the mouse position with the canvas.getBoundingClientRect
var canvas = document.querySelector("#canvas");
var container = document.querySelector(".col-md-4");
canvas.width = container.offsetWidth;
canvas.height = container.offsetHeight;
var c = canvas.getContext('2d');
c.fillStyle = "red";
c.strokeStyle = "red";
c.lineWidth = 5;
c.lineCap = "round";
function draw(e) {
var rect = canvas.getBoundingClientRect();
var x = e.clientX - rect.left
var y = e.clientY - rect.top
c.lineTo(x, y);
c.stroke();
}
canvas.addEventListener("mousemove", draw);
.container {
position: absolute;
left: 50px;
top: 25px
}
#canvas-container {
position: relative;
width: 200px;
height: 200px;
background-color: #f3f6f7;
}
<div class="container">
<div class="col-md-4 col-md-offset-4 " id="canvas-container">
<canvas id="canvas"></canvas>
</div>
</div>
I'm creating an interactive art piece, which people can collaborate on. What I want is that there is a library of icons people can use. And when clicking on them, the mouse gets a class and thus when clicking on a specific cell in the table, the cell will get the icon as their background image.
(Now I know I will need a database etc, but that's for later. First things first.)
I did something similar a long time ago, but I don't know how to edit this in order to work for this project:
function nextPic() {
if ( $('html,body').css('cursor').indexOf('cursor2.png') > 0 )
{
counter += 1;
if (counter > myPictures.length - 1) {
// counter = 0;
}
else {
element.style.backgroundImage = "url(" + myPictures[counter] + ")";
}
}
It just works according to the image on the cursor. Not ideal at all, it bugged ALL the time.
I've looked at a code for pixel art, which (kind of) does what needs t one done. But not quite.
The pixel art fiddle here:
https://jsfiddle.net/bxstmufj/
So here is an example of someone doing what you want but instead of in a table grid in a canvas. Mad props to them for putting this out:
http://www.williammalone.com/articles/create-html5-canvas-javascript-drawing-app/
After the basic drawing on a canvas they add the ability to pick colors. Notice how they save the picked color into a variable that is then called on for the canvas reDraw() function.
The same thing can be done with icons. Simply having an onClick event for whatever icon is clicked just like they did with colors (in their case they chose mousedown event):
$('#choosePurpleSimpleColors').mousedown(function(e){
curColor_simpleColors = colorPurple;
});
That is the event handler they put on the purple button for example. You can see this by inspecting the element (button) then on the right click Event Handlers then go to the mousedown event and then you can click on the javascript file location where this code is. (All of this done in chrome inspect{right click, then pick inspect})
Now if you did not want to do it on a canvas but instead a a table/grid all you would do is set onClick events for the cells. They would then call on the color/icon variable and set them for that cell.
Let me know if you would like an example for a grid/table. The canvas is a bit more of a complex answer but I suspect it is what you really prefer. The second example and beyond is really what you want so you could also pick icons to insert.
context = document.getElementById('canvas').getContext("2d");
$('#canvas').mousedown(function(e){
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;
paint = true;
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);
redraw();
});
$('#canvas').mousemove(function(e){
if(paint){
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
redraw();
}
});
$('#canvas').mouseup(function(e){
paint = false;
});
$('#canvas').mouseleave(function(e){
paint = false;
});
var clickX = new Array();
var clickY = new Array();
var clickDrag = new Array();
var paint;
function addClick(x, y, dragging)
{
clickX.push(x);
clickY.push(y);
clickDrag.push(dragging);
}
function redraw(){
context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas
context.strokeStyle = "#df4b26";
context.lineJoin = "round";
context.lineWidth = 5;
for(var i=0; i < clickX.length; i++) {
context.beginPath();
if(clickDrag[i] && i){
context.moveTo(clickX[i-1], clickY[i-1]);
}else{
context.moveTo(clickX[i]-1, clickY[i]);
}
context.lineTo(clickX[i], clickY[i]);
context.closePath();
context.stroke();
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="canvas" width="490" height="220" style="border: solid 1px black;"></canvas>
Fixed!
<div id="p1" class="pen"></div>
<div id="p2" class="pen"></div>
<div id="art">
<div class="row">
<div class="pixel"></div>
<div class="pixel"></div>
</div>
</div>
icon = '(icon.png)'
$('#p1').click(function (){
icon = "icon2.png";
alert(icon);
});
$('#p2').click(function (){
icon = "icon3.png";
alert(icon);
});
// onclick function classes
$(".pixel").click(function() {
//function that changes background to url
// $(this).css('background-image', var(icon));
// $(this).css("background-image", "url(" + icon")");
$(this).css("background-image", "url(" +icon +")");
});
#art {
display: table;
border-spacing: 1px;
background-color: black;
border: 1px solid black;
}
.row {
display: table-row;
}
.pixel {
display: table-cell;
background-color: white;
width: 25px;
margin: 1px;
height: 25px;
background-size: contain;
}
.pen {
display: inline-block;
width: 40px;
height: 40px;
border: 2px solid black;
}
I don't know about using a class to set varied colors; a class would infer that they are all the same. You'd have to use ids to differentiate. You could pass the id and the color that you want to change the background to to a function and work it that way. Or you might opt to put the colors in an array and use the index number?
I made a basic example using the squares in your fiddle, to give an idea. As you can see, I only assigned one of the two a background value using css. The function can be tweaked to change background image if you want to use images instead of colors of course..
Hope this helps
function setPenColour(id, pixel) {
var myDiv = document.getElementById(id);
myDiv.style.backgroundColor = pixel;
}
#p1 {
background-color: grey;
}
#art {
display: table;
border-spacing: 1px;
background-color: black;
border: 1px solid black;
}
.row {
display: table-row;
}
.pixel {
display: table-cell;
background-color: white;
width: 25px;
margin: 1px;
height: 25px;
}
.pen {
display: inline-block;
width: 40px;
height: 40px;
border: 2px solid black;
}
<div id="p1" class="pen" onclick="setPenColour(id, '#00FF00')" ;></div>
<div id="p2" class="pen" style="background-color:blue;" onclick="setPenColour(id, 'red')"></div>
First look at my code:
IMAGE:
<img class="small" src="http://thecodeplayer.com/uploads/media/iphone.jpg" width="200"/>
BACKGROUND URL:
<div class="small" style="background-image: url('http://thecodeplayer.com/uploads/media/iphone.jpg')" ></div>
In the IMAGE I can use an attribute src in jquery
attr("src");
But how can I do it to in a background Image URL? I made this code and added an attribute but it's not working, any ideas?
<div class="small" style="background-image: url(attr(data-image-src='http://thecodeplayer.com/uploads/media/iphone.jpg')" ></div>
attr("data-image-src");
Now the reason why I want this to happen is that if you will look in this CodePen:
codepen
The sample code is an image and they used an attr(src) in jquery code, but I want it to be a background image URL, not an image.
To get the background-image in jQuery you can use:
var urlFull = $('.small').css('background-image');
//You will get the full value here
url = urlFull.split('"');
//But for using it properly you have to split it and get the url with `"` which will be holding the url.
console.log(url[1]); //You will get URL here
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="small" style="background-image: url('http://thecodeplayer.com/uploads/media/iphone.jpg')"></div>
Now for your real issue:
$(document).ready(function() {
var native_width = 0;
var native_height = 0;
var urlFull = $('.small').css('background-image');
//You will get the full value here
url = urlFull.split('"');
//But for using it properly you have to split it and get the url with `"` which will be holding the url.
//console.log(urlFull);
$(".large").css("background-image", urlFull);
//Now the mousemove function
$(".magnify").mousemove(function(e) {
//When the user hovers on the image, the script will first calculate
//the native dimensions if they don't exist. Only after the native dimensions
//are available, the script will show the zoomed version.
if (!native_width && !native_height) {
//This will create a new image object with the same image as that in .small
//We cannot directly get the dimensions from .small because of the
//width specified to 200px in the html. To get the actual dimensions we have
//created this image object.
var image_object = new Image();
image_object.src = url[1];
//This code is wrapped in the .load function which is important.
//width and height of the object would return 0 if accessed before
//the image gets loaded.
native_width = image_object.width;
native_height = image_object.height;
} else {
//x/y coordinates of the mouse
//This is the position of .magnify with respect to the document.
var magnify_offset = $(this).offset();
//We will deduct the positions of .magnify from the mouse positions with
//respect to the document to get the mouse positions with respect to the
//container(.magnify)
var mx = e.pageX - magnify_offset.left;
var my = e.pageY - magnify_offset.top;
//Finally the code to fade out the glass if the mouse is outside the container
if (mx < $(this).width() && my < $(this).height() && mx > 0 && my > 0) {
$(".large").fadeIn(100);
} else {
$(".large").fadeOut(100);
}
if ($(".large").is(":visible")) {
//The background position of .large will be changed according to the position
//of the mouse over the .small image. So we will get the ratio of the pixel
//under the mouse pointer with respect to the image and use that to position the
//large image inside the magnifying glass
var rx = Math.round(mx / $(".small").width() * native_width - $(".large").width() / 2) * -1;
var ry = Math.round(my / $(".small").height() * native_height - $(".large").height() / 2) * -1;
var bgp = rx + "px " + ry + "px";
//Time to move the magnifying glass with the mouse
var px = mx - $(".large").width() / 2;
var py = my - $(".large").height() / 2;
//Now the glass moves with the mouse
//The logic is to deduct half of the glass's width and height from the
//mouse coordinates to place it with its center at the mouse coordinates
//If you hover on the image now, you should see the magnifying glass in action
$(".large").css({
left: px,
top: py,
backgroundPosition: bgp
});
}
}
})
})
/*Some CSS*/
* {
margin: 0;
padding: 0;
text-align: center
}
.magnify {
width: 200px;
margin: 50px auto;
position: relative;
cursor: none;
display: inline-block;
}
/*Lets create the magnifying glass*/
.large {
width: 175px;
height: 175px;
position: absolute;
border-radius: 100%;
/*Multiple box shadows to achieve the glass effect*/
box-shadow: 0 0 0 7px rgba(255, 255, 255, 0.85), 0 0 7px 7px rgba(0, 0, 0, 0.25), inset 0 0 40px 2px rgba(0, 0, 0, 0.25);
/*hide the glass by default*/
display: none;
background-repeat: no-repeat;
}
/*To solve overlap bug at the edges during magnification*/
.small {
display: block;
width: 200px;
height: 400px;
float: left;
background-size: contain;
background-repeat: no-repeat;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Lets make a simple image magnifier -->
<div class="magnify">
<!-- This is the magnifying glass which will contain the original/large version -->
<div class="large"></div>
<!-- This is the small image -->
<div class="small" style="background-image:url('http://thecodeplayer.com/uploads/media/iphone.jpg')" width="200" />
</div>
</div>
Codepen if you want.
I hope this woks for you.
I think you have missed a Single quote in your attribute.
Change
<div class="small" style="background-image: url(http://thecodeplayer.com/uploads/media/iphone.jpg')" ></div>
to
<div class="small" style="background-image: url('http://thecodeplayer.com/uploads/media/iphone.jpg')" ></div>
Hope this helps.
First you have to set '' to url
<div class="small" style="background-image: url('http://thecodeplayer.com/uploads/media/iphone.jpg')" ></div>
To get url of background-image:
var url=$('.small').attr('src')
$('.large').css('background-image',"url('"+ url + "')");
.large{
background-repeat: no-repeat;
width: 175px;
height: 175px;
background-size: cover;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img class="small" src="http://thecodeplayer.com/uploads/media/iphone.jpg" width="200"/>
<div class="large"></div>
I am trying to use drag and drop to move pictures from one <div> to another.
Currently, I can move the pictures anywhere in the destination <div>, but what I really want is that the pictures snap together when dropped. Ideally, they would be able to snap together on any side (not just, for example, on the bottom or on the right).
I've tried a few different things (including using <canvas>) and it didn't work.
This is what I have so far:
var clone;
var offsetx = null;
var offsety = null;
var isClone = false;
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
offsetx = ev.target.offsetLeft - event.clientX;
offsety = ev.target.offsetTop - event.clientY;
ev.dataTransfer.setData("text", ev.target.id);
}
function dropTrash(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
var remove = document.getElementById(data);
remove.parentNode.removeChild(remove);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
}
function dropClone(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
var num = Math.random() * (1000 - 1) + 1;
isClone = true;
clone = document.getElementById(data).cloneNode(true);
clone.id = "newId" + num.toString();
clone.style.position = "absolute";
clone.style.left = (event.clientX+offsetx)+"px";
clone.style.top = (event.clientY+offsety)+"px";
ev.target.appendChild(clone);
}
html, body {
height: 100%;
padding: 0;
margin: 0;
}
div {
width: 50%;
height: 50%;
float: left;
}
#div1 {
background: #DDD;
}
#div2 {
background: #AAA;
}
#div3 {
background: #777;
}
#div4 {
background: #444;
}
#imgDiv {
width: 611px;
height: 324px;
border: 5px solid #DDD;
}
<div id="div1">
</div>
<div id="div2">
</div>
<div id="div3" ondrop="dropTrash(event)" ondragover="allowDrop(event)">
<img id="drag1" src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/18/Bartagame_fcm.jpg/1200px-Bartagame_fcm.jpg" draggable="true" ondragstart="drag(event)" width="105" height="105">
<img id="drag2" src="http://www.earthtimes.org/newsimage/lizard_Ngo_Van_Tri_big_281.jpg" draggable="true" ondragstart="drag(event)" width="105" height="105">
</div>
<div id="div4">
<div align="center" id="imgDiv" ondrop="dropClone(event)" ondragover="allowDrop(event)"></div>
</div>
When you start dragging an image, you need to store the position of the cursor, relative to that particular image.
There are multiple position properties in the MouseEvent that will help you calculate that, but if browser support is not an issue, I would go for MouseEvent.offsetX and MouseEvent.offsetY. From the docs:
The offsetX/offsetY read-only property of the MouseEvent interface provides the offset in the X/Y coordinate of the mouse pointer between that event and the padding edge of the target node.
So, on dragstart, you will do just:
x = e.offsetX;
y = e.offsetY;
Then, when you drop the image in your, let's call it canvas (note the italics as it is not a <canvas> element, but any other element that you use as your drop zone, a <div> in this particular example), you need to know the position of the cursor relative to that canvas, so you may think you could use offsetX and offsetY again, and your are partially right. That would give you the expected value if you drop the image on the canvas itself, but there may be other images in it already, and you may drop the current one on top of another one, getting the offsetX and offsetY relative to that one instead.
What you can do is use MouseEvent.pageX and MouseEvent.pageY and, from that value, subtract the position of the (upper-left corner) of that canvas element, which you can get from HTMLElement.offsetLeft and HTMLElement.offsetTop:
e.pageX - imageCanvas.offsetLeft;
e.pageY - imageCanvas.offsetTop;
With this you will get the position of the cursor relative to the canvas element.
Now, you need to subtract the x and y values that you stored on dragstart, and that will give you the left and top values of the upper-left corner of the dragged image, relative to the canvas element:
image.style.left = (e.pageX - imagesCanvas.offsetLeft - x) + 'px';
image.style.top = (e.pageY - imagesCanvas.offsetTop - y) + 'px';
All together it will look like this:
let x;
let y;
let currentTarget = null;
let cloneElement = false;
function startDrag(e, clone) {
const target = e.target;
if (target.tagName === 'IMG') {
x = e.offsetX;
y = e.offsetY;
currentTarget = target;
cloneElement = clone;
}
}
function cloneImage(e) {
startDrag(e, true);
}
function moveImage(e) {
startDrag(e, false);
}
function removeImage(e) {
if (!cloneElement) {
currentTarget.remove();
}
}
function stickImage(e) {
const image = cloneElement ? currentTarget.cloneNode(true) : currentTarget;
imagesCanvas.appendChild(image);
// + 1 for the border
image.style.left = (e.pageX - imagesCanvas.offsetLeft - x + 1) + 'px';
image.style.top = (e.pageY - imagesCanvas.offsetTop - y + 1) + 'px';
currentTarget = null;
}
function allowDrag(e) {
e.preventDefault();
}
// Bind event listeners:
const imagesBarElement = document.getElementById('imagesBar');
const imagesCanvasElement = document.getElementById('imagesCanvas');
document.addEventListener('dragenter', allowDrag);
document.addEventListener('dragover', allowDrag);
imagesBarElement.addEventListener('dragstart', cloneImage);
imagesBarElement.addEventListener('drop', removeImage);
imagesCanvasElement.addEventListener('dragstart', moveImage);
imagesCanvasElement.addEventListener('drop', stickImage);
body {
margin: 0;
font-size: 0;
display: flex;
flex-direction: column;
height: 100vh;
user-select: none;
}
img {
width: 100px;
height: 100px;
}
#imagesBar {
height: 100px;
border-bottom: 1px solid #CCC;
padding: 10px 0;
}
#imagesBar > img {
margin: 0 0 0 10px;
}
#imagesCanvas {
position: relative;
background: #EEE;
flex-grow: 1;
overflow: hidden;
}
#imagesCanvas > img {
position: absolute;
}
<div id="imagesBar">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/18/Bartagame_fcm.jpg/1200px-Bartagame_fcm.jpg" draggable="true">
<img src="http://www.earthtimes.org/newsimage/lizard_Ngo_Van_Tri_big_281.jpg" draggable="true">
</div>
<div id="imagesCanvas"></div>
I'm making an image drawing application with html and javascript. I made it with canvas and added some buttons(<div>s) on the canvas. Of course, canvas have onmousedown, onmouseup, onmousemove handlers to draw lines. But when I move mouse to the position of buttons or out of the canvas, then return to the canvas area, line breaks.
refer to the code(http://jsfiddle.net/coldmund/MQKMv/) please.
html:
<div>
<div style="position: absolute; margin-top: 0px; margin-left: 0px;"><canvas id="canvas" width="500" height="300" onmousedown="down(event)" onmouseup="up()" onmousemove="move(event)" style="border: 1px solid"></canvas></div>
<div style="position: absolute; margin-top: 100px; margin-left: 100px; width: 100px; height: 100px; background: #ff0000; opacity: 0.5"></div>
</div>
js:
var mouseDown = false;
down = function(e)
{
mouseDown = true;
prevX = e.clientX;
prevY = e.clientY;
};
up = function()
{
mouseDown = false;
};
move = function(e)
{
if( mouseDown === false )
return;
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.lineWidth = 5;
context.lineCap = 'round';
context.beginPath();
context.moveTo( prevX, prevY );
context.lineTo( e.clientX, e.clientY );
context.stroke();
prevX = e.clientX;
prevY = e.clientY;
};
Here is a fiddle with a potential solution (fiddle). This basically toggles the buttons css property to pointer-events:none while drawing on the canvas.
The differences between your code and mine basically reduce to the following:
// CSS
.no-pointer-events {
pointer-events:none;
}
// Inside the mousedown handler
document.getElementById( "button1" ).class = "no-pointer-events";
// Inside the mouseup handler
document.getElementById( "button1" ).class = "";