pythoniosIV
pythoniosIV

Reputation: 237

Rotate background-image in a rotated div?

I have a div shape with before: and after: so it looks like a cross shape (Rotated). But now my problem is, that the background is logically also rotated. I'd like that the background image isn't rotated and the image should be the size of the div.

I already tried to add a transform rotate to the place where I added the background but it didnt rotate back. Also for the size I tried background-size to adjust it, didnt work either.

Here is my jsbin: http://jsbin.com/iYogaCE/29/edit

thanks in advance!

nick

Upvotes: 1

Views: 1902

Answers (2)

Zach Saucier
Zach Saucier

Reputation: 26014

Well, I tried for a while to get a version working with pure CSS and HTML, but I was unable to do so. I believe that double pseudo selectors, aka ::after and ::before, would allow it to be possible, but I don't think that you can do it in pure CSS in one object currently.

With that being said, the way I accomplished it using one element is the much more common way - by using a canvas. With canvas it becomes pretty simple. Hopefully the comments make it easy to understand

Live demo here

// Gets a list of all the canvases to create an X for
var canvases = document.getElementsByClassName('profile');

// Allows the X to be drawn on multiple canvases without being redrawn
var tempCanvas = drawX();

// Gives the canvases a background image (the person's profile)
// If you wanted different images for each you could easily create an array
//   and iterate through it for each canvas
var background = new Image();
background.src = "http://asta-design.ch/gameotion/wp-content/uploads/2013/03/placeholder.jpg";

// Once the image has loaded, apply the Xs
background.onload = function() {

  // Do it for each canvas
  for(var i = 0, j = canvases.length; i < j; i ++)
  {
    // Gets the current canvas and context
    var canvas = canvases[i];
    var context = canvas.getContext('2d');

    // Allows the portrait only to be shown through the generated X
    context.globalCompositeOperation = "destination-atop";

    // Draws the profile picture
    context.drawImage(background, 0,0, canvas.width, canvas.height)

    // Cuts out everything that is not within the X
    context.drawImage(tempCanvas, 0, 0);
  }
}

// Creates the X to use as the cut out
function drawX() {
    // Creates a hidden canvas to draw the X on
    var offscreenCanvas = document.createElement('canvas');
    var offscreenCtx = offscreenCanvas.getContext('2d');

    // The width/height of the original canvas, not sure why "canvas.width" doesn't work here...
    var size = 200;
    offscreenCanvas.width = size;
    offscreenCanvas.height = size;

    // Creates the rectangles sloped positively
    offscreenCtx.save();
    offscreenCtx.translate(3 * size / 4, 3 * size / 4);
    offscreenCtx.rotate(Math.PI/4);
    offscreenCtx.fillRect(-size/2, -size/2, size * .3, size);

    // Loads the state before the first rectangle was created
    offscreenCtx.restore();

    // Creates the rectangles sloped positively
    offscreenCtx.translate(3 * size / 4, 1 * size / 4);
    offscreenCtx.rotate(-Math.PI/4);
    offscreenCtx.fillRect(-size/2, -size/2, size * .3, size);

    // Returns the canvas with the X
    return offscreenCanvas;
}

Upvotes: 1

Spudley
Spudley

Reputation: 168843

You can't rotate a CSS background independently of the element it is attached to.

The only way you're going to be able to do this is to have the rotated content in an additional element inside your existing one, and only rotate the inner element.

eg:

<div>                 <-- background applied to this element
    <div>....</div>   <-- but this one is rotated
</div>

Now your background will remain static while the content inside it rotates.

If you can't have any extra markup, you could still achieve this without changing the HTML, by using CSS the :before selector to create an additional pseudo-element behind the main element. Apply the background to that instead of the main element; after that it's similar to what I described above with the extra markup.

Hope that helps.

Upvotes: 1

Related Questions