fritzing / fritzing-parts

Electronic components for use in the Fritzing app (aka the parts library)
http://fritzing.org/parts
Other
505 stars 358 forks source link

Moving parts #386

Open KjellMorgenstern opened 10 months ago

KjellMorgenstern commented 10 months ago

Since we have a simulator in Fritzing, we are trying to improve the support for dynamic SVGs. For example, we might have a knob on a potentiometer that can be turned, or rotate the lever on a servo.

Right now this would be a quite complex custom implementation for each of these examples. But ideally, we'd have support for that in the part format.

One idea is to use data-* attributes, that Fritzing would then apply:

<svg xmlns="http://www.w3.org/2000/svg">
    <g id="knob" data-rotation="0">
        <!-- SVG elements for the knob -->
    </g>
</svg>

Other attributes could change the visibility , color or move an element along a path.

Support for official animated SVG is limited (also in modern browser), so we could use a custom solution. If there is a widespread and dependency free javascript library, we could use that SVG syntax. In the end it will probably not be possible to stay compatible with any library, so it would be just about evaluating the syntax. Of course compatibility would be interesting if we can get better support from designer tools this way, but I don't know any such library.

mMerlin commented 10 months ago

The subset of the svg standard used for Fritzing might have problems, but the full standard supports animations. All that should be needed is a method to 'freeze' an animation at a specific timepoint. https://www.w3.org/TR/SVG/animate.html

KjellMorgenstern commented 10 months ago

I tried this in a browser, and i think the "freeze" was one of the things i had trouble with.

There are a number of javascript libraries that modify the DOM of the SVG for animations.

From the C++ implementation side, i think it doesn't matter much, we need to code the effects anyway.

For many things, like brightness of a LED, we could in theory use CSS, which is also part of the SVG standard. However, i am afraid that this would bring in huge complexity: CSS itself is way more complex than SVG, and I doubt we can get away with supporting only the tiny element that we need. (we don't want it to mess with pcb footprints) Vector tools that export to SVG 2, often with custom annotations already are the most common catch when creating parts.

mMerlin commented 10 months ago

I did not think it would be that complicated. I have not researched extensively, but a quick question to ChatGPT says that QT has the support needed for SVG animations. Previous exploration has found that the code supplied by ChatGPT can be wrong, but it usually gets the basics right. This is likely based on 'full' SVG, not the subset that Fritzing currently uses. For 'settings' type cases, I would expect the details to come from inspector. Instead of extending svg to store data like that, I would lean towards putting it in the fzp file, leaving only an id (and graphics) in the svg to link it to.

Qt, a popular C++ framework, has built-in support for creating and controlling SVG animations. You can integrate SVG animations into your Qt application using Qt's QGraphicsView framework, which allows you to work with SVG files and perform animations with them.

Here are the general steps to work with SVG animations in Qt:

  1. Install Qt: Make sure you have Qt installed on your system. You can download it from the official Qt website.

  2. Include Required Headers: In your Qt application, include the necessary headers:

    #include <QtWidgets>
    #include <QtSvg>
  3. Create a QGraphicsView for SVG: Create a QGraphicsView widget in your application's user interface, and set it up to display SVG content.

    QGraphicsView* svgView = new QGraphicsView;
    QSvgRenderer* svgRenderer = new QSvgRenderer("path/to/your.svg");
    QGraphicsSvgItem* svgItem = new QGraphicsSvgItem;
    svgItem->setSharedRenderer(svgRenderer);
    svgView->setScene(new QGraphicsScene);
    svgView->scene()->addItem(svgItem);

    Replace "path/to/your.svg" with the actual path to your SVG file.

  4. Animating SVG: To animate the SVG content, you can use Qt's animation classes like QPropertyAnimation and QSequentialAnimationGroup. For example, you can animate the position of an SVG item as follows:

    QPropertyAnimation* animation = new QPropertyAnimation(svgItem, "pos");
    animation->setDuration(2000); // 2 seconds
    animation->setStartValue(QPointF(0, 0));
    animation->setEndValue(QPointF(100, 100));
    animation->start();

    This code animates the SVG item's position from (0, 0) to (100, 100) over 2 seconds.

  5. Run the Qt Application: Build and run your Qt application to display the SVG and its animations.

This is a simplified example of integrating SVG animations into a Qt application. You can create more complex animations, control timing, and respond to animation events as needed for your specific use case.

Qt provides extensive documentation and resources for working with SVG and animations, so you may want to explore the Qt documentation and examples for more detailed guidance on this topic.