I am having trouble displaying my JavaScript-generated SVG

I attempted to achieve a similar effect (inspired by Fabio Ottaviani) as shown in this CodePen.

However, I'm facing the challenge of creating this SVG using JavaScript.

The ChatGPT response seems correct. The SVG is generated in the DOM but doesn't display on the screen.

<!DOCTYPE html>
<html lang='en'>
<head>
  <title>Creating SVG with JavaScript</title>
</head>
<body>
  <script>
    // Function to create an SVG element with specified attributes
    function createSVGElement(tag, attributes) {
      const element = document.createElementNS("http://www.w3.org/2000/svg", tag);
      for (const key in attributes) {
        element.setAttribute(key, attributes[key]);
      }
      return element;
    }

    // Creating a circle with the "displacement" class
    const circleMask = createSVGElement("circle", {
      cx: "200",
      cy: "200",
      r: "100",
      fill: "white",
      class: "displacement",
    });

    // Creating the image
    const image = createSVGElement("image", {
      "xlink:href": "https://images.unsplash.com/photo-1630563451961-ac2ff27616ab?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTF8fGFwcGxlfGVufDB8fDB8fHww&auto=format&fit=crop&w=400&h=400&q=60",
      width: "400",
      height: "400",
      mask: "url(#circleMask)",
    });

    // Creating the mask and adding the circle
    const mask = createSVGElement("mask", { id: "circleMask" });
    mask.appendChild(circleMask);

    // Creating the <defs> element and adding the mask
    const defs = createSVGElement("defs");
    defs.appendChild(mask);

    // Creating the SVG and adding the elements above
    const svgElement = createSVGElement("svg", {
      width: "400",
      height: "400",
      version: "1.1",
      xmlns: "http://www.w3.org/2000/svg",
    });
    svgElement.appendChild(defs);
    svgElement.appendChild(image);

    // Adding SVG to the body
    document.body.appendChild(svgElement);
    
  </script>
</body>
</html>;

    
  </script>
</body>
</html>

I've tried :

image.addEventListener("load", function () {
      svgElement.appendChild(image);
      document.body.appendChild(svgElement);
    });

In an attempt to wait for the image to load...

Additionally, I've also tried:

document.addEventListener("DOMContentLoaded", function () {
      document.body.appendChild(svgElement);
    });

Unfortunately, none of these methods yielded any results :(

Although the SVG appears in the DOM when inspected, everything seems fine, yet it doesn't display as intended. Here's a screenshot from the browser showing the issue.

I have ruled out the common mistake of using document.createElement. Any thoughts or ideas?

Answer №1

To remove the "xlink" namespace from the href attribute on the image (as it is outdated: xlink:href), and make sure to wait for the DOM to load before adding any content.

<!DOCTYPE html>
<html lang='en'>

<head>
  <title>Creating SVG with JavaScript</title>
  <script>
    document.addEventListener('DOMContentLoaded', e => {
      // Function for generating an SVG element with specified attributes
      function createSVGElement(tag, attributes) {
        const element = document.createElementNS("http://www.w3.org/2000/svg", tag);
        for (const key in attributes) {
          element.setAttribute(key, attributes[key]);
        }
        return element;
      }

      // Generating a circle with the "displacement" class
      const circleMask = createSVGElement("circle", {
        cx: "200",
        cy: "200",
        r: "100",
        fill: "white",
        class: "displacement",
      });

      // Generating the image
      const image = createSVGElement("image", {
        "href": "https://images.unsplash.com/photo-1630563451961-ac2ff27616ab?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTF8fGFwcGxlfGVufDB8fDB8fHww&auto=format&fit=crop&w=400&h=400&q=60",
        width: "400",
        height: "400",
        mask: "url(#circleMask)",
      });

      // Generating the mask and including the circle
      const mask = createSVGElement("mask", {
        id: "circleMask"
      });
      mask.appendChild(circleMask);

      // Generating the <defs> element and adding the mask
      const defs = createSVGElement("defs");
      defs.appendChild(mask);

      // Generating the SVG and adding the elements above
      const svgElement = createSVGElement("svg", {
        width: "400",
        height: "400",
        version: "1.1",
        xmlns: "http://www.w3.org/2000/svg",
      });
      svgElement.appendChild(defs);
      svgElement.appendChild(image);

      // Adding SVG to body
      document.body.appendChild(svgElement);
    });
  </script>
</head>

<body>

</body>

</html>

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

Material-UI icons refusing to show up on the display

I've been working on creating a sidebar component and importing various icons to enhance the UI, but for some reason they are not displaying on the screen. I even tried other suggested solutions without success. <SidebarOption Icon = {InsertComment ...

Steps for implementing remote modals in Bootstrap 5 using CS HTML

I'm attempting to implement a remote modal window in Bootstrap 5 with C# MVC. The endpoint for the modal partial view is configured correctly. According to this discussion on Github, all that needs to be done is to call some JavaScript. However, it ...

Can you identify any issues with this Basic authentication code for an HTTP-Get request?

My setup consists of node.js restify as the backend for running a REST API server, and angularjs as the front-end for making HTTP GET calls. The REST server is configured with HTTP Basic Authentication using the username foo and password bar. To confirm t ...

JavaScript: Redirect to a webpage with randomized sections within the address

When I access an HTML site, my goal is to automatically redirect to the following page: www.xyz.de?user=default&f1=OPTION1&f2=OPTION2&f3=OPTION3&f4=OPTION4&f5=OPTION5&... etc. To achieve this, I need to randomly select values for ...

Sending AJAX information to multiple pages

I have created an HTML page where I am struggling to pass two variables using the POST method to a PHP page. The PHP page is supposed to accept these variables and then call an API to retrieve data based on them. However, my challenge is in receiving this ...

Activate a button utilizing jQuery keyboard functionality

Here is what I have accomplished so far: http://jsfiddle.net/qEKfg/ I have created two buttons that activate on click and resemble keyboard keys. My goal is to make them animate only when the corresponding keys (CTRL and ...

Leveraging the power of react routes for efficient navigation within a react-based application

I am currently facing an issue with setting up routes for a basic react application using react-router. The given routes don't seem to match and the switch defaults to displaying the 404 page. Below is the code for the routes: import { BrowserRout ...

ESLint error caught off guard by function expression in customized MUI Snackbar Component with Alert

Struggling to create a personalized MUI Snackbar using the MUI Alert example from the official Documentation, but facing ESlint errors: error Unexpected function expression prefer-arrow-callback error Prop spreading is forbidden react/jsx-props-no-s ...

Navigate to items within a content block with a set height

I have a <div> that has a fixed height and overflow-y: scroll. Inside this div, there is mostly a <p> tag containing a long text with some highlighting (spans with background-color and a numbered id attribute). Just to note, this is an HTML5 a ...

Once the form is submitted, Vue automatically resets all the data

export default { data() { return { usrName: null, pass1: null, pass2: null, regState: {stateCode:-1}, } }, methods: { register: function () { this.axios.post("/login/", { baseURL: 'http://127 ...

Increasing the sms counter in javascript once it reaches 160 characters

I am facing an issue with my two counters that are used to track the number of characters in a message. Everything works fine until 160 characters, but after that point, the first counter stops at 0 instead of resetting back to 160 and decreasing from ther ...

trouble with maintaining nodejs mariadb connection

Hello, I am working with nodejs to create a rest API However, I have encountered an issue Let's take a look at the code var http = require('http'); var url = require('url'); var mariadb = require('mariadb'); http.c ...

What is the best way to incorporate a JSON file into a JavaScript class?

I attempted to load a JSON file within a JavaScript class, but encountered an issue where the loaded data was only accessible inside a specific function. class CreatePage { constructor() { var request = new XMLHttpRequest(); request. ...

Unable to create follow/unfollow feature with jquery ajax

Issue: While the database part for following and unfollowing actions is functioning correctly, there seems to be a problem with the jQuery and Ajax section. The follow button changes to unfollow (with some CSS styling) only after refreshing the page, rathe ...

Utilizing Vue.js transitions to display content with a one-time transition limit

I have followed the Vue.js documentation given below to implement the show transition, but I'm struggling with stopping the hide effect on the second click. Is there a way to achieve this? https://v2.vuejs.org/v2/guide/transitions.html#a Can I conti ...

Selecting the most popular post from a Facebook group

Here is the JSON file that I am currently using JSON.parse(); in Google Apps Script. Currently, I have found a temporary solution with this code by selecting posts that have more than 15 likes. However, my goal is to be able to select the post with the ...

How can I ensure that Bootstrap Navbar elements are all aligned in a single line?

https://i.sstatic.net/pkxyI.pngI'm experiencing an issue with my code, and I suspect it might be related to Bootstrap. I've tried using align-items-center but it doesn't seem to work as expected. Changing the display property to inline or in ...

Version 2 of the Microsoft Logo Animation

I made some changes to my Microsoft logo animation project. You can view the updated version on CodePen. Overall, I'm pretty happy with how it turned out except for one issue. I'm struggling to determine the right timing to end the animation so ...

Azure webhosting blocks the use of AJAX calls

There is a PHP script hosted on my Azure server that returns JSON when accessed through the browser. However, I am having trouble making an AJAX call to this script as none of my requests seem to go through. The issue remains unclear. You can see a failed ...

Changing TypeScript Enum from String to Number in Angular

Does anyone know how to convert a Typescript enum value to a number for display in a dropdown but passing the numeric value on submit? Here is how the enum is currently set up: I am currently able to output the string key of the object when it is emitted ...