HTML5 setDragImage(): dragIcon.width does absolutely nothing - javascript

When using the HTML5 drag and drop API, it would appears though the .width property on has no impact on the width of an image being used as an icon for dragging. Take this fiddle for example: http://jsfiddle.net/cnAHv/7/. You can set dragIcon.width to anything you want, and it will not change the actual width of the icon.
Most of the resources on the web seem to arbitrarily set dragIcon.width to 100. Is this just a matter of people copying eachother's code without checking functionality?
So...
Is the width property on an image variable actually something that setDragImage() will accept?
If not, how would you set the width of the icon without manually changing sizing the image in a program like photoshop?

When you use an <img> in setDragImage Javascript will just use the actual image bitmap data, ignoring other attributes like width. Check the specs.
However if you do something like this:
function handleDragStart(e) {
var dragIcon = document.createElement('img');
dragIcon.src = 'http://jsfiddle.net/favicon.png';
dragIcon.width = '100';
var div = document.createElement('div');
div.appendChild(dragIcon);
document.querySelector('body').appendChild(div);
e.dataTransfer.setDragImage(div, -10, -10);
}
http://jsfiddle.net/cnAHv/9/
You will see the drag shadow now contains the bigger image. It occurs because when we use other visible HTML elements (that's why I appended the DIV to the body), the browser will use its rendered view as a drag image.

This answer might be a bit late but you can also use a canvas to scale your original image.
function handleDragStart(e) {
var dragIcon = document.createElement('img');
dragIcon.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC';
var width = 100;
var height = width * (3/4); // The height must be set explicitly. I'm assuming the image is 4:3 for this example
var c = document.createElement("canvas");
c.width = width;
c.height = height;
var ctx = c.getContext('2d');
ctx.drawImage(dragIcon,0,0,width,height);
dragIcon.src = c.toDataURL();
e.dataTransfer.setDragImage(dragIcon, -10, -10);
}
http://jsfiddle.net/cnAHv/138/
The only downside to this is that the canvas may be tainted if the image doesn't come from the same origin. More on tainted canvases here

Related

Canvas height changed by EaselJS. How to avoid this?

I'm using Easel JS to develop Canvas based Solitaire game.
TODO: Set height for canvas and draw all elements inside of that.
Issue: EaselJS change the canvas height automatically.
References:
How I set the height:
var gameBoard = document.getElementById("board");
gameBoard.style.height = window.innerHeight+"px";
gameBoard.height = gameBoard.offsetHeight;
gameBoard.style.height = "auto";
Without knowing what your goals are, it's hard to tell what the problem is exactly... but setting the CSS "canvas.style.height" property to "auto" seems to be the problem. The width and height properties (not CSS) are still what you set them to originally (1300 x 501).
Remove this line and you will be left with a canvas that is the size of the window when the page is loaded.
gameBoard.style.height = "auto";
If you want your canvas to have as many pixels as there are in the window, you will need to listen for the "resize" event and apply the values back to your canvas.
window.addEventListener("resize", function(){
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});

Canvas is stretching using drawImage

I am aware of having to set the size of a <canvas> element using the width and height attribute to avoid stretching. I have no CSS applied to it other than background-color.
I am using ctx.drawImage() to show a video. The weird thing is, my 640x480 video plays fine and is not stretched. It is only happening on my 640x360 videos for now.
I have created an angular directive that draws video onto a canvas element and it all works except for the stretching. Here is my code that draws the video element onto the canvas:
scope.renderPlayer = function()
{
var $this = this;
attributes.width = player.videoWidth;
attributes.height = player.videoHeight;
canvas.setAttribute('width', attributes.width);
canvas.setAttribute('height', attributes.height);
(function loop()
{
if (!$this.paused && !$this.ended)
{
ctx.drawImage($this, 0,0, attributes.width, attributes.height);
setTimeout(loop, 1000/30);
}
})();
};
player.addEventListener('play', scope.renderPlayer);
I assure you the source of the videos don't have that stretching artifacting on the bottom as shown in the image below (You can really see the pixels stretched on the bottom right). My initial width and height of the canvas element is 640x480 and it will change depending on the size of the loaded video.
Let me know if this CSS fixes it for you, I need it whenever I use canvas:
canvas {
display: block;
}
the canvas tag is susceptible to the same pitfalls as the img tag in that it renders extra space below it. You are correct to set the dimensions as HTML attributes though, what a pain.
I haven't worked with canvas in a while, but you can give ctx.drawImage($this) a try, also you can requestAnimationFrame and use it instead of setTimeout:
scope.renderPlayer = function()
{
var $this = this;
canvas.width = player.width; // if canvas is a Jquery Object, try canvas[0].width
canvas.height = player.height; // if canvas is a Jquery Object, try canvas[0].height
(function loop()
{
if (!$this.paused && !$this.ended)
{
ctx.drawImage($this);
setTimeout(loop, 1000/30);
}
})();
};
player.addEventListener('play', scope.renderPlayer);

How can I copy a hidden canvas object to image without a blurred image

I am rendering a QR code to a div, however the div is hidden. When I copy the canvas to an image with the correct size, the image is blurred.
var children = $("#trial").children();
var canvas = children[0];
var ctx = canvas.getContext('2d');
//ctx.scale(3,3);
var img = new Image();
img.width = "300";
img.src = canvas.toDataURL();
$("#imagetrial").html(img);
I have tried scaling it as in the commented code, but the raw image turns out small, and when stretching the image it is blurred. If the div is not hidden, the code works correctly, but I cannot show the canvas, I am only interested in the data url which is passed on to a pop up print page.
Does anyone know a way to adjust the canvas size in the hidden div so that it copies correctly?
You can set the width of a canvas (onscreen or offscreen) like this:
canvas.width = 300;
You may be running into some subpixel issues regardless of canvas and image size matching.
Every canvas applies anti aliasing that CANNOT be turned off if the image you're generating on the canvas contains graphical elements or images drawn at sub pixel coordinates.
See this article: http://sebleedelisle.com/2011/02/html5-canvas-sprite-optimisation
I ended up hiding the div by placing it offscreen, then the canvas gets copied correctly.

Unaccountable spreading image in HTML5 canvas

I am trying to write my first game in JavaScript and HTML5 but I am stuck. I want to only draw a image into HTML canvas which has set background-image but the image is still magnified and additionally bad positioned and I don't know why. Let's show my code.
In HTML file in body I have only canvas #gameCanvas, that's all.
And this is JavaSript code.
function prepare()
{
var canvas = $('#gameCanvas');
var context = canvas[0].getContext('2d');
$('#wrapper').css({"width": "704"});
canvas.css({"width": "704",
"height": "672",
"backgroundImage": "url(./images/map.png)"});
var player1 = new Image();
player1.src = "./images/player1.png";
player1.onload = function() {
context.drawImage(player1, 0, 0, 26, 36, 100, 100, 26, 36);
};
}
$(function(){
prepare();
})
And that's my weird result -> 1.result
I find out that when I remove setting of css properties width and height of canvas it draws image correct but canvas has only default size of according to browser. -> 2.result
I am totally confused.
You are using CSS to set the size of the canvas. This will only enlarge the default 300x150 sized canvas to the size you set with CSS (like if it was an image) (and besides, for CSS to work with other values than 0 you need to specify a unit - but ignore this for a moment).
You need to set the size explicitly using the canvas properties (attributes) width and height.
canvas[0].width = 704; // no unit required for the attributes
canvas[0].height = 672;

Create image, size relative to window width. Image not drawn when inserted in DOM

I'm building a phonegap app (with jquery mobile) and trying to insert an image in my DOM with width relative to the window.outerWidth and height auto.
I've already tried placing the image in a div with relative width like so:
<div style="width:myRelativeWidth">
<img style"width:100%; height:100%" src="somePath>
</div>
This works great, except on the iPhone where it sets the height of the image (auto) too late. It will be the correct width, but it is stretched heightwise to its original size before it is sized to the correct aspect ratio.
To counteract this, I've tried to scale it in relation to the size of the original image. The only way I know to get this is by preloading the image and setting the size before it is inserted in the DOM by the following function
imageElement = new Image();
imageElement.src = path;
setImageSize(widthPercentage);
function setImageSize(widthPercentage) {
var pageWidth = window.outerWidth;
var pageHeight = window.outerHeight;
var imageWidth = imageElement.width;
var imageHeight = imageElement.height;
var calculatedImageWidth;
var calculatedImageHeight;
var scaleFactor;
if(widthPercentage) {
calculatedImageWidth = pageWidth * (widthPercentage / 100);
scaleFactor = calculatedImageWidth / imageWidth;
calculatedImageHeight = imageHeight * scaleFactor;
imageElement.width = calculatedImageWidth;
imageElement.height = calculatedImageHeight;
}
}
document.body.appendChild(imageElement);
But testing in the browser i don't get the image when loading the page, but i get it when refreshing it.
Some googling told me that I have a problem with the image being loaded in the cache, but not drawn.
How can i force the image to be drawn?
Found my answer!
Assign the onload method to setImageSize as mentioned by #CBroe, and place it before imageElement.src=.

Categories