Raphaeljs IE8 setViewBox not working - internet-explorer-8

I use RaphaelJS for generate SVG. My SVG is 1024px width and height.
I use setViewBox because the div containing it is more small than 510px width and height.
With IE8 RaphaelJS produces VML but setViewBox is not working, the size of VML produced is 1024px.
How I can make that VML responsive?
paper = Raphael(document.getElementById("SVGDiv"));
paper.canvas.id = 'paper';
paper.setViewBox(0,0,1024,1024);
paper.setViewBox(0,0,1024,1024);
image = paper.image("",0,0, 1024, 1024);
text = paper.text(512, 512, '');
if( isIE() > 8 || isIE() == false){
paper.setSize("100%","100%");
}

Related

With canvas, ctx.lineTo draws a longer "Y" line than instructed (160 instead of 120) [duplicate]

I have 2 canvases, one uses HTML attributes width and height to size it, the other uses CSS:
<canvas id="compteur1" width="300" height="300" onmousedown="compteurClick(this.id);"></canvas>
<canvas id="compteur2" style="width: 300px; height: 300px;" onmousedown="compteurClick(this.id);"></canvas>
Compteur1 displays like it should, but not compteur2. The content is drawn using JavaScript on a 300x300 canvas.
Why is there a display difference?
It seems that the width and height attributes determine the width or height of the canvas’s coordinate system, whereas the CSS properties just determine the size of the box in which it will be shown.
This is explained in the HTML specification:
The canvas element has two attributes to control the size of the element’s bitmap: width and height. These attributes, when specified, must have values that are valid non-negative integers. The rules for parsing non-negative integers must be used to obtain their numeric values. If an attribute is missing, or if parsing its value returns an error, then the default value must be used instead. The width attribute defaults to 300, and the height attribute defaults to 150.
To set the width and height on a canvas, you may use:
canvasObject.setAttribute('width', '150');
canvasObject.setAttribute('height', '300');
For <canvas> elements, the CSS rules for width and height set the actual size of the canvas element that will be drawn to the page. On the other hand, the HTML attributes of width and height set the size of the coordinate system or 'grid' that the canvas API will use.
For example, consider this (jsfiddle):
var ctx = document.getElementById('canvas1').getContext('2d');
ctx.fillStyle = "red";
ctx.fillRect(10, 10, 30, 30);
var ctx2 = document.getElementById('canvas2').getContext('2d');
ctx2.fillStyle = "red";
ctx2.fillRect(10, 10, 30, 30);
canvas {
border: 1px solid black;
}
<canvas id="canvas1" style="width: 50px; height: 100px;" height="50" width="100"></canvas>
<canvas id="canvas2" style="width: 100px; height: 100px;" height="50" width="100"></canvas>
Both have had the same thing drawn on them relative to the internal coordinates of the canvas element. But in the second canvas, the red rectangle will be twice as wide because the canvas as a whole is being stretched across a bigger area by the CSS rules.
Note: If the CSS rules for width and/or height aren't specified then the browser will use the HTML attributes to size the element such that 1 unit of these values equals 1px on the page. If these attributes aren't specified then they will default to a width of 300 and a height of 150.
The canvas will be stretched if you set the width and height in your CSS. If you want to dynamically manipulate the dimension of the canvas you have to use JavaScript like so:
canvas = document.getElementById('canv');
canvas.setAttribute('width', '438');
canvas.setAttribute('height', '462');
The browser uses the css width and height, but the canvas element scales based on the canvas width and height. In javascript, read the css width and height and set the canvas width and height to that.
var myCanvas = $('#TheMainCanvas');
myCanvas[0].width = myCanvas.width();
myCanvas[0].height = myCanvas.height();
Shannimal correction
var el = $('#mycanvas');
el.attr('width', parseInt(el.css('width')))
el.attr('height', parseInt(el.css('height')))
Canvas renders image by buffer, so when you specify the width and height HTML attributes the buffer size and length changes, but when you use CSS, the buffer's size is unchanged. Making the image stretched.
Using HTML sizing.
Size of canvas is changed -> buffer size is changed -> rendered
Using CSS sizing
Size of canvas is changed -> rendered
Since the buffer length is kept unchanged, when the context renders the image,
the image is displayed in resized canvas (but rendered in unchanged buffer).
CSS sets the width and height of the canvas element so it affects the coordinate space leaving everything drawn skewed
Here's my way on how to set the width and height with Vanilla JavaScript
canvas.width = numberForWidth
canvas.height = numberForHeight
I believe CSS has much better machinery for specifying the size of the canvas and CSS must decide styling, not JavaScript or HTML. Having said that, setting width and height in HTML is important for working around the issue with canvas.
CSS has !important rule that allows to override other styling rules for the property, including those in HTML. Usually, its usage is frowned upon but here the use is a legitimate hack.
In Rust module for WebAssembly you can do the following:
fn update_buffer(canvas: &HtmlCanvasElement) {
canvas.set_width(canvas.client_width() as u32);
canvas.set_height(canvas.client_height() as u32);
}
//..
#[wasm_bindgen(start)]
pub fn start() -> Result<(), JsValue> {
// ...
let canvas: Rc<_> = document
.query_selector("canvas")
.unwrap()
.unwrap()
.dyn_into::<HtmlCanvasElement>()
.unwrap()
.into();
update_buffer(&canvas);
// ...
// create resizing handler for window
{
let on_resize = Closure::<dyn FnMut(_)>::new(move |_event: Event| {
let canvas = canvas.clone();
// ...
update_buffer(&canvas);
// ...
window.add_event_listener_with_callback("resize", on_resize.as_ref().unchecked_ref())?;
on_resize.forget();
}
}
There we update the canvas buffer once the WASM module is loaded and then whenever the window is resized. We do it by manually specifying width and height of canvas as values of clientWidth and clientHeight. Maybe there are better ways to update the buffer but I believe this solution is better than those suggested by #SamB, #CoderNaveed, #Anthony Gedeon, #Bluerain, #Ben Jackson, #Manolo, #XaviGuardia, #Russel Harkins, and #fermar because
The element is styled by CSS, not HTML.
Unlike elem.style.width & elem.style.height trick used by #Manolo or its JQuery equivalent used by #XaviGuardia, it will work for canvas whose size is specified by usage as flex or grid item.
Unlike the solution by #Russel Harkings, this also handles resizing. Though I like his answer because it is really clean and easy.
WASM is the future! Haha :D
P.S. there's a ton of .unwrap() because Rust explicitly handles possible failures.
P.P.S.
{
let on_resize = Closure::<dyn FnMut(_)>::new(move |_event: Event| {
let canvas = canvas.clone();
// ...
update_buffer(&canvas);
// ...
window.add_event_listener_with_callback("resize", on_resize.as_ref().unchecked_ref())?;
on_resize.forget();
}
can be done much cleaner with better libraries. E.g.
add_resize_handler(&window, move |e: ResizeEvent| {
let canvas = canvas.clone();
// ...
update_buffer(&canvas);
})
If you want a dynamic behaviour based on, e.g. CSS media queries, don't use canvas width and height attributes. Use CSS rules and then, before getting the canvas rendering context, assign to width and height attributes the CSS width and height styles:
var elem = document.getElementById("mycanvas");
elem.width = elem.style.width;
elem.height = elem.style.height;
var ctx1 = elem.getContext("2d");
...

Itext7 - Crop Image

Hi How can we resize image in iText 7 .
I am not able to find PDFTemplate in itext 7 now which used to crop image.
.
public Image cropImage(PdfWriter writer, Image image, float leftReduction, float rightReduction, float topReduction, float bottomReduction) throws DocumentException {
float width = image.getScaledWidth();
float height = image.getScaledHeight();
PdfTemplate template = writer.getDirectContent().createTemplate(
width - leftReduction - rightReduction,
height - topReduction - bottomReduction);
template.addImage(image,
width, 0, 0,
height, -leftReduction, -bottomReduction);
return Image.getInstance(template);
}
This is used for itext 5
Suppose that you have this image, measuring 900 x 1200 pixels:
But you only want to show part of this image (e.g. the ping pong balls):
Then you can use this iText 7 code:
PdfDocument pdf = new PdfDocument(new PdfWriter("cropimage.pdf"));
Document document = new Document(pdf);
Image image = new Image(ImageDataFactory.create(imagePath));
image.setFixedPosition(-20, -320);
Rectangle rectangle = new Rectangle(300, 300);
PdfFormXObject template = new PdfFormXObject(rectangle);
Canvas canvas = new Canvas(template, pdf);
canvas.add(image);
Image croppedImage = new Image(template);
document.add(croppedImage);
document.close();
We create an Image instance with the full image, and we set the fixed position in such a way that we chip off 20 pixels from the left, and 320 from the bottom.
We create a rectangle of 300 x 300 user units. This defines the size of the cropped image.
We create a PdfFormXObject using this rectangle. In iText 5 language, a Form XObject used to be named a PdfTemplate.
We create a Canvas object with this template, and we add the image to the canvas.
Finally, we create another Image using the template. The Canvas operation will have added the full image to that template, but it will be cropped to the size of the rectangle.
You can add this croppedImage to the document.

How to achieve high quality cropped images from canvas?

I am desperately searching for a good cropping tool. There are a bunch out there, for example:
Croppic
Cropit
Jcrop
The most important thing that I am trying to find is a cropping tool, that crops images without making the cropped image low in resolution. You can hack this by using the canvas tag by resizing the image. This way the image itself stays native, only the representation is smaller.
DarkroomJS was also something near the solution, but, unfortunately, the downloaded demo did not work. I'll try to figure out whats wrong. Does someone know some great alternatives, or how to get the cropped images in...let's say "native" resolution?
Thanks in advance!
You are relying on the cropping tool to provide an interface for the users. the problem is that the image returned is sized to the interface and not the original image. Rather than me sifting through the various API's to see if they provide some way of controlling this behaviour (I assume at least some of them would) and because it is such a simple procedure I will show how to crop the image manually.
To use JCrop as an example
Jcrop provides various events for cropstart, cropmove, cropend... You can add a listener to listen to these events and keep a copy of the current cropping interface state
var currentCrop;
jQuery('#target').on('cropstart cropmove cropend',function(e,s,crop){
currentCrop = crop;
}
I don't know where you have set the interface size and I am assuming the events return the crop details at the interface scale
var interfaceSize = { //you will have to work this out
w : ?,
h : ?.
}
Your original image
var myImage = new Image(); // Assume you know how to load
So when the crop button is clicked you can create the new image by scaling the crop details back to the original image size, creating a canvas at the cropped size, drawing the image so that the cropped area is corectly positioned and returning the canvas as is or as a new image.
// image = image to crop
// crop = the current cropping region
// interfaceSize = the size of the full image in the interface
// returns a new cropped image at full res
function myCrop(image,crop,interfaceSize){
var scaleX = image.width / interfaceSize.w; // get x scale
var scaleY = image.height / interfaceSize.h; // get y scale
// get full res crop region. rounding to pixels
var x = Math.round(crop.x * scaleX);
var y = Math.round(crop.y * scaleY);
var w = Math.round(crop.w * scaleX);
var h = Math.round(crop.h * scaleY);
// Assume crop will never pad
// create an drawable image
var croppedImage = document.createElement("canvas");
croppedImage.width = w;
croppedImage.height = h;
var ctx = croppedImage.getContext("2d");
// draw the image offset so the it is correctly cropped
ctx.drawImage(image,-x,-y);
return croppedImage
}
You then only need to call this function when the crop button is clicked
var croppedImage;
myButtonElement.onclick = function(){
if(currentCrop !== undefined){ // ensure that there is a selected crop
croppedImage = myCrop(myImage,currentCrop,interfaceSize);
}
}
You can convert the image to a dataURL for download, and upload via
imageData = croppedImage.toDataURL(mimeType,quality) // quality is optional and only for "image/jpeg" images

Setting kendo grid height scrollable auto min-height max-height

I am aware of this beeing a frequently discussed issue.
Anyway I want to give it a shot:
I am using multiple kendo grids - so I am looking for a reusable and clean way how to set the grids styles without having side effects on each other.
So here's what I want to achieve:
Grid style 1:
- min-height: 150px max-heigt: 600px scrollable
Grid style 2:
- min-height: 150px max-heigt: 300px scrollable
Doesn't seem very extraordinary, does it?
I tryed setting html.attributes, setting scrollable() height and overwriting css.
But in the end I'll always find myself in having following problems, though:
Grid content div overflows the parent div
no scrollbars anymore
"fixing" by overwriting css classes what has undesired side effects
of course
Does anybody have a solution?
I have a possible solution which I have modified from a bit of code I use.
independent grid height resizing
So lets examine the magic bit for you:
function resizeGrid(grid, size, fixed, minHeight, minSizeHeight, maxHeight, maxSizHeight) {
if (size === null || size === undefined) {
size = 0.6;
}
if (minHeight === null || minHeight === undefined) {
minHeight = 600;
minSizeHeight = 150;
}
if (maxHeight === null || maxHeight === undefined) {
maxHeight = 800;
maxSizHeight = 600;
}
var windowHeight = $(window).height();
if (!fixed) {
windowHeight = windowHeight * size;
} else {
windowHeight = size;
}
if ($(window).height() < minHeight) {
windowHeight = minSizeHeight;
}
if ($(window).height() > maxHeight) {
windowHeight = maxSizHeight;
}
var gridContent = $("#" + grid + " div.k-grid-content");
var lockedContent = $("#" + grid + " div.k-grid-content-locked");
gridContent.height(windowHeight);
if (lockedContent !== null && lockedContent !== undefined) {
lockedContent.height(windowHeight);
}
}
So based on your requirements and my understanding you want to be able to change the scrollable area dynamically and independently of one another.
in this example we provide the following signature:
resizeGrid(grid, size, fixed, minHeight, minSizeHeight, maxHeight, maxSizeHeight)
Grid ==> the id of the grid we are working with
Size ==> this is the size either expressed as a pixel value or percentage (eg. 150 or 0.4 (40%))
fixed ==> this tells the function if the value passed is a fixed height or a percentage height for the initial height requirements
minHeight==> this should be the minimum screen size that the grid should resize itself
minSizeHeight ==> this is the size the grid should resize to if the minHeight condition is met.
maxHeight ==> this should be the maximum screen size that the grid should resize itself.
maxSizeHeight ==> this should be the maximum size of the grid should be be above the maxHeight of the window.
Note: the final 4 settings will use pixel defined values but the code could be adapted to work with percentages as well
so in the example I have provided I have declared:
resizeGrid("grid",600,true, 400,150, 800,600 );
resizeGrid("grid2",150,true, 300,300, 600,400 );
So the first grid #grid will set itself to a size of 600px initially and then resize itself if the window goes below 400px and over 800px. In both scenarios it will resize to 150px, 600px respectively.
then when we start resizing the window I have added this:
$(window).resize(function () {
console.log("resizing::" ,$(window).height() );
resizeGrid("grid",600,true, 400,150, 800,600 );
resizeGrid("grid2",150,true, 300,300, 600,400 );
});
This will then look for the window resize event to be fired off and then resize the grids accordingly.
I have added the console statement purely so you can see this event being fired off and what the window height is to check the code is being activated at the right point.
One thing you may notice are these lines here:
var gridContent = $("#" + grid + " div.k-grid-content");
var lockedContent = $("#" + grid + " div.k-grid-content-locked");
Due to the grid "wrapping" the locked and non-locked portions into different tags I am checking to see if there are any locked columns as otherwise you will have different scrolling/unexpected style on the various parts of the grid.
If you need anything more explaining/changing let me know and I will update my answer accordingly. Hopefully this is what you are after.
Edit: I have updated the example so you can see the grids side by side

Rmagick setting opacity in watermark with transparency

I am trying to create a watermark with different opacity values (from 0 opaque value to 1 totally transparent).
I have the following method for RMagick in ruby:
# 0 = opaque (Magick::OpaqueOpacity) 1= transparent (Magick::TransparentOpacity)
def watermark(opacity = 0.99, size = 'm')
manipulate! do |img|
logo = Magick::Image.read("#{Rails.root}/app/assets/images/watermark#{size}.png").first
logo.alpha(Magick::ActivateAlphaChannel)
logo.opacity = (1 - opacity.to_f) * Magick::QuantumRange
img.alpha(Magick::ActivateAlphaChannel)
img = img.composite(logo, Magick::NorthWestGravity, 0, 0, Magick::OverCompositeOp)
end
end
My problem is that it seems to work, but the composite mode or the alpha composite or setting the opacity or alpha is failing, because I get a black transparency in the image. For example if my watermark is a totally transparent image with a text, that I put over a car image, then I get a more dark or nightly image with the watermark, so the background of the watermark it is not blending properly.
Any suggestions to set properly the opacity in the watermark image? Maybe some method to disolve the watermark?
EDIT: Adding image examples:
http://uppix.com/f-watermarkg53925b100016ab8e.png (watermark)
http://oi62.tinypic.com/2us8rxl.jpg (base image)
http://oi60.tinypic.com/2pt6mg3.jpg (composition)
Thanks to Neil Slater, I finally found the right solution. I need a combination of composite operation of DstIn + Over in my finalt result:
def watermark(opacity = 0.99, size = 'm')
manipulate! do |img|
logo = Magick::Image.read("#{Rails.root}/app/assets/images/watermark#{size}.png").first
logo.alpha(Magick::ActivateAlphaChannel)
white_canvas = Magick::Image.new(logo.columns, logo.rows) { self.background_color = "none" }
white_canvas.alpha(Magick::ActivateAlphaChannel)
white_canvas.opacity = Magick::QuantumRange - (Magick::QuantumRange * opacity)
# Important: DstIn composite operation (white canvas + watermark)
logo_opacity = logo.composite(white_canvas, Magick::NorthWestGravity, 0, 0, Magick::DstInCompositeOp)
logo_opacity.alpha(Magick::ActivateAlphaChannel)
# Important: Over composite operation (original image + white canvas watermarked)
img = img.composite(logo_opacity, Magick::NorthWestGravity, 0, 0, Magick::OverCompositeOp)
end
end

Resources