Is there a way to rotate a symbol around its center without the need to specify its position on two separate occasions

I am working on placing tile symbols on a grid and aiming to achieve the following:

  • Utilize tile coordinates for symbol placement (e.g. 4,2 instead of 85,43)
  • Define the vertices of symbols using pixel coordinates (not tile coordinates)
  • Rotate symbols around their center without specifying absolute coordinates.

I have solutions for the first two requirements, but I am struggling with the third. Currently, I can rotate the tile at 4,2 by a quarter turn using the following code:

<!-- 10/21 = 0.47619047619 -->
<use x="4" y="2" href="#rooftop-0" class="theme-0" transform="rotate(90 4.476 2.476)" />

However, I find it redundant to specify the tile coordinates twice. Ideally, I would prefer a solution like this:

<use x="4" y="2" href="#rooftop-0" class="theme-0 rotate-1" />

Although defining .rotate-1 in the stylesheet does not seem to affect the rotation. Perhaps adjusting the symbol coordinates or viewBox could help?

Alternatively, manually changing the vertices to achieve different orientations is an option, but not ideal.

Despite the challenges, here is the current state of the project:

Is there a more efficient way to achieve the desired rotation around the symbol's center?

Answer №1

If you choose to define your use attributes using the x and y coordinates, you have the option of utilizing transform="translate(x, y) instead. By doing so, you ensure that the origin parameters of the rotate() method remain consistent (0.5, 0.5):

<svg viewBox="0 0 211 211">
  <style>
    .grid-line {
      fill: #DDD;
    }
    .grass-fill {
      fill: #8C8;
    }
    .theme-0 {
      --roof-color-0: #F44;
      --roof-color-1: #F66;
      --roof-color-2: #F88;
      --roof-color-3: #FAA;
    }

    .theme-1 {
      --roof-color-0: #44F;
      --roof-color-1: #66F;
      --roof-color-2: #88F;
      --roof-color-3: #AAF;
    }
  </style>

  <defs>
    <pattern id="grid" x="-0.5" y="-0.5" width="20" height="20" patternUnits="userSpaceOnUse">
      <rect class="grid-line" x="0" y="0" width="1" height="20" />
      <rect class="grid-line" x="0" y="0" width="20" height="1" />
    </pattern>

    <symbol id="rooftop-0" viewBox="0 0 20 20">
      <g class="tile" transform="translate(0.5, 0.5) scale(0.95)">
        <rect class="grass-fill" width="20" height="20" />
        <polygon style="fill: var(--roof-color-0)" points="3,2 17,2 18,8 2,8" />
        <polygon style="fill: var(--roof-color-1)" points="2,8 18,8 17,14 3,14" />
        <polygon style="fill: var(--roof-color-2)" points="8,8 11,14 11,18 8,18" />
        <polygon style="fill: var(--roof-color-3)" points="8,8 8,18 5,18 5,14" />
      </g>
    </symbol>

    <symbol id="rooftop-1" viewBox="0 0 20 20">
      <g class="tile"transform="translate(0.5, 0.5) scale(0.95)">
        <rect class="grass-fill" width="20" height="20" />
        <polygon style="fill: var(--roof-color-0)" points="2,11 18,11 17,17 3,17" />
        <polygon style="fill: var(--roof-color-1)" points="3,5 17,5 18,11 2,11" />
        <polygon style="fill: var(--roof-color-2)" points="10,11 10,3 13,3 13,5" />
        <polygon style="fill: var(--roof-color-3)" points="10,11 7,5 7,3 10,3" />
      </g>
    </symbol>
  </defs>
  
  <g>
    <rect fill="#999" width="100%" height="100%" />
    <rect fill="url(#grid)" width="100%" height="100%" />
  </g>
  
  <g transform="scale(20, 20)">
      <use xlink:href="#rooftop-0" class="theme-1" width="1" height="1" transform="translate(4, 2) rotate(0,0.5,0.5)"/>
      <use xlink:href="#rooftop-1" class="theme-0" width="1" height="1" transform="translate(5, 2) rotate(90,0.5,0.5)"/>
      <use xlink:href="#rooftop-0" class="theme-1" width="1" height="1" transform="translate(6, 2) rotate(180,0.5,0.5)"/>
  </g>
</svg>

Answer №2

Here is the information you requested: The symbol now includes a wiewBox attribute: viewBox="0 0 20 20". This indicates that the symbol has a width and height of 20 units each. You can now utilize the symbol in the following manner:

<use xlink:href="#rooftop-0"  width="20" height="20" x="63" y="21"  />

As demonstrated, you can specify the width and height of the symbol, such as width="20" height="20", but feel free to adjust the size as needed. Additionally, you have the option to reposition the symbol using the x and y attributes.

You can also rotate the use element around its center by employing transform="rotate(90,73,31)". This action rotates the element 90 degrees around the point {x:73, y:31}.

<svg viewBox="0 0 211 211">
  <style>
    .grid-line {
      fill: #DDD;
    }
    .grass-fill {
      fill: #8C8;
    }
    
    .theme-0 {
      --roof-color-0: #F44;
      --roof-color-1: #F66;
      --roof-color-2: #F88;
      --roof-color-3: #FAA;
    }
    
    .theme-1 {
      --roof-color-0: #44F;
      --roof-color-1: #66F;
      --roof-color-2: #88F;
      --roof-color-3: #AAF;
    }
  </style>
  
  <defs>
    <pattern id="grid" width="21" height="21" patternUnits="userSpaceOnUse">
      <rect class="grid-line" x="0" y="0" width="1" height="21" />
      <rect class="grid-line" x="0" y="0" width="21" height="1" />
    </pattern>
    
    <symbol id="rooftop-0" viewBox="0 0 20 20">
      <g class="tile">
        <rect class="grass-fill" width="20" height="20" />
        <polygon style="fill: var(--roof-color-0)" points="3,2 17,2 18,8 2,8" />
        <polygon style="fill: var(--roof-color-1)" points="2,8 18,8 17,14 3,14" />
        <polygon style="fill: var(--roof-color-2)" points="8,8 11,14 11,18 8,18" />
        <polygon style="fill: var(--roof-color-3)" points="8,8 8,18 5,18 5,14" />
      </g>
    </symbol>
    

  </defs>
  
  <g>
    <rect fill="#999" width="100%" height="100%" />
    <rect fill="url(#grid)" width="100%" height="100%" />
  </g>
  
  <g transform="translate(1, 1)">
    <use x="42" y="21" xlink:href="#rooftop-0" class="theme-1" width="20" height="20" />
    
    <use x="63" y="21" xlink:href="#rooftop-0" class="theme-0" width="20" height="20" transform="rotate(90,73,31)" />
  </g>
</svg>

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

Is your Z-Index failing to make an impact?

Currently, I am attempting to layer divs on top of a background image. All the elements have designated position attributes, and I have applied a 50% opacity to the background image so that what's behind it is partially visible. Despite setting the z- ...

Arrangement within a span

I've been refreshing my HTML/CSS skills in preparation for a new job opportunity. The last time I dabbled in HTML was way back in 1999... Needless to say, I've fallen quite behind. As a big fan of the "Space Trader" game on Palm OS, I've tak ...

What are some effective ways to ensure the footer stays at the bottom of the page

I managed to successfully position the footer at the bottom of the page, but I noticed that when I resize the screen to fit a phone, especially when there is scrolling on the page, the footer moves up! <footer className="footerContainer"> &l ...

The z-index property in jQuery dialog does not seem to function properly when used within an

When using bootstrap with jQuery dialog, I encountered a strange issue. If the z-index of the dialog is set to 1 or higher in a standalone script, everything works fine. However, when the same script is called inside an iframe, the dialog ends up appearing ...

Tips for showcasing the complete image within v-parallax

For my project, I decided to go with vuetify as the frontend framework. It's a great choice! Now, I have a question about v-parallax - how can I make it display the full image without cropping? Below is some code snippet, and you can find the full cod ...

Trouble with CSS styling arising when launching the MVC application on IIS

Currently working on a website in ASP.Net MVC 5. I am trying to test it on my local IIS (version 8), but encountering an issue where the CSS styling is not being applied. In my _layout.cshtml file, I opted for direct link tags instead of using bundles. &l ...

Create a stylish Bootstrap 3 modal featuring an image and convenient scroll bars

My dilemma is with a modal dialog containing an image of fixed width set at 1500px. I want the image to maintain this size and for scroll bars to appear on smaller screen sizes, allowing users to scroll through the entire image. Essentially, I need the mod ...

In my PHP script, I'm seeking a solution to include a numeric value and then

Greetings, I'm experiencing a peculiar issue where only the first section appears when I submit a number. Here is the code I've implemented and I would greatly appreciate any assistance or guidance. Essentially, my intention is to have a user red ...

Attempting to include a navigation bar within the footer section of my layout page - the master page on my website

Is there a way to add a navigation bar in my footer on the layout page without having to add it to every individual page? I want the icon color for the active page to be red, but only apply this to the current page and not all pages. Currently, when I nav ...

What steps are needed to develop a proper HTML structure for this specific box in order to achieve the desired aesthetics?

Currently working on a box that includes various tags and an input field for adding new tags. The goal is to make this box resemble the tag form used on YouTube: https://i.stack.imgur.com/RSj2p.png This particular layout features a box with existing tags ...

Tips on creating responsive email designs

What is the best way to make emails responsive in a php application when external css files are not supported and media queries cannot be included inline? Looking for alternatives to make emails responsive without external css files and media queries, any ...

Concluding remarks can be found at the end of the article

Is there a way to keep text aligned next to an image without it dropping down and disrupting the layout of the article? * { margin: 0; box-sizing: border-box; } * a:link { text-decoration: none; ...

Tips for showing both label and value on a pie slice in Apex charts

I am currently utilizing apex chart within an angular application to showcase charts. I am specifically focusing on a pie chart and aiming to customize it by displaying labels on the values within each slice of the pie, similar to what is shown in the atta ...

Error encountered in Flatpickr NextJS+TS application: Uncaught DOMException - accessing CSSStyleSheet.cssRules getter is not permitted for cross-origin stylesheet

After successfully integrating Flatpickr into my project, I encountered an issue when testing in mobile view. When trying to open the calendar by clicking on the input field, I received the following error: Uncaught DOMException: CSSStyleSheet.cssRules get ...

Align three divs vertically within one div, all floated to achieve the desired layout

Can someone help me align three divs vertically within a container div? The challenge is that all three divs inside the container are floated - one on the right, one in the center, and one on the left to create a navbar. I've seen the navbars in Boot ...

Alter the Header/Navigation to switch colors depending on the section of the website currently being viewed

I'm currently revamping my personal portfolio website and had an idea for a cool feature. I want the header/navigation bar to change color based on which section of the webpage it's in (the site is one page only). My initial thought was to add o ...

Enhancing an Image Gallery using CSS

Currently in the process of building a website for an upcoming event, and naturally, I need to create an event calendar. For inspiration, I have been referencing this example for its gallery layout and hover effects. However, I am hoping to customize thi ...

Rotation of the SVG coordinate system distorts angles

My comprehension of SVG, particularly the viewport, viewBox, and the user coordinate system, seemed fairly solid. In the initial example provided below, we utilized a viewBox with a matching aspect ratio as the viewport. As expected, there was no distorti ...

What is the best way to pass a CSS root constant to a separate CSS file?

In my Angular test project, I'm experimenting with using the same colors repeatedly. To achieve this, I created a constants.css file where I defined all my root constants, which currently consist of colors. However, I've hit a roadblock when atte ...

What is the inner workings of CSS?

I'm curious about the inner workings of CSS. Does the HTML get interpreted before CSS, or vice versa? Or does it all apply as soon as the browser has constructed the DOM? I would appreciate a detailed explanation on this topic. ...