Tips for utilizing CSS perspective to align a div so it seamlessly fits within an SVG laptop display

Confusion may arise from the question at hand. My goal is to utilize CSS to absolutely position a div with perspective in a way that resembles it being inside the laptop screen I created with an SVG.

I am under the impression that achieving this effect is possible by using a combination of perspective, rotateX(), rotateY(), but I haven't quite nailed it yet.

Take a look at this Codepen for reference.

Below is the relevant CSS code snippet:

.container {
    perspective: 500px;
}
.screenContents {
    transform: rotateX(10deg) rotateY(-10deg);
    /* 16:9 ratio to calculate size */
    --scale: 36;
    width: calc(16px * var(--scale));
    height: calc(9px * var(--scale));
    position: absolute;
    top: 30px;
    left: 300px;
}

Here's the HTML part:

<div class='container'>
    <div class='screenContents'>Screen Contents</div>
</div>
<img src='device.svg' />

I've experimented with setting perspective-origin, and using rotateZ() among other things.

Dimensions and Information Regarding the SVG

Here are some screen dimensions I derived from the SVG:

area: 1529 sq pixels

(width and height calculated from each corner point)

width: ~500px
height: ~350px

Coordinates of each point on the SVG screen I used for calculations:

top left: 382,514
top right: 882,503
bottom left: 312,187
bottom right: 816,151

The SVG is a traced image of a Google Pixel Go laptop with a 13.3" screen size and 16:9 ratio.

I believe these dimensions must play a role in the final calculations.

Conclusion

I aim to position a div in a manner that simulates it being displayed on the laptop screen. I'm seeking guidance or a brilliant mind to devise a solution. Feel free to experiment with the Codepen.

Calling all CSS experts out there, any help would be greatly appreciated!

Answer №1

Revise CSS Below

.wrapper {
/*   effect: 3D; */
}

.pageContent {
 transform: effect(3651px) rotateY(-30deg) rotateX(18deg) rotate(3deg);
 --size: 37;
 width: calc(16px * var(--size));
 height: calc(10px * var(--size));
}

Answer №2

I have developed a demonstration inspired by How to match 3D perspective of real photo and object in CSS3 3D transforms written by @szym that utilizes matrix calculation for precise alignment.

I have enhanced the demonstration to function as a standalone tool (possibly creating one in the future) where you can drag 4 points. The demo employs jQuery Terminal as a div, although any element can be used to fit it into an image. The tool will provide you with the necessary CSS to fit the element into an image, ensuring it is not stretched or distorted.

The core solution from that post involves the following matrix computation:

// Function to calculate the matrix3d that maps source points to destination.
function compute_transform(src, dst) {
  // src and dst should each have 4 points
  var count = 4;
  var a = []; // (2*count) x 8 matrix
  var b = []; // (2*count) vector

  for (var i = 0; i < 2 * count; ++i) {
    a.push([0, 0, 0, 0, 0, 0, 0, 0]);
    b.push(0);
  }

  for (var i = 0; i < count; ++i) {
    var j = i + count;
    a[i][0] = a[j][3] = src[i][0];
    a[i][1] = a[j][4] = src[i][1];
    a[i][2] = a[j][5] = 1;
    a[i][3] = a[i][4] = a[i][5] =
      a[j][0] = a[j][1] = a[j][2] = 0;
    a[i][6] = -src[i][0] * dst[i][0];
    a[i][7] = -src[i][1] * dst[i][0];
    a[j][6] = -src[i][0] * dst[i][1];
    a[j][7] = -src[i][1] * dst[i][1];
    b[i] = dst[i][0];
    b[j] = dst[i][1];
  }

  var x = numeric.solve(a, b);
  // matrix3d is homogenous coords in column major!
  // the z coordinate is unused
  var m = [
    x[0], x[3], 0, x[6],
    x[1], x[4], 0, x[7],
    0, 0, 1, 0,
    x[2], x[5], 0, 1
  ];
  return "matrix3d(" + m.join(',') + ')';
}

// The array should contain all 4 points
// of the rectangle on the image
var points = []; 

function transform_terminal() {
    var w = geometry.width + 20,
        h = geometry.height + 20;
    var transform = compute_transform(
        [
            [0, 0],
            [w, 0],
            [w, h],
            [0, h]
        ],
        points
    );
    function format(klass, left, top) {
        return `
.${klass} {
   left: ${left}px;
   top: ${top}px;
}`.trim();
    }
    const point_css = $('.point').map(function() {
        var {left, top} = $(this).position();
        var klas = $(this).attr('class').replace(/point /, ''); 
        return format(klas, left, top);
    }).get().join('\n');
    $('.output pre').html(`
.terminal {
    transform: ${transform};
}
/* optional control points */
${point_css}`.trim())
    term.css({
        '--transform': transform
    });
}

The code utilizes the numeric library to solve a linear equation for obtaining the matrix.

Check out the demo here: https://codepen.io/jcubic/pen/PojPbZz

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Problems with displaying Wordpress content on your web browser

I am having trouble getting my website content to display properly in a web browser, even though I built it using Wordpress. It appears that only the logo and the 'Services' bar are showing up on the page, while the rest seems to be missing. I s ...

"Encountering an issue with the live preview feature in Br

Currently, I am working on a project offline and trying to make Brackets' live preview feature work smoothly. It has proven to be quite convenient for my tasks. While opening my project files using the "open file" option in Brackets, I encountered an ...

How to transform an image into a base64 string using Vue

I am having trouble converting a local image to base64. The function reader.readAsDataURL is not working for me. Instead of the image data, I always get 'undefined' assigned to the rawImg variable. The file variable contains metadata from the upl ...

What is the best way to add an active class to a clicked menu item that already has a class

I have menu items on the master page, and if users click on that menu item, I want to show it as active. My goal is to append "Active" to the existing class to indicate that it is active. _Layout.cshtml: <div class="menu-items-navigation"> <di ...

Utilizing variable values in HTML and CSS to enhance a website's functionality

My current project involves modifying an HTML web resource for use in Dynamics 365. I need to replace a static URL with a dynamic value obtained via Javascript, specifically: var URL = Xrm.Page.context.getClientUrl(); There are multiple instances within ...

The second entry is not being styled by CSS, is there an issue with the code in this section?

I am facing a challenge while trying to set the same background image for two div elements: .abc { background: url('images/autogen.png') no-repeat 0px -133px; width: 256px; height: 256px; }; .def { background: url('images/autogen.png' ...

Efficiently linking styles through computation in Angular

So I've been working with Angular5 and I figured out how to bind an HTML element's style to a Boolean value. However, I'm struggling to find a way to do this for multiple styles simultaneously. For example, I have this code snippet that wor ...

Ensure that the <TabPanel> content occupies the entire width and height of its parent container

Currently, I am working with React and material-ui. Specifically, I am utilizing an appbar with tabs and my goal is to have the content of each tab expand to full width and height when selected. If you'd like to see an example, check out this sandbox ...

How can I prevent the <br/> tag from being included on every new line when exporting data to PDF in jQuery Datatable?

I am currently working with a datatable that contains a large amount of data. Within this table, I have included 2 buttons for exporting the data in PDF and CSV formats. One of the columns within my table contains a comma-separated string, and when I expor ...

I am having trouble with the dropdown button in my Bootstrap - it just won't seem

I've exhausted all YouTube tutorials and followed the entire Bootstrap documentation, but I still can't seem to get it to work. Please, someone, help me figure out why it's not functioning properly :( This is the basic HTML bootstrap code I ...

What is the best way to retrieve the height of a <DIV> element without factoring in the presence of a horizontal scrollbar with

I have created a unique jQuery plugin that involves utilizing two nested <DIV> elements. The outer div is set with a fixed width and overflow: scroll, while the inner div (which is wider) houses the content for scrolling purposes. Everything is fun ...

The Main page is being graced by a floating Twitter Bootstrap video

When trying to display a video next to a paragraph, I encountered an issue where the paragraph was taking up 100% of the screen and the video was floating over it, obstructing part of the text. Despite setting the row and cols, the layout wasn't behav ...

display the hidden box contents when clicking the button within a PHP loop

I am attempting to create a simple e-commerce site for learning purposes, but I encountered an issue when trying to display information upon clicking a button. The button does not seem to trigger any action as expected. It is meant to reveal text from the ...

Using CSS sprites to style text links

I've been attempting to incorporate an image with various icons for text links in an unordered list, but I can't seem to display just one icon with some space next to it for the text. The code I have so far is: http://jsfiddle.net/XyVtq/2/ This ...

Creating dynamic height based on width using JavaScript

I'm trying to make a rectangle responsive based on the width of the window. This is my current logic: aspectRatio = 16 / 9 win = { width: window.innerWidth, height: window.innerHeight, } get browser() { const width = this.win.width - 250 ...

Angular navigation is inconsistent in its functionality

Currently, my Angular project consists of four components: home, portfolio, contact, and about. While I can navigate from the home page to any other component using the nav-bar, I am restricted to navigating only back to the home page when on any other pag ...

enhance the brilliance of elements at different intervals

My latest CSS animation project involves creating a stunning 'shine' effect on elements with a specific class. The shine effect itself is flawless, but having all elements shine simultaneously is making it look somewhat artificial. I've bee ...

Blend Image and Text with jQuery when Hovered Over

Alright, so here's the deal - I have an image that needs to smoothly transition to another image when hovered over. I also have some descriptive text that should crossfade into different text corresponding to the second image. The current setup is ki ...

Switch up the image automatically after a short amount of time

Hello, I am a beginner in javascript and I have a question. Is it possible for javascript to automatically change an image after a few seconds? This is for my college project and it's quite messy. Below is the code snippet I am working with: <!DOC ...

Creating a <Box /> component in MaterialUI with styled components is a great way to customize the design and layout of your

@material-ui/styles offers a different way to customize default styles: import React from 'react'; import Box from '@material-ui/core/Box'; import { styled } from '@material-ui/core/styles'; const StyledBox = styled(Box)({ ...