Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sprite Animation Functions Systems #35

Open
wants to merge 7 commits into
base: testing
Choose a base branch
from

Conversation

Reqrefusion
Copy link
Contributor

I am also influencing this technique that I applied on the old site I was working on here. It is only possible with the ratio system #34 . More detailed information can be found in this PR FreeCAD/FreeCAD-Homepage#186. You can look at the direct code system here.

@Reqrefusion
Copy link
Contributor Author

There are certainly question marks about how to use this feature, but these do not overshadow its power.

Now use like these
{{< sprite frame_count="121" frames_per_row="12" frame_width="413" frame_height="400" image_url="https://images2.imgbox.com/8f/d6/nwUrHa7y_o.png" >}}
@Reqrefusion
Copy link
Contributor Author

I did some research and thought it could be used as a shortcode. And that's how I did it. There are a few default values. For example, it should be able to be used like this.
{{< sprite frame_count="121" frames_per_row="12" frame_width="413" frame_height="400" image_url="https://images2.imgbox.com/8f/d6/nwUrHa7y_o.png" >}}

@Reqrefusion
Copy link
Contributor Author

The macro I use for Freecad:

import FreeCADGui as Gui
import FreeCAD
import time
import os
from datetime import datetime

base_directory = 'D:/XXXX'

timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
directory = os.path.join(base_directory, timestamp)

if not os.path.exists(directory):
    os.makedirs(directory)

width = 1920
height = 1080

view = Gui.ActiveDocument.ActiveView

#view.fitAll()

initial_cam_rotation = view.getCameraOrientation()

current_angle = 0

for i in range(1, 73):
    rotation = FreeCAD.Rotation(FreeCAD.Vector(1, 0, 0), current_angle)
    current_cam_rotation = rotation.multiply(initial_cam_rotation)
    view.setCameraOrientation(current_cam_rotation)
    time.sleep(1)
    file_path = os.path.join(directory, f'{i}.png')
    view.saveImage(file_path, width, height, 'Transparent', 'Offscreen (New)')
    print(f'Image {file_path} save directory.')
    current_angle += 1

time.sleep(1)


view.setCameraOrientation(initial_cam_rotation)

print("All images were saved and the camera was returned to its original position.")

The code I used to combine the images

import os
from PIL import Image

# Define the folder path and number of columns
columns = 12  # 12 columns
folder_path = '.'  # Current folder, change if needed

# Get all image files in the folder and sort them alphabetically
image_files = sorted([file for file in os.listdir(folder_path) if file.endswith('.png')])

# Get the number of images
image_count = len(image_files)

# Load the first image and get its dimensions
first_image = Image.open(os.path.join(folder_path, image_files[0])).convert('RGBA')
image_width, image_height = first_image.size
print(f"First image size: {image_width}x{image_height}")

# Calculate the number of rows
row_count = (image_count + columns - 1) // columns  # Round up

# Create a new image (width x height)
combined_image = Image.new('RGBA', (columns * image_width, row_count * image_height))
print("New image created.")

# Load and combine the images
for i, file_name in enumerate(image_files):
    image = Image.open(os.path.join(folder_path, file_name)).convert('RGBA')  # Convert image to RGBA format
    print(f"Loading {file_name}...")
    
    # Calculate the position of the image
    x = (i % columns) * image_width
    y = (i // columns) * image_height
    print(f"Placing image {i+1} at: ({x}, {y})")
    
    # Paste the image onto the combined image
    combined_image.paste(image, (x, y), image)
    print(f"Image {i+1} combined.")

# Save the combined image
combined_image.save('combined.png')
print("Combined image saved: 'combined.png'")

@marcuspollio
Copy link
Owner

Thanks for adding the macros to generate the base images.

I'm pasting below the comments I made on Discord for this PR :

  1. Limit the number of custom parameters in the Shortcode to bare minimum for the moment (background-image PATH, frame-count). I also recommend adjusting the macros above so it's using only one long row.
  2. Use Hugo built-in features to get more properties, see image process docs and math docs, e.g. width="{{ div .Width $frameCount | default "ABC" }} .
  3. Move the Shortcode file to theme/FC/layouts/shortcodes/sprite.html
  4. In /theme/FC/layouts/partials/footer.html add the method to include the JS file
example
{{- if (and (eq .Kind "page") (ne .Layout "archives") (.Param "EnableSpriteAnimation")) -}}
    {{- $SpriteAnimation := resources.Get "js/SpriteAnimation.js" }}
    {{- if hugo.IsProduction }}
        {{- $SpriteAnimation = minify $SpriteAnimation }}
    {{- end }}
    <script type="text/javascript" src="{{ $SpriteAnimation.RelPermalink }}"></script>
{{- end }}

This assumes a EnableSpriteAnimation: true is added in hugo.yaml params (e.g. below EnableUA).

  1. For the JS bit, I see a lot of repetitions for the variables in functions, is it possible to make them globally-scoped ?

@Reqrefusion
Copy link
Contributor Author

Thanks for adding the macros to generate the base images.

I'm pasting below the comments I made on Discord for this PR :

1. Limit the number of custom parameters in the Shortcode to bare minimum for the moment (background-image PATH, frame-count). I also recommend adjusting the macros above so it's using only one _long_ row.

2. Use Hugo built-in features to get more properties, see [image process docs](https://gohugo.io/content-management/image-processing/) and [math docs](https://gohugo.io/functions/math/), e.g. `width="{{ div .Width $frameCount | default "ABC" }} `.

3. Move the Shortcode file to `theme/FC/layouts/shortcodes/sprite.html`

4. In `/theme/FC/layouts/partials/footer.html` add the method to include the JS file

example

5. For the JS bit, I see a lot of repetitions for the variables in functions, is it possible to make them globally-scoped ?

I think I did everything written here.

@marcuspollio
Copy link
Owner

marcuspollio commented Jan 21, 2025

Hi @Reqrefusion

Getting back to your PR.
Thanks for updating and sorry for the long time in-between =P

Could you please keep your comments on the code, so we know what the functions are for.
Also, to test this properly, I would need an example. Is there any on the official FreeCAD website you recommend for testing in this case ?

@Reqrefusion
Copy link
Contributor Author

Hi @Reqrefusion

Getting back to your PR. Thanks for updating and sorry for the long time in-between =P

Could you please keep your comments on the code, so we know what the functions are for. Also, to test this properly, I would need an example. Is there any on the official FreeCAD website you recommend for testing in this case ?

So let me delete the comments lines? FreeCAD site used by taking into account the line feature was made here we have removed the line feature I can give their resources. This is the only line https://codepen.io/turan-furkan-topak/pen/jojvzlk
In addition, the Greetings of Brussels was spoken on this site topic, I wanted to be there.

@marcuspollio
Copy link
Owner

Hi @Reqrefusion

Sorry, I have difficulties understanding what you mean...

  • /* Comments */ : I would like you to keep all the comments you made on the code please (/*A set of functions that makes..., //This function does...)
  • Sprite Animation file to test the feature: indeed, I asked you to simplify the logic here... so I cannot reuse directly the ones your added on the official website. My fault =P I'll see if I can crop them manually to a single line.
  • Yeah, I gave a short presentation of this unified website prototype project. Feedback was really encouraging. I must now get back to some peeps to coordinate a bit the work forwards. Can we discuss these aspects either on the issue or Discord instead of this PR ?

Thanks =D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants