Forum
    • Categories
    • Register
    • Login

    UPDATE // NEW: Online Knob Builder for HISE!! // SVG's has entered the chat ! =)

    Scheduled Pinned Locked Moved Scripting
    lafknobsknob designerscalable knobonline editor
    39 Posts 11 Posters 378 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • T
      thewind433
      last edited by

      @Chazrox said in NEW: Online Knob Builder for HISE!! by Me :):

      https://rox-knob-builder-for-hise.netlify.app/

      THANKS BROTHA

      1 Reply Last reply Reply Quote 1
      • C
        ccbl
        last edited by

        Is it possible to do sliders? Or is that a future feature maybe?

        ChazroxC 1 Reply Last reply Reply Quote 0
        • ChazroxC
          Chazrox @ccbl
          last edited by

          @ccbl Working on it. 👍

          1 Reply Last reply Reply Quote 1
          • A
            Anhuarcin @Chazrox
            last edited by

            @Chazrox

            I loved it! Are you planning to add a button creator as well?
            MadeWithRoxKNFH_snapshot.png

            const var MadeWithRoxKNFH = Content.createLocalLookAndFeel();
            
            MadeWithRoxKNFH.registerFunction("drawRotarySlider", function(g, obj)
            {
                var a = obj.area;
                var range = obj.max - obj.min;
                var stableSize = a[2] * (1.0 - 2.0 * 0.15);
                var ox = a[0] + (a[2] - stableSize) / 2;
                var oy = a[1] + (a[2] - stableSize) / 2;
                var cx = ox + stableSize / 2;
                var cy = oy + stableSize / 2;
                var sw = stableSize / 200.0;
                var startOffset = 2.5;
                var totalSweep = 2.0 * startOffset;
                var endOffset = -startOffset + totalSweep * (obj.value - obj.min) / range;
            
                // ============ COLOUR CONTROL ============
                // -- Skirt --
                var cSkirtFlat = 0xff121212;
                var cSkirtHover = 0xffFFFFFF;
                // -- Arc Track --
                var cArcTrackOuter = 0x00000000;
                var cArcTrackBackground = 0xff000000;
                // -- Arc Value Basic --
                var cArcBasicGlow = 0x4d007BFF;
                var cArcBasicLow = 0xff004FA3;
                var cArcBasicHigh = 0xff2D61C8;
                // -- Body 1 --
                var cFace1Top = 0xff555558;
                var cFace1Bot = 0xff2A2A2E;
                var cFace1Hover = 0xffFFFFFF;
                var cFace1Outline = 0x4d000000;
            
                // -- skirt --
                var skirtR = stableSize * 0.49;
                var skirtcx = cx + 0 * sw;
                var skirtcy = cy + 0 * sw;
                g.setColour(cSkirtFlat);
                g.fillEllipse([skirtcx - skirtR, skirtcy - skirtR, skirtR * 2, skirtR * 2]);
                g.beginLayer(false);
                g.setColour(cSkirtFlat);
                g.fillEllipse([skirtcx - skirtR, skirtcy - skirtR, skirtR * 2, skirtR * 2]);
                var skirtnp = Content.createPath();
                skirtnp.addRoundedRectangle([skirtcx - skirtR, skirtcy - skirtR, skirtR * 2, skirtR * 2], skirtR);
                g.applyMask(skirtnp, [skirtcx - skirtR, skirtcy - skirtR, skirtR * 2, skirtR * 2], false);
                g.rotate(endOffset, [skirtcx, skirtcy]);
                g.addNoise({"alpha": 0.03, "monochromatic": false, "area": [skirtcx - skirtR, skirtcy - skirtR, skirtR * 2, skirtR * 2]});
                g.rotate(-endOffset, [skirtcx, skirtcy]);
                g.endLayer();
                if (obj.hover || obj.clicked) {
                    g.setColour(Colours.withAlpha(cSkirtHover, 0.03));
                    g.fillEllipse([skirtcx - skirtR, skirtcy - skirtR, skirtR * 2, skirtR * 2]);
                }
            
                // -- ARC TRACK --
                var trkW = 0.45 * 2;
                var Ktrk = Content.createPath();
                Ktrk.addArc([(1.0-trkW)/2, (1.0-trkW)/2, trkW, trkW], -startOffset, startOffset);
                var arTrk = Ktrk.getBounds(stableSize); arTrk[0]+=ox; arTrk[1]+=oy + stableSize * 0;
                g.setColour(cArcTrackOuter);
                g.drawPath(Ktrk, arTrk, {Thickness: stableSize * 0.08 + 0 * sw, EndCapStyle: "rounded", JointStyle: "curved"});
                g.setColour(cArcTrackBackground);
                g.drawPath(Ktrk, arTrk, {Thickness: stableSize * 0.08, EndCapStyle: "rounded", JointStyle: "curved"});
            
                // -- ARC BASIC (gradient) --
                var basW = 0.45 * 2;
                var basR = stableSize * 0.45;
                var Kbas = Content.createPath();
                Kbas.addArc([(1.0-basW)/2, (1.0-basW)/2, basW, basW], -startOffset, endOffset);
                var arBas = Kbas.getBounds(stableSize); arBas[0]+=ox; arBas[1]+=oy + stableSize * 0;
                var basGlowW = stableSize * 0.08 + stableSize * 0.08 * 20 / 10;
                g.setColour(cArcBasicGlow);
                g.drawPath(Kbas, arBas, {Thickness: basGlowW, EndCapStyle: "rounded", JointStyle: "curved"});
                var gx1 = cx + basR * Math.sin(-startOffset);
                var gy1 = cy - basR * Math.cos(-startOffset) + stableSize * 0;
                var gx2 = cx + basR * Math.sin(startOffset);
                var gy2 = cy - basR * Math.cos(startOffset) + stableSize * 0;
                g.setGradientFill([cArcBasicLow, gx1, gy1, cArcBasicHigh, gx2, gy2, false]);
                g.drawPath(Kbas, arBas, {Thickness: stableSize * 0.08, EndCapStyle: "rounded", JointStyle: "curved"});
            
                // -- face1 --
                var face1R = stableSize * 0.41;
                var face1cx = cx + 0 * sw;
                var face1cy = cy + 0 * sw;
                g.setGradientFill([cFace1Top, face1cx, face1cy - face1R + (2 * face1R * (0.5 - 0.5)), cFace1Bot, face1cx, face1cy + face1R + (2 * face1R * (0.5 - 0.5)), false]);
                g.fillEllipse([face1cx - face1R, face1cy - face1R, face1R * 2, face1R * 2]);
                g.beginLayer(false);
                g.setGradientFill([cFace1Top, face1cx, face1cy - face1R + (2 * face1R * (0.5 - 0.5)), cFace1Bot, face1cx, face1cy + face1R + (2 * face1R * (0.5 - 0.5)), false]);
                g.fillEllipse([face1cx - face1R, face1cy - face1R, face1R * 2, face1R * 2]);
                var face1np = Content.createPath();
                face1np.addRoundedRectangle([face1cx - face1R, face1cy - face1R, face1R * 2, face1R * 2], face1R);
                g.applyMask(face1np, [face1cx - face1R, face1cy - face1R, face1R * 2, face1R * 2], false);
                g.rotate(endOffset, [face1cx, face1cy]);
                g.addNoise({"alpha": 0.04, "monochromatic": false, "area": [face1cx - face1R, face1cy - face1R, face1R * 2, face1R * 2]});
                g.rotate(-endOffset, [face1cx, face1cy]);
                g.endLayer();
                if (obj.hover || obj.clicked) {
                    g.setColour(Colours.withAlpha(cFace1Hover, 0.07));
                    g.fillEllipse([face1cx - face1R, face1cy - face1R, face1R * 2, face1R * 2]);
                }
                g.setColour(cFace1Outline);
                g.drawEllipse([face1cx - face1R, face1cy - face1R, face1R * 2, face1R * 2], 1);
            
            });
            
            ChazroxC 1 Reply Last reply Reply Quote 1
            • ChazroxC
              Chazrox @Anhuarcin
              last edited by

              @Anhuarcin said in NEW: Online Knob Builder for HISE!! by Me :):

              button creator

              Glad you love it! Most definitely working buttons also. I'll let everyone know when thats done. 👍 Thanks for giving it a go! 🙏

              1 Reply Last reply Reply Quote 2
              • ChazroxC
                Chazrox
                last edited by

                Pointer Grips?

                Screenshot 2026-06-26 at 4.50.51 PM.png

                1 Reply Last reply Reply Quote 1
                • ChazroxC
                  Chazrox
                  last edited by Chazrox

                  I just pushed a couple of really cool updates!

                  Updates:

                  'Star Body' Layer Elements x 3

                  Screenshot 2026-06-26 at 7.41.04 PM.png

                  Fully Customizable Star knob shapes:
                  Screenshot 2026-06-26 at 7.43.38 PM.png

                  Examples in HISE:
                  Screenshot 2026-06-26 at 7.46.21 PM.png
                  Screenshot 2026-06-26 at 8.00.08 PM.png

                  'Pointer Grip' Layer Element
                  Screenshot 2026-06-26 at 7.41.21 PM.png

                  Pointer grip parameters:
                  Screenshot 2026-06-26 at 7.41.56 PM.png

                  Examples in HISE:
                  Screenshot 2026-06-26 at 4.50.51 PM.png
                  Screenshot 2026-06-26 at 4.46.15 PM.png

                  Enjoy!

                  Here's the link again:
                  https://rox-knob-builder-for-hise.netlify.app/

                  1 Reply Last reply Reply Quote 1
                  • resonantR
                    resonant @Chazrox
                    last edited by

                    @Chazrox Phenomenal work! Thank you for this!

                    ChazroxC 1 Reply Last reply Reply Quote 1
                    • ChazroxC
                      Chazrox @resonant
                      last edited by

                      @resonant Go buck! haha. You're welcome 🙏

                      1 Reply Last reply Reply Quote 0
                      • ChazroxC
                        Chazrox
                        last edited by Chazrox

                        Just a warning...rotation is unstable at point counts around 12 and under. Im working on fixing this now. 🤔

                        ChazroxC 1 Reply Last reply Reply Quote 1
                        • ChazroxC
                          Chazrox @Chazrox
                          last edited by Chazrox

                          STABLE!

                          MyKnobLaf_snapshot (17).png

                          StarKnobWickedFixed.gif
                          You can truly get wicked now! 😎

                          Knob Designer:
                          https://rox-knob-builder-for-hise.netlify.app/

                          Thank you @ustk for the low down on boundaries! 🙏 ⚡

                          dannytaurusD 1 Reply Last reply Reply Quote 3
                          • ChazroxC Chazrox marked this topic as a question
                          • ChazroxC Chazrox has marked this topic as solved
                          • ChazroxC Chazrox marked this topic as a regular topic
                          • dannytaurusD
                            dannytaurus @Chazrox
                            last edited by

                            @Chazrox Excellent work! 👏

                            Meat Beats: https://meatbeats.com
                            Klippr Video: https://klippr.video

                            1 Reply Last reply Reply Quote 1
                            • ChazroxC
                              Chazrox
                              last edited by Chazrox

                              Major Update! :

                              SVG's has entered the chat!

                              KnobBuilderV2_SVG_2STEP.gif
                              (I just noticed I knocked the svg a little off center but you get the point lol)

                              You are now able to import your own SVG file and place it anywhere on the knob.
                              Aside from free placement, you can also choose whether or not the image will rotate with knob or not.
                              You can also shift the image around the knobs center to get some cool effects (heart examples shown below).

                              The process for importing SVG's is easy.

                              Step 1: Activate 'SVG BODY' layer element in the layers column to the left of the UI.
                              Screenshot 2026-06-28 at 12.48.36 AM.png

                              Step 2. Drop in your raw SVG file into the 'SVG Dropzone' (strictly for UI visual reference)
                              Screenshot 2026-06-28 at 12.49.14 AM 2.png

                              Step 3. Get 'HiseScript Path Number Array' with HISE's built in 'SVG to Path Converter'. Paste this into the second dropzone that accepts the HiseScript Path Number Array.
                              Screenshot 2026-06-28 at 12.51.59 AM.png

                              Make sure you use the right conversion or else your code will not work. This is the actual path that gets baked into your exported LAF function.
                              Screenshot 2026-06-28 at 12.54.29 AM.png

                              Paste Hise path number here:
                              Screenshot 2026-06-28 at 12.49.14 AM.png

                              From this point you can continue to design the rest of your knob!
                              These are the available parameters for SVG layers.
                              Screenshot 2026-06-28 at 1.28.26 AM.png

                              Here's an example of how you can offset the SVG and get some unique results:
                              SVG_Offset_Rotation_ExampleWorking.gif

                              ENJOY!

                              LINK:
                              https://rox-knob-builder-for-hise.netlify.app/

                              David HealeyD 1 Reply Last reply Reply Quote 1
                              • David HealeyD
                                David Healey @Chazrox
                                last edited by

                                @Chazrox it would be better to use the 64 encoded string rather than the array

                                Free HISE Bootcamp Full Course for beginners.
                                YouTube Channel - HISE tutorials
                                My Patreon - More HISE tutorials

                                ChazroxC 1 Reply Last reply Reply Quote 0
                                • ChazroxC
                                  Chazrox @David Healey
                                  last edited by Chazrox

                                  @David-Healey I tried that first and was running into a couple problems so I tried this method and worked it out. I may try to just add that also as a different import option. Besides making the output code longer, I figured both methods are just as easy to the user. Have you had a chance to out the app? Would love to get some feedback from you!

                                  David HealeyD 1 Reply Last reply Reply Quote 0
                                  • ustkU
                                    ustk
                                    last edited by

                                    Since it throws us code, I can really see this as integrated Hise popup or specific tool window

                                    Hise made me an F5 dude, any other app just suffers...

                                    ChazroxC 1 Reply Last reply Reply Quote 1
                                    • ChazroxC
                                      Chazrox @ustk
                                      last edited by Chazrox

                                      @ustk That would be sick! Im slowly building other element designers as well. Just trying to get this one feature complete as possible so I can let it go for a bit.

                                      1 Reply Last reply Reply Quote 0
                                      • David HealeyD
                                        David Healey @Chazrox
                                        last edited by

                                        @Chazrox I tried the version you sent me the other day but not the more recent ones. My knob requirements are very basic :)

                                        Free HISE Bootcamp Full Course for beginners.
                                        YouTube Channel - HISE tutorials
                                        My Patreon - More HISE tutorials

                                        ChazroxC 1 Reply Last reply Reply Quote 0
                                        • ChazroxC
                                          Chazrox @David Healey
                                          last edited by Chazrox

                                          @David-Healey Basic is good! Nothing ever wrong with that. I'm also a designer so this is just more intuitive and fun (because why not fun? lol) for me and probably also for people alike. I've seen some pretty interesting knobs with some of the new plugin releases i've been seeing so I just hope this will help Hise users that dont have much coding experience make more and more unique styles faster and easier (which keeps it fun). The knobs i've shown in these examples take less than 5 minutes to make when i've taken hours to make one knob trying to figure out how things work. No more of that. 👍

                                          I've already built a 6-State Button Designer that spits out LAF code and PNG filmstrips. Thats coming soon and it will be just as feature stacked!

                                          Basic button Sample output:
                                          FILMSTRIP>>
                                          button_6_state_strip (7).png

                                          LAF>>

                                          const var MyButtonLaf = Content.createLocalLookAndFeel();
                                          
                                          MyButtonLaf.registerFunction("drawToggleButton", function(g, obj)
                                          {
                                              var a = obj.area;
                                              var cx = a[0] + a[2] * 0.5;
                                              var cy = a[1] + a[3] * 0.5;
                                              var stableSize = Math.min(a[2], a[3]);
                                              var sw = stableSize / 200.0;
                                          
                                              var stateIndex = 0;
                                              if (!obj.enabled) stateIndex = 3;
                                              else if (obj.value && obj.over) stateIndex = 5;
                                              else if (obj.value) stateIndex = 4;
                                              else if (obj.down) stateIndex = 2;
                                              else if (obj.over) stateIndex = 1;
                                          
                                              var widths = [133, 260, 260, 260, 260, 260];
                                              var heights = [70, 70, 70, 70, 70, 70];
                                              var radii = [14, 14, 14, 14, 14, 14];
                                              var offXs = [0, 0, 0, 0, 0, 0];
                                              var offYs = [0, 0, 0, 0, 0, 0];
                                              var useGrad = [true, true, true, true, true, true];
                                              var cTop = [0xff56565D, 0xff707078, 0xff202026, 0xff363636, 0xffD99A2B, 0xffF2BC55];
                                              var cBot = [0xff25252B, 0xff34343C, 0xff0E0E12, 0xff1F1F1F, 0xff7C4B09, 0xff9C610F];
                                              var cFlat = [0xff25252B, 0xff34343C, 0xff0E0E12, 0xff1F1F1F, 0xff7C4B09, 0xff9C610F];
                                              var gradMid = [0.5, 0.5, 0.5, 0.5, 0.5, 0.5];
                                              var outlineOn = [true, true, true, true, true, true];
                                              var cOutline = [0xa6000000, 0xa6000000, 0xa6000000, 0xa6000000, 0xa6000000, 0xa6000000];
                                              var outlineW = [2, 2, 2, 2, 2, 2];
                                              var innerOn = [true, true, true, true, true, true];
                                              var cInner = [0x1fFFFFFF, 0x1fFFFFFF, 0x1fFFFFFF, 0x1fFFFFFF, 0x1fFFFFFF, 0x1fFFFFFF];
                                              var innerW = [1, 1, 1, 1, 1, 1];
                                              var shadowOn = [true, true, true, true, true, true];
                                              var cShadow = [0x73000000, 0x73000000, 0x73000000, 0x73000000, 0x73000000, 0x73000000];
                                              var shadowR = [12, 12, 12, 12, 12, 12];
                                              var shadowX = [0, 0, 0, 0, 0, 0];
                                              var shadowY = [6, 6, 6, 6, 6, 6];
                                              var texts = ["BUTTON", "BUTTON", "BUTTON", "BUTTON", "BUTTON", "BUTTON"];
                                              var textSize = [18, 18, 18, 18, 18, 18];
                                              var cText = [0xffFFFFFF, 0xffFFFFFF, 0xffFFFFFF, 0xff777777, 0xffFFFFFF, 0xffFFFFFF];
                                              var textX = [0, 0, 0, 0, 0, 0];
                                              var textY = [0, 0, 0, 0, 0, 0];
                                          
                                              var bw = widths[stateIndex] * sw;
                                              var bh = heights[stateIndex] * sw;
                                              var br = radii[stateIndex] * sw;
                                              var bx = cx - bw * 0.5 + offXs[stateIndex] * sw;
                                              var by = cy - bh * 0.5 + offYs[stateIndex] * sw;
                                          
                                              if (shadowOn[stateIndex])
                                                  g.drawDropShadow([bx + shadowX[stateIndex] * sw, by + shadowY[stateIndex] * sw, bw, bh], cShadow[stateIndex], shadowR[stateIndex] * sw);
                                          
                                              if (useGrad[stateIndex])
                                              {
                                                  var sh = bh * (gradMid[stateIndex] - 0.5);
                                                  g.setGradientFill([cTop[stateIndex], cx, by + sh, cBot[stateIndex], cx, by + bh + sh, false]);
                                              }
                                              else
                                                  g.setColour(cFlat[stateIndex]);
                                          
                                              g.fillRoundedRectangle([bx, by, bw, bh], br);
                                          
                                              if (innerOn[stateIndex])
                                              {
                                                  g.setColour(cInner[stateIndex]);
                                                  g.drawRoundedRectangle([bx + 2 * sw, by + 2 * sw, bw - 4 * sw, bh - 4 * sw], Math.max(0, br - 2 * sw), innerW[stateIndex] * sw);
                                              }
                                          
                                              if (outlineOn[stateIndex])
                                              {
                                                  g.setColour(cOutline[stateIndex]);
                                                  g.drawRoundedRectangle([bx, by, bw, bh], br, outlineW[stateIndex] * sw);
                                              }
                                          
                                              g.setFont("default", textSize[stateIndex] * sw);
                                              g.setColour(cText[stateIndex]);
                                              g.drawAlignedText(texts[stateIndex], [a[0] + textX[stateIndex] * sw, cy - textSize[stateIndex] * sw * 0.5 + textY[stateIndex] * sw, a[2], textSize[stateIndex] * sw + 4 * sw], "centred");
                                          });
                                          

                                          When I call this knob designer 'done' i'll move on to finishing this one.
                                          🍻

                                          1 Reply Last reply Reply Quote 0
                                          • First post
                                            Last post

                                          16

                                          Online

                                          2.4k

                                          Users

                                          13.8k

                                          Topics

                                          120.3k

                                          Posts