Interactive Radial Menu Using Raphael JS

Greetings and thank you for taking the time to consider my predicament. I am currently working on creating an SVG menu using raphael, but unfortunately, geometry has never been my strong suit.

Below is a visual representation of what I have managed to create so far. While I have successfully implemented the blue center part using CSS, I am struggling to find a suitable solution for the white outer part. Traditional methods like images and CSS do not seem to work due to the block nature of these elements. Ideally, I would like to generate a series of arcs that can adjust in size based on the number of elements.

Do you have any recommendations on how I can create a series of clickable arcs forming a quarter circle with hover effects? Additionally, I will need to place icons on these arcs as well. Any guidance on accomplishing this task would be greatly appreciated.

I have come across some examples utilizing pie charts in raphael, but I am struggling to adapt them to fit my needs. If only I had paid more attention in geometry class...

Once again, thank you for your assistance and expertise.

Answer №1

The structure isn't too complex, it's definitely not as frustrating as dealing with the elliptical arc path syntax in SVG. Both are manageable.

Check out this function that creates a series of arc segments as paths and passes each one (along with any additional data) to a callback function:

function createRadialNavigation( paper, cx, cy, innerRadius, thickness, items, callback, opts ) {
    opts = opts || {};
    
    var startAngle = opts.startAngle || 0;
    var endAngle = opts.endAngle || Math.PI / 2;
    var itemCount = Object.keys(items).length;
    var sliceAngle = (endAngle - startAngle) / itemCount;
    
    var index = 0;
    for (var key in items) {
        var path = [];
        path.push("M", cx + Math.cos(startAngle + sliceAngle * index) * innerRadius, cy + Math.sin(startAngle + sliceAngle * index) * innerRadius);
        path.push("L", cx + Math.cos(startAngle + sliceAngle * index) * (innerRadius + thickness), cy + Math.sin(startAngle + sliceAngle * index) * (innerRadius + thickness));
        path.push("A",
            innerRadius + thickness, innerRadius + thickness,
            sliceAngle, 0, 1,
            cx + Math.cos(startAngle + sliceAngle * (index + 1)) * (innerRadius + thickness), cy + Math.sin(startAngle + sliceAngle * (index + 1)) * (innerRadius + thickness));
        path.push("L", cx + Math.cos(startAngle + sliceAngle * (index + 1)) * innerRadius, cy + Math.sin(startAngle + sliceAngle * (index + 1)) * innerRadius);
        path.push("A",
            innerRadius, innerRadius,
            sliceAngle, 0, 0,
            cx + Math.cos(startAngle + sliceAngle * index) * innerRadius, cy + Math.sin(startAngle + sliceAngle * index) * innerRadius);
        path.push("Z");

        var element = paper.path(path).attr({ fill: 'none', stroke: 'none' });
        callback(key, element, items[key]);

        index++;
    }
}

This function calculates the area for each menu item, creates a corresponding path, and then executes a callback function with the menu details. Adding support for icons can be done separately by enhancing the menu_items data. For a demo of this approach, visit my test page -- please excuse any imperfections due to rushing!

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

Enhance the serialization with more information when submitting

I'm trying to submit form data along with some extra information using serializeArray, but for some reason it's not working as expected. $("#submitBtn").submit(function(ev) { ev.preventDefault(); var info = $(this).serializeArray(); info ...

Identifying when a system window covers an iframe

After watching a fascinating YouTube video (https://www.youtube.com/watch?v=TzPq5_kCfow), I became intrigued by how certain features demonstrated in the video could be implemented using JavaScript. One specific question that arose for me was how one can d ...

Passing a variable between two PHP files and then showcasing its value in a separate third file

bookincome.php receives several inputs, and bi.php calculates the total net income based on the values provided by bookincome.php. It then displays a table containing all the user-given values and the calculated total book income ($tnibeforetax) value. How ...

Flex wrap is causing additional space within the layout

When using flex-wrap, if there are more textBoxes than the available width in the container, they shift to the next line. This is fine, but it leaves too much space between the button and the textBox. This spacing issue can make the layout look odd. I hav ...

Creating an account form using PHP and MySQL

All fields in my registration form are working properly except for the village field, which is returning a '0' in the database. To enhance user experience, I implemented AJAX and jQuery to create dropdown lists for governorate, district, and vil ...

The combination of the card hover effect and the bootstrap modal creates complications

Hey there! I'm in the midst of crafting a webpage using Bootstrap and EJS. My aim is to craft a modal window that pops up when a specific button is clicked to display extra information, and upon clicking an X or "close" button, the modal should disapp ...

Guide: Generating a DIV Element with DOM Instead of Using jQuery

Generate dynamic and user-defined positioning requires input parameters: offsetHeight, offsetLeft, offsetParent, offsetTop, offsetWidth ...

Seeking a light-weight, text-rich editor specifically designed for use on our enterprise website. This editor should be even lighter than TinyMCE

I am in search of a lightweight text editor for an enterprise website, lighter than tinymce with basic buttons for the comment form. It is imperative that the editor also functions properly in IE6. So far, I have tried cleditor 15KB, but it has an issue in ...

Experiencing a lack of desired outcome in Outlook when using simple HTML with table elements

When creating a template for Outlook, I encountered an issue where the logo appeared on the right and the link text was on the left, which is the opposite of what I wanted. How can this be resolved? <center> <table width="600px;" style="margin:au ...

Pressing the dart key will alter the sprite's direction in a 2D game

Recently, I've been working on a Dart game where the user controls a space ship sprite using the W, A, S, and D keys. Pressing these keys will move the sprite up, left, right, and down respectively. Additionally, pressing the Space bar will launch a p ...

Develop a seamless user experience by creating dynamic forms using Jquery, PHP, and

I have been attempting to create a simple contact form using jQuery, AJAX, and PHP without refreshing the page. Everything seems to be working smoothly except for event.preventDefault(); Here are my files: Contact_engine.php <?php $name = $_POST ...

What prevents Django websites from being embedded within another HTML (iframe)?

I attempted to include a Django form within another HTML page, but it's not functioning correctly. I've tried on several of my other Django sites with no success. I even tested it on other websites as well. Is there a restriction on using Django ...

What is the reason that setTimeout does not delay calling a function?

I am looking to develop a straightforward game where a div is duplicated recursively after a short interval. Each new div should have a unique ID (ID+i). The concept is to continuously generate divs that the user must click on to remove before reaching a ...

Dealing with code issues in Subscription forms using AJAX and JQuery

Currently, I am independently studying jQuery and grappling with the Mailchimp Opt-In form code. Despite various existing queries on this topic, I am curious about why my own implementation, as a beginner in jQuery, is not functioning correctly. My intenti ...

The Google Docs viewer is displaying an empty screen

I have been utilizing the Google Docs viewer on my website: <div class="embed-r embed-responsive-a"> <iframe class="embed-responsive-it" src="https://docs.google.com/viewer?embedded=true&amp;url=http://LINK.PDF"></iframe> </div& ...

Having trouble with uploading an image in Laravel using a modal?

For my laravel inventory system, I am facing an issue with uploading images for products. The old code I used for image upload is not working in my current project where I am utilizing a modal and ajax request to save inputs in the database. Can anyone pro ...

What is the best way to display an image and text side by side within a single row in react-table?

I am trying to display an image and text side by side within a single column in a React table. I have successfully added two texts together in a single column using the code below: Header: "Name", id: "User", accessor: (d) => ...

The spacing problem arises from the interaction between two HTML tags containing a Bootstrap file

view image details hereUsing Bootstrap 5, I have a screenshot with an h5 element in a black border and an em tag in a red border. I specified margin 0 to the h5 element but it still does not touch the em tag (in red border). I have tried adjusting line spa ...

Update the iframe located on a different webpage

I am looking to create a dynamic button feature on my website where clicking a button on page1.html will open a new page (portal.html) with an iframe displaying the URL specified in the button. The setup involves two main pages: page1.html, and portal.htm ...

How to create fading directional navigation arrows using the Orbit jQuery plugin?

I want the navigation arrows to only appear when the user hovers over the "#featured" div or its display. My current code achieves this, but the transition is quite abrupt: $("#featured, div.slider-nav").hover(function(){ $("div.slider-nav").animate({ ...