HTML5 canvas drawImage or CSS background url - css

I have a question, wich one have the best performance in webBrowsers?
drawing a canvas with the given url image "context.drawImage(...)" or just using css with "background:url('...')".
(both images filling the entire webPage as a wallpaper)
For big images (wallpapers) who fill the entire page i think it is heavier to load the image with css.
At least for firefox(20+), if you change tabs or minimize the window and go back again to your page (with the background), i can see that the image takes to show again after a half second.
So, i'm asking bc i found a lot of people telling that basic DOM is better.
Code for css:
--html: <body></body>
$('body').css('background',
"url('http://www.iwallscreen.com/stock/city-lights-hd-wallpaper.jpg') repeat fixed 0 0 #000000");
$('body').css('background-size', "100% auto");
Code for canvas:
--html: <canvas id="canvasWall" style="position:fixed;left:0;z-index:-1;"></canvas>
var context = $('#canvasWall')[0].getContext("2d");
context.canvas.width = window.innerWidth;
context.canvas.height = window.innerHeight;
var img = new Image();
img.src = 'http://www.iwallscreen.com/stock/city-lights-hd-wallpaper.jpg';
img.onload = function() {
context.drawImage(img, 0, 0, window.innerWidth, window.innerHeight);
};

Related

How do I get video transparency for web?

I want to create a video that has transparency, but I can't have it be a Quicktime movie since it is being deployed on the web. I need something that is cross-browser compatible also.
I tried to create a video with a black background and use a blend mode in CSS to knock out the background, creating the illusion of transparency. That worked, but it also affected the art in the video that lay on top of the black background. I need a solution that will work to create transparency (alpha) on the background but not affect the rest of the content, such as seen with a QuickTime video with alpha channel.
you can use html5 transparent video, mp4 as example, double the height, with a canvas and alpha channel.
take a look at this code:
(function () {
var outputCanvas = document.getElementById('output'),
output = outputCanvas.getContext('2d'),
bufferCanvas = document.getElementById('buffer'),
buffer = bufferCanvas.getContext('2d'),
video = document.getElementById('video'),
width = outputCanvas.width,
height = outputCanvas.height,
interval;
function processFrame() {
buffer.drawImage(video, 0, 0);
// this can be done without alphaData, except in Firefox which doesn't like it when image is bigger than the canvas
var image = buffer.getImageData(0, 0, width, height),
imageData = image.data,
alphaData = buffer.getImageData(0, height, width, height).data;
for (var i = 3, len = imageData.length; i < len; i = i + 4) {
imageData[i] = alphaData[i - 1];
}
output.putImageData(image, 0, 0, 0, 0, width, height);
}
video.addEventListener('play', function () {
clearInterval(interval);
interval = setInterval(processFrame, 40)
}, false);
// Firefox doesn't support looping video, so we emulate it this way
video.addEventListener('ended', function () {
video.play();
}, false);
})();
and i used this on a webpage once:
<div class="IntroVideo" id="canvas_output">
<video id="video" style="display:none;" autoplay crossorigin="anonymous">
<source src="https://jakearchibald.com/scratch/alphavid/compressed.mp4" type='video/mp4' />
</video>
<canvas width="920" height="1300" id="buffer" style="display: none;"></canvas>
<canvas width="920" height="650" id="output" style="display: inline-block;"></canvas>
</div>
i found a transparent video example for you to try,
there is some instruction somewhere but i can't seem to find them anymore,
it's on jakearchibald.com perhaps the instruction is there too.
I'm afraid it is not possible. I'm also searching, searching and searching.. But looking at your image: can't you create a CSS animation instead of video?

Pure CSS parallaxing (not fixed) background for single row in layout

I'm wondering if it's possible to use only CSS to create a parallax scrolling background that meets the following specifications.
It works on an element that sits inside an otherwise static layout (i.e. my whole page layout isn't a group of parallaxing items)
The background isn't entirely fixed in place; it moves, just not as fast as the rest of the page.
I've looked up tons of tutorials for parallaxing backgrounds, and have found some seemingly great tutorials, but they all have one of the following problems.
They rely on the whole page being a parallax group so that you're actually scrolling over a container via an "overflow: auto" specification
The background is totally fixed in place
they use JavaScript.
Sooo, I can accomplish what I want with JavaScript fairly easily. Here's a full working example on JSFiddle that you can try out.
CSS
.parallax-row {
background-image: url(http://lorempixel.com/output/nature-q-c-781-324-3.jpg);
background-size: auto 150%;
}
JavaScript
/**
* Update the parallaxing background img to partially scroll
*/
jQuery(document).ready(function($) {
$(window).on('scroll', function() {
$('.parallax-row').each(function(index, el) {
var $el = $(el);
var fromTop = $el.offset().top + ($el.outerHeight() / 2) - $(window).scrollTop();
var windowHeight = $(window).height();
var percent = (fromTop * 100 / windowHeight);
$el.css('background-position', '0 ' + percent + '%');
});
});
});
Is it possible to accomplish that same effect with just CSS?

Scaling a canvas nicely with css

I'm trying to draw an image on a canvas, then use css to fit the canvas within a certain size. It turns out that many browsers don't scale the canvas down very nicely. Firefox on OS X seems to be one of the worst, but I haven't tested very many. Here is a minimal example of the problem:
HTML
<img>
<canvas></canvas>
CSS
img, canvas {
width: 125px;
}
JS
var image = document.getElementsByTagName('img')[0],
canvas = document.getElementsByTagName('canvas')[0];
image.onload = function() {
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext('2d');
context.drawImage(image, 0, 0, canvas.width, canvas.height);
}
image.src = "http://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Helvetica_Neue_typeface_weights.svg/783px-Helvetica_Neue_typeface_weights.svg.png"
Running in a codepen: http://codepen.io/ford/pen/GgMzJd
Here's the result in Firefox (screenshot from a retina display):
What's happening is that both the <img> and <canvas> start at the same size and are scaled down by the browser with css (the image width is 783px). Apparently, the browser does some nice smoothing/interpolation on the <img>, but not on the <canvas>.
I've tried:
image-rendering, but the defaults seem to already be what I want.
Hacky solutions like scaling the image down in steps, but this didn't help: http://codepen.io/ford/pen/emGxrd.
Context2D.imageSmoothingEnabled, but once again, the defaults describe what I want.
How can I make the image on the right look like the image on the left? Preferably in as little code as possible (I'd rather not implement bicubic interpolation myself, for example).
You can fix the pixelation issue by scaling the canvas's backing store by the window.devicePixelRatio value. Unfortunately, the shoddy image filtering seems to be a browser limitation at this time, and the only reliable fix is to roll your own.
Replace your current onload with:
image.onload = function() {
var dpr = window.devicePixelRatio;
canvas.width = image.width * dpr;
canvas.height = image.height * dpr;
var context = canvas.getContext('2d');
context.drawImage(image, 0, 0, canvas.width, canvas.height);
}
Results:
Tested on Firefox 35.0.1 on Windows 8.1. Note that your current code doesn't handle browser zoom events, which could reintroduce pixelation. You can fix this by handling the resize event.
Canvas is not quite meant to be css zoomed : Try over-sampling : use twice the required canvas size, and css scaling will do a fine job in down-scaling the canvas.
On hi-dpi devices you should double yet another time the resolution to reach the
same quality.
(even on a standard display, X4 shines a bit more).
(Image, canvas 1X, 2X and 4X)
var $ = document.getElementById.bind(document);
var image = $('fntimg');
image.onload = function() {
drawAllImages();
}
image.src = "http://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Helvetica_Neue_typeface_weights.svg/783px-Helvetica_Neue_typeface_weights.svg.png"
function drawAllImages() {
drawImage(1);
drawImage(2);
drawImage(4);
}
function drawImage(x) {
console.log('cv' + x + 'X');
var canvas = $('cv' + x + 'X');
canvas.width = x * image.width;
canvas.height = x * image.height;
var context = canvas.getContext('2d');
context.drawImage(image, 0, 0, canvas.width, canvas.height);
}
img,
canvas {
width: 125px;
}
<br>
<img id='fntimg'>
<canvas id='cv1X'></canvas>
<canvas id='cv2X'></canvas>
<canvas id='cv4X'></canvas>
<br>
It's not good idea to scale canvas and think that you solved the image scale problem.you can pass your dynamic value to canvas,and then draw with that size whatever you want.
here is link of canvas doc: http://www.w3docs.com/learn-javascript/canvas.html
Simple answer, you can't do it. The canvas is just like a bitmap, nothing more.
My idea:
You should redraw the whole surface on zooming, and make sure you scale the image you're drawing to the canvas. As it is a vector graphic, this should work. But you're going to have to redraw the canvas for sure.

HTML5 Canvas fills windows with full resolution

I am trying to achieve a layout like this:
where:
Navbar is just a bootstrap-like top menu, 60px of height, always on top
Pop-up menu is fixed in that position (not always visible), always on top
The entire free area (windows w.o. navbar) is filled with Canvas.
Live example: jsFiddle
I have a problem with Canvas. I currently have a simple style:
<canvas id="le_canvas">Y U NO CANVAS</canvas>
...
#le-canvas {
position:absolute;
width:100%;
height:100%;
}
and the canvas is filling the background, but:
the resolution is very low
it doesn't maintain ratio during window resizes.
What I'd like (if it is possible):
full resolution of the area to fill (1:1 pixel on canvas and on screen)
set the ratio of the area to fill
bonus: update the above after window resize
Setting the canvas element in per-centage will not set the actual canvas size which must be set in absolute pixels. What happens here is that you get a canvas with a default size which then is stretched by the html-rendering giving the blurry look.
You therefor need to set the size by using f.ex. the window's sizes in absolute pixels.
You can do this like this (update of fiddle here: http://jsfiddle.net/x5LpA/3/ ) -
Create a function that sets the canvas size based on window size (you will of course need to subtract height of bars etc, but to show the principle):
function initCanvasArea(cnv) {
cnv.width = window.innerWidth;
cnv.height = window.innerHeight;
}
As the canvas content are cleared when the canvas is re-sized you need to render the content again for each time. Therefor it will be smart to extract the render content into a separate function like f.ex:
function renderCanvas(ctx) {
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect(0, 0, 55, 50);
ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
ctx.fillRect(20, 20, 55, 50);
}
Now, make the main function a self-invoking one where you also attach an event handler for windo.resize to update the canvas:
$(function () {
var canvas = $('#le_canvas')[0];
var ctx = canvas.getContext('2d');
initCanvasArea(canvas);
renderCanvas(ctx);
window.onresize = function(e) {
initCanvasArea(canvas);
renderCanvas(ctx);
};
})();
And finally edit the CSS-rule by removing the width/height set to 100%;
#le_canvas {
position:absolute;
}
(Tip: a better approach here is to use the fixed attribute for position - plus use a wrapper element, padding, box-sizing.. but that is out of scope for this question).
Is this what you are after? I used $(document).width() and $(document).height() to get the width and height for the rectangle. http://jsfiddle.net/x5LpA/1/

CSS background of png with semitransparancies transparant on a gradient shows a white background

if you look at this fiddle( http://jsfiddle.net/5ajYD/ ) with an android browser you see that the PNG that makes up the flowers has a white background.
On all other browsers it shows perfectly normal, except the android browser.
I've googled on this problem but the only thing I can find is a problem with png banding and related to android app programming.
This reminds me of the issues MSIE 6 has with transparant images, and I find it very strange that this happens.
Does anyone know a fix for this issue on android browsers?
I can't use non transparant background because of the gradient differences in different browsers.
What I have tried so far:
I have already tried using "multiple" backgrounds both posistioned at
location 0px 0px, but that doens't work
I've tried adding a gradient to to the div with the flowers, but that
failed too and broke in other browsers.
I find it very mystifying that this kind of issue shows up on a modern browser... even a nokia n95 gets it right....
The android version I’m testing against/found this with is android 2.3.4(Sony Ericsson Xperia Arc S LT18i)
This is what I see with the fiddle in the android browser on the phone
http://t.co/mofPkqjf
I had a big facepalm moment.
I've been battling with this for two months now and I simply couldn't figure out the logic. The problem was in the econtainer element that it had a parameter: width:100%.
What happens is that it only renders the width up to the actual page width of the viewport.
So if you have a browser screen on mobile that's 480px wide, it'll set width to 480px, render a gradient of 480px, and not rerender when you scroll sideways.
The problem was solved by adding a min-width:1200px; and now it renders properly!
Thank you all for looking into this...
Use HTML5 Canvas to create an alphaJPEG, a JPEG layered under an equivalent PNG with an alpha channel.
<head>
<style>img[data-alpha-src]{visibility: hidden;}</style>
</head>
<body>
<img src="image.jpg" data-alpha-src="alpha.png" />
<!--...-->
<script src="ajpeg.js"></script>
</body>
ajpeg.js
(function() {
var create_alpha_jpeg = function(img) {
var alpha_path = img.getAttribute('data-alpha-src')
if(!alpha_path) return
// Hide the original un-alpha'd
img.style.visiblity = 'hidden'
// Preload the un-alpha'd image
var image = document.createElement('img')
image.src = img.src
image.onload = function () {
// Then preload alpha mask
var alpha = document.createElement('img')
alpha.src = alpha_path
alpha.onload = function () {
var canvas = document.createElement('canvas')
canvas.width = image.width
canvas.height = image.height
img.parentNode.replaceChild(canvas, img)
// For IE7/8
if(typeof FlashCanvas != 'undefined') FlashCanvas.initElement(canvas)
// Canvas compositing code
var context = canvas.getContext('2d')
context.clearRect(0, 0, image.width, image.height)
context.drawImage(image, 0, 0, image.width, image.height)
context.globalCompositeOperation = 'xor'
context.drawImage(alpha, 0, 0, image.width, image.height)
}
}
}
// Apply this technique to every image on the page once DOM is ready
// (I just placed it at the bottom of the page for brevity)
var imgs = document.getElementsByTagName('img')
for(var i = 0; i < imgs.length; i++)
create_alpha_jpeg(imgs[i])
})();
In the head element I linked to FlashCanvas:
<!--[if lte IE 8]><script src="flashcanvas.js"></script><![endif]-->
... and I threw in this to avoid a flicker of the un-alpha’d JPEG:

Resources