0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-26 00:36:12 -05:00

Merge pull request #167 from uxbox/195/alignment

195/alignment
This commit is contained in:
Andrey Antukh 2020-04-09 10:53:40 +02:00 committed by GitHub
commit ebc9d7aa63
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 197 additions and 32 deletions

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500.00001 500.00001" width="500" height="500"><path d="M238.53-.837c6.907 0 13.812 2.066 19.564 6.2 3.378 2.43 6.874 6.133 7.763 8.23.89 2.093 1.529 107.942 1.529 107.942v255.256s-.64 105.846-1.532 107.94c-.889 2.093-4.384 5.797-7.76 8.228-11.502 8.272-27.626 8.272-39.129 0-3.377-2.428-6.871-6.131-7.76-8.228-.891-2.094-1.529-107.944-1.529-107.944V121.533s.641-105.847 1.532-107.94c.889-2.096 4.383-5.8 7.76-8.23 5.751-4.134 12.657-6.2 19.563-6.2zm251.079 146c6.997 0 12.628 4.055 12.628 9.095v51.808c0 5.04-5.63 9.096-12.628 9.096H14.864c-6.996 0-12.627-4.057-12.627-9.096v-51.808c0-5.04 5.631-9.096 12.627-9.096zm-106.2 123.998c6.997 0 12.628 4.057 12.628 9.096v51.809c0 5.037-5.631 9.097-12.629 9.097H82.194c-6.996 0-12.627-4.06-12.627-9.097v-51.809c0-5.04 5.631-9.096 12.627-9.096z"/></svg>

After

Width:  |  Height:  |  Size: 849 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500.00001 500.00001" width="500" height="500"><path d="M23.96 0c5.542 0 11.085 2.066 15.7 6.201 2.712 2.43 5.518 6.133 6.231 8.229.716 2.094 1.228 107.943 1.228 107.943v255.254s-.515 105.847-1.23 107.94c-.713 2.097-3.518 5.797-6.228 8.232-9.232 8.268-22.173 8.268-31.405 0-2.711-2.432-5.515-6.135-6.229-8.232C1.312 483.474.8 377.627.8 377.627V122.371S1.314 16.524 2.03 14.43C2.743 12.335 5.547 8.63 8.258 6.2 12.874 2.066 18.416 0 23.96 0zm466.707 146c5.613 0 10.133 4.056 10.133 9.095v51.808c0 5.04-4.52 9.096-10.133 9.096h-381.04c-5.615 0-10.135-4.056-10.135-9.096v-51.808c0-5.04 4.52-9.095 10.135-9.095zM351.946 270c5.613 0 10.132 4.055 10.132 9.095v51.807c0 5.04-4.52 9.097-10.132 9.097H110.184c-5.615 0-10.135-4.056-10.135-9.097v-51.807c0-5.04 4.52-9.096 10.135-9.096z"/></svg>

After

Width:  |  Height:  |  Size: 836 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500.00001 500.00001" width="500" height="500"><path d="M477.641 0c-5.543 0-11.083 2.066-15.7 6.201-2.712 2.43-5.519 6.133-6.232 8.229-.714 2.094-1.226 107.943-1.226 107.943v255.254s.515 105.847 1.229 107.94c.714 2.097 3.52 5.797 6.23 8.232 9.23 8.268 22.172 8.268 31.403 0 2.713-2.432 5.516-6.135 6.23-8.232.713-2.093 1.225-107.94 1.225-107.94V122.371s-.512-105.847-1.23-107.941c-.713-2.095-3.516-5.799-6.225-8.229-4.617-4.135-10.16-6.2-15.704-6.2zM10.935 146C5.32 146 .8 150.056.8 155.095v51.808c0 5.04 4.52 9.096 10.135 9.096h381.04c5.616 0 10.136-4.056 10.136-9.096v-51.808c0-5.04-4.52-9.095-10.136-9.095zm138.721 124c-5.615 0-10.135 4.055-10.135 9.095v51.807c0 5.04 4.52 9.097 10.135 9.097h241.761c5.617 0 10.136-4.056 10.136-9.097v-51.807c0-5.04-4.52-9.096-10.136-9.096z"/></svg>

After

Width:  |  Height:  |  Size: 838 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500.00001 500.00001" width="500" height="500"><path d="M0 476.001c0-5.543 2.066-11.086 6.201-15.7 2.43-2.712 6.133-5.519 8.229-6.233 2.094-.714 107.943-1.225 107.943-1.225h255.254s105.846.511 107.94 1.229c2.097.714 5.797 3.517 8.231 6.229 8.27 9.23 8.27 22.173 0 31.404-2.43 2.712-6.134 5.515-8.23 6.23-2.095.713-107.941 1.225-107.941 1.225H122.37s-105.847-.512-107.941-1.23c-2.095-.713-5.799-3.516-8.229-6.229C2.066 487.088 0 481.544 0 476.001zM146 9.294C146 3.68 150.056-.84 155.095-.84h51.808c5.04 0 9.096 4.52 9.096 10.134v381.04c0 5.613-4.056 10.136-9.096 10.136h-51.808c-5.04 0-9.095-4.523-9.095-10.136zm123.999 138.722c0-5.615 4.056-10.135 9.096-10.135h51.807c5.04 0 9.097 4.52 9.097 10.135v241.761c0 5.613-4.056 10.136-9.097 10.136h-51.807c-5.04 0-9.096-4.523-9.096-10.136z"/></svg>

After

Width:  |  Height:  |  Size: 844 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500.00001 500.00001" width="500" height="500"><path d="M0 261.631c0-6.906 2.066-13.812 6.201-19.563 2.43-3.38 6.133-6.874 8.229-7.763 2.094-.89 107.943-1.531 107.943-1.531h255.254s105.846.642 107.94 1.531c2.097.89 5.797 4.384 8.231 7.76 8.27 11.502 8.27 27.626 0 39.129-2.43 3.38-6.134 6.871-8.23 7.76-2.095.889-107.941 1.527-107.941 1.527H122.37s-105.847-.642-107.941-1.532c-2.095-.889-5.799-4.382-8.229-7.76C2.066 275.443 0 268.537 0 261.631zM146 10.553c0-6.996 4.056-12.628 9.095-12.628h51.808c5.04 0 9.096 5.632 9.096 12.628v474.744c0 6.997-4.056 12.628-9.096 12.628h-51.808c-5.04 0-9.095-5.63-9.095-12.628zm123.999 106.2c0-6.996 4.056-12.627 9.096-12.627h51.807c5.04 0 9.097 5.631 9.097 12.627v301.214c0 6.998-4.056 12.629-9.097 12.629h-51.807c-5.04 0-9.096-5.631-9.096-12.629z"/></svg>

After

Width:  |  Height:  |  Size: 845 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500.00001 500.00001" width="500" height="500"><path d="M0 22.318c0 5.544 2.066 11.085 6.201 15.702 2.43 2.712 6.133 5.517 8.229 6.23 2.094.714 107.943 1.23 107.943 1.23h255.254s105.846-.516 107.94-1.23c2.097-.713 5.797-3.518 8.231-6.228 8.27-9.231 8.27-22.173 0-31.405-2.43-2.712-6.134-5.515-8.23-6.228-2.095-.717-107.941-1.23-107.941-1.23H122.37S16.524-.324 14.43.39C12.335 1.103 8.63 3.906 6.2 6.617 2.066 11.233 0 16.775 0 22.318zm146 466.71c0 5.612 4.056 10.132 9.095 10.132h51.808c5.04 0 9.096-4.52 9.096-10.133V107.986c0-5.615-4.056-10.135-9.096-10.135h-51.808c-5.04 0-9.095 4.52-9.095 10.135zm123.999-138.722c0 5.612 4.056 10.132 9.096 10.132h51.807c5.04 0 9.097-4.52 9.097-10.132V108.543c0-5.615-4.056-10.135-9.097-10.135h-51.807c-5.04 0-9.096 4.52-9.096 10.135z"/></svg>

After

Width:  |  Height:  |  Size: 833 B

View file

@ -1 +1 @@
<svg height="500" viewBox="0 0 500.00001 500.00001" width="500" xmlns="http://www.w3.org/2000/svg"><path d="m9.0957031 0c-5.0392472 0-9.0957031 4.0564559-9.0957031 9.0957031v51.8085939c0 5.039247 4.0564559 9.095703 9.0957031 9.095703h481.8085969c5.03924 0 9.0957-4.056456 9.0957-9.095703v-51.8085939c0-5.0392472-4.05646-9.0957031-9.0957-9.0957031zm69.9160159 146c-5.039247 0-9.095703 4.05646-9.095703 9.0957v51.8086c0 5.03924 4.056456 9.0957 9.095703 9.0957h341.976561c5.03925 0 9.0957-4.05646 9.0957-9.0957v-51.8086c0-5.03924-4.05645-9.0957-9.0957-9.0957zm-32.839844 144c-5.039247 0-9.095703 4.05646-9.095703 9.0957v51.8086c0 5.03924 4.056456 9.0957 9.095703 9.0957h407.656245c5.03925 0 9.09571-4.05646 9.09571-9.0957v-51.8086c0-5.03924-4.05646-9.0957-9.09571-9.0957zm95.339845 140c-5.03925 0-9.0957 4.05646-9.0957 9.0957v51.8086c0 5.03924 4.05645 9.0957 9.0957 9.0957h216.97656c5.03925 0 9.0957-4.05646 9.0957-9.0957v-51.8086c0-5.03924-4.05645-9.0957-9.0957-9.0957z"/></svg>
<svg height="500" viewBox="0 0 500.00001 500.00001" width="500" xmlns="http://www.w3.org/2000/svg"><path d="m9.0957031 0c-5.0392472 0-9.0957031 4.0564559-9.0957031 9.0957031v51.8085939c0 5.039247 4.0564559 9.095703 9.0957031 9.095703h481.8085969c5.03924 0 9.0957-4.056456 9.0957-9.095703v-51.8085939c0-5.0392472-4.05646-9.0957031-9.0957-9.0957031zm69.9160159 146c-5.039247 0-9.095703 4.05646-9.095703 9.0957v51.8086c0 5.03924 4.056456 9.0957 9.095703 9.0957h341.976561c5.03925 0 9.0957-4.05646 9.0957-9.0957v-51.8086c0-5.03924-4.05645-9.0957-9.0957-9.0957zm-32.839844 144c-5.039247 0-9.095703 4.05646-9.095703 9.0957v51.8086c0 5.03924 4.056456 9.0957 9.095703 9.0957h407.656245c5.03925 0 9.09571-4.05646 9.09571-9.0957v-51.8086c0-5.03924-4.05646-9.0957-9.09571-9.0957zm95.339845 140c-5.03925 0-9.0957 4.05646-9.0957 9.0957v51.8086c0 5.03924 4.05645 9.0957 9.0957 9.0957h216.97656c5.03925 0 9.0957-4.05646 9.0957-9.0957v-51.8086c0-5.03924-4.05645-9.0957-9.0957-9.0957z"/></svg>

Before

Width:  |  Height:  |  Size: 976 B

After

Width:  |  Height:  |  Size: 977 B

View file

@ -1 +1 @@
<svg height="500" viewBox="0 0 500.00001 500.00001" width="500" xmlns="http://www.w3.org/2000/svg"><path d="m9.0957031 0c-5.0392472 0-9.0957031 4.0564559-9.0957031 9.0957031v51.8085939c0 5.039247 4.0564559 9.095703 9.0957031 9.095703h481.8085969c5.03924 0 9.0957-4.056456 9.0957-9.095703v-51.8085939c0-5.0392472-4.05646-9.0957031-9.0957-9.0957031zm0 146c-5.0392472 0-9.0957031 4.05646-9.0957031 9.0957v51.8086c0 5.03924 4.0564559 9.0957 9.0957031 9.0957h481.8085969c5.03924 0 9.0957-4.05646 9.0957-9.0957v-51.8086c0-5.03924-4.05646-9.0957-9.0957-9.0957zm0 142c-5.0392472 0-9.0957031 4.05646-9.0957031 9.0957v51.8086c0 5.03924 4.0564559 9.0957 9.0957031 9.0957h481.8085969c5.03924 0 9.0957-4.05646 9.0957-9.0957v-51.8086c0-5.03924-4.05646-9.0957-9.0957-9.0957zm0 142c-5.0392472 0-9.0957031 4.05646-9.0957031 9.0957v51.8086c0 5.03924 4.0564559 9.0957 9.0957031 9.0957h481.8085969c5.03924 0 9.0957-4.05646 9.0957-9.0957v-51.8086c0-5.03924-4.05646-9.0957-9.0957-9.0957z"/></svg>
<svg height="500" viewBox="0 0 500.00001 500.00001" width="500" xmlns="http://www.w3.org/2000/svg"><path d="m9.0957031 0c-5.0392472 0-9.0957031 4.0564559-9.0957031 9.0957031v51.8085939c0 5.039247 4.0564559 9.095703 9.0957031 9.095703h481.8085969c5.03924 0 9.0957-4.056456 9.0957-9.095703v-51.8085939c0-5.0392472-4.05646-9.0957031-9.0957-9.0957031zm0 146c-5.0392472 0-9.0957031 4.05646-9.0957031 9.0957v51.8086c0 5.03924 4.0564559 9.0957 9.0957031 9.0957h481.8085969c5.03924 0 9.0957-4.05646 9.0957-9.0957v-51.8086c0-5.03924-4.05646-9.0957-9.0957-9.0957zm0 142c-5.0392472 0-9.0957031 4.05646-9.0957031 9.0957v51.8086c0 5.03924 4.0564559 9.0957 9.0957031 9.0957h481.8085969c5.03924 0 9.0957-4.05646 9.0957-9.0957v-51.8086c0-5.03924-4.05646-9.0957-9.0957-9.0957zm0 142c-5.0392472 0-9.0957031 4.05646-9.0957031 9.0957v51.8086c0 5.03924 4.0564559 9.0957 9.0957031 9.0957h481.8085969c5.03924 0 9.0957-4.05646 9.0957-9.0957v-51.8086c0-5.03924-4.05646-9.0957-9.0957-9.0957z"/></svg>

Before

Width:  |  Height:  |  Size: 974 B

After

Width:  |  Height:  |  Size: 975 B

View file

@ -1 +1 @@
<svg height="500" viewBox="0 0 500.00001 500.00001" width="500" xmlns="http://www.w3.org/2000/svg"><path d="m9.0957031 0c-5.0392472 0-9.0957031 4.0564559-9.0957031 9.0957031v51.8085939c0 5.039247 4.0564559 9.095703 9.0957031 9.095703h481.8085969c5.03924 0 9.0957-4.056456 9.0957-9.095703v-51.8085939c0-5.0392472-4.05646-9.0957031-9.0957-9.0957031zm0 146c-5.0392472 0-9.0957031 4.05646-9.0957031 9.0957v51.8086c0 5.03924 4.0564559 9.0957 9.0957031 9.0957h341.9785169c5.03925 0 9.0957-4.05646 9.0957-9.0957v-51.8086c0-5.03924-4.05645-9.0957-9.0957-9.0957zm0 144c-5.0392472 0-9.0957031 4.05646-9.0957031 9.0957v51.8086c0 5.03924 4.0564559 9.0957 9.0957031 9.0957h407.6562469c5.03925 0 9.09571-4.05646 9.09571-9.0957v-51.8086c0-5.03924-4.05646-9.0957-9.09571-9.0957zm0 140c-5.0392472 0-9.0957031 4.05646-9.0957031 9.0957v51.8086c0 5.03924 4.0564559 9.0957 9.0957031 9.0957h216.9785169c5.03925 0 9.0957-4.05646 9.0957-9.0957v-51.8086c0-5.03924-4.05645-9.0957-9.0957-9.0957z"/></svg>
<svg height="500" viewBox="0 0 500.00001 500.00001" width="500" xmlns="http://www.w3.org/2000/svg"><path d="m9.0957031 0c-5.0392472 0-9.0957031 4.0564559-9.0957031 9.0957031v51.8085939c0 5.039247 4.0564559 9.095703 9.0957031 9.095703h481.8085969c5.03924 0 9.0957-4.056456 9.0957-9.095703v-51.8085939c0-5.0392472-4.05646-9.0957031-9.0957-9.0957031zm0 146c-5.0392472 0-9.0957031 4.05646-9.0957031 9.0957v51.8086c0 5.03924 4.0564559 9.0957 9.0957031 9.0957h341.9785169c5.03925 0 9.0957-4.05646 9.0957-9.0957v-51.8086c0-5.03924-4.05645-9.0957-9.0957-9.0957zm0 144c-5.0392472 0-9.0957031 4.05646-9.0957031 9.0957v51.8086c0 5.03924 4.0564559 9.0957 9.0957031 9.0957h407.6562469c5.03925 0 9.09571-4.05646 9.09571-9.0957v-51.8086c0-5.03924-4.05646-9.0957-9.09571-9.0957zm0 140c-5.0392472 0-9.0957031 4.05646-9.0957031 9.0957v51.8086c0 5.03924 4.0564559 9.0957 9.0957031 9.0957h216.9785169c5.03925 0 9.0957-4.05646 9.0957-9.0957v-51.8086c0-5.03924-4.05645-9.0957-9.0957-9.0957z"/></svg>

Before

Width:  |  Height:  |  Size: 977 B

After

Width:  |  Height:  |  Size: 978 B

View file

@ -1 +1 @@
<svg height="500" viewBox="0 0 500.00001 500.00001" width="500" xmlns="http://www.w3.org/2000/svg"><path d="m490.9043 0c5.03924 0 9.0957 4.0564559 9.0957 9.0957031v51.8085939c0 5.039247-4.05646 9.095703-9.0957 9.095703h-481.8086c-5.03924 0-9.0957-4.056456-9.0957-9.095703v-51.8085939c0-5.0392472 4.05646-9.0957031 9.0957-9.0957031zm0 146c5.03924 0 9.0957 4.05646 9.0957 9.0957v51.8086c0 5.03924-4.05646 9.0957-9.0957 9.0957h-341.97852c-5.03925 0-9.0957-4.05646-9.0957-9.0957v-51.8086c0-5.03924 4.05645-9.0957 9.0957-9.0957zm0 144c5.03924 0 9.0957 4.05646 9.0957 9.0957v51.8086c0 5.03924-4.05646 9.0957-9.0957 9.0957h-407.65625c-5.03925 0-9.09571-4.05646-9.09571-9.0957v-51.8086c0-5.03924 4.05646-9.0957 9.09571-9.0957zm0 140c5.03924 0 9.0957 4.05646 9.0957 9.0957v51.8086c0 5.03924-4.05646 9.0957-9.0957 9.0957h-216.97852c-5.03925 0-9.0957-4.05646-9.0957-9.0957v-51.8086c0-5.03924 4.05645-9.0957 9.0957-9.0957z"/></svg>
<svg height="500" viewBox="0 0 500.00001 500.00001" width="500" xmlns="http://www.w3.org/2000/svg"><path d="m490.9043 0c5.03924 0 9.0957 4.0564559 9.0957 9.0957031v51.8085939c0 5.039247-4.05646 9.095703-9.0957 9.095703h-481.8086c-5.03924 0-9.0957-4.056456-9.0957-9.095703v-51.8085939c0-5.0392472 4.05646-9.0957031 9.0957-9.0957031zm0 146c5.03924 0 9.0957 4.05646 9.0957 9.0957v51.8086c0 5.03924-4.05646 9.0957-9.0957 9.0957h-341.97852c-5.03925 0-9.0957-4.05646-9.0957-9.0957v-51.8086c0-5.03924 4.05645-9.0957 9.0957-9.0957zm0 144c5.03924 0 9.0957 4.05646 9.0957 9.0957v51.8086c0 5.03924-4.05646 9.0957-9.0957 9.0957h-407.65625c-5.03925 0-9.09571-4.05646-9.09571-9.0957v-51.8086c0-5.03924 4.05646-9.0957 9.09571-9.0957zm0 140c5.03924 0 9.0957 4.05646 9.0957 9.0957v51.8086c0 5.03924-4.05646 9.0957-9.0957 9.0957h-216.97852c-5.03925 0-9.0957-4.05646-9.0957-9.0957v-51.8086c0-5.03924 4.05645-9.0957 9.0957-9.0957z"/></svg>

Before

Width:  |  Height:  |  Size: 919 B

After

Width:  |  Height:  |  Size: 920 B

View file

@ -21,7 +21,7 @@ $color-warning: #e6a16f;
$color-danger: #de4762;
$color-info: #59b9e2;
// Mixing Color varriable for creating both light and dark colors
// Mixing Color variable for creating both light and dark colors
$mix-percentage-dark: 81%;
$mix-percentage-darker: 60%;
$mix-percentage-light: 80%;

View file

@ -51,6 +51,7 @@
@import 'main/partials/project-bar';
@import 'main/partials/sidebar';
@import 'main/partials/sidebar-tools';
@import 'main/partials/sidebar-align-options';
@import 'main/partials/sidebar-element-options';
@import 'main/partials/sidebar-icons';
@import 'main/partials/sidebar-layers';

View file

@ -0,0 +1,38 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) 2015-2016 Andrey Antukh <niwi@niwi.nz>
// Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
.align-options {
display: flex;
width: 100%;
justify-content: space-evenly;
border-bottom: solid 1px $color-gray-60;
.align-button {
cursor: pointer;
padding: $small;
svg {
height: 16px;
width: 16px;
fill: $color-gray-light;
}
&:hover {
background-color: $color-primary;
svg {
fill: $color-gray-50;
}
}
&.disabled {
background-color: transparent;
cursor: default;
svg {
fill: $color-gray-dark;
}
}
}
}

View file

@ -11,10 +11,10 @@
(def action (icon-xref :action))
(def actions (icon-xref :actions))
(def align-center (icon-xref :align-center))
(def align-justify (icon-xref :align-justify))
(def align-left (icon-xref :align-left))
(def align-right (icon-xref :align-right))
(def text-align-center (icon-xref :text-align-center))
(def text-align-justify (icon-xref :text-align-justify))
(def text-align-left (icon-xref :text-align-left))
(def text-align-right (icon-xref :text-align-right))
(def alignment (icon-xref :alignment))
(def arrow (icon-xref :arrow))
(def arrow-down (icon-xref :arrow-down))
@ -69,6 +69,12 @@
(def ruler-tool (icon-xref :ruler-tool))
(def save (icon-xref :save))
(def search (icon-xref :search))
(def shape-halign-left (icon-xref :shape-halign-left))
(def shape-halign-center (icon-xref :shape-halign-center))
(def shape-halign-right (icon-xref :shape-halign-right))
(def shape-valign-top (icon-xref :shape-valign-top))
(def shape-valign-center (icon-xref :shape-valign-center))
(def shape-valign-bottom (icon-xref :shape-valign-bottom))
(def size-horiz (icon-xref :size-horiz))
(def size-vert (icon-xref :size-vert))
(def stroke (icon-xref :stroke))

View file

@ -1447,21 +1447,37 @@
;; --- Shape / Selection Alignment
(defn initial-selection-align
"Align the selection of shapes."
[ids]
(us/verify ::set-of-uuid ids)
(ptk/reify ::initialize-shapes-align-in-bulk
ptk/WatchEvent
(watch [_ state stream]
#_(let [shapes-by-id (get-in state [:workspace-data :objects])
shapes (mapv #(get shapes-by-id %) ids)
sshape (geom/shapes->rect-shape shapes)
point (gpt/point (:x1 sshape)
(:y1 sshape))]
(->> (uwrk/align-point point)
(rx/map (fn [{:keys [x y] :as pt}]
(apply-displacement-in-bulk ids (gpt/subtract pt point)))))))))
(declare align-object-to-frame)
(declare align-objects-list)
(defn align-objects
[axis]
(us/verify ::geom/axis axis)
(ptk/reify :align-objects
IBatchedChange
ptk/UpdateEvent
(update [_ state]
(let [page-id (::page-id state)
objects (get-in state [:workspace-data page-id :objects])
selected (get-in state [:workspace-local :selected])
moved-objs (if (= 1 (count selected))
[(align-object-to-frame objects (first selected) axis)]
(align-objects-list objects selected axis))
updated-objs (merge objects (d/index-by :id moved-objs))]
(assoc-in state [:workspace-data page-id :objects] updated-objs)))))
(defn align-object-to-frame
[objects object-id axis]
(let [object (get objects object-id)
frame (get objects (:frame-id object))]
(geom/align-to-rect object frame axis)))
(defn align-objects-list
[objects selected axis]
(let [selected-objs (map #(get objects %) selected)
rect (geom/selection-rect selected-objs)]
(map #(geom/align-to-rect % rect axis) selected-objs)))
;; --- Temportal displacement for Shape / Selection

View file

@ -525,12 +525,12 @@
(gmt/matrix? displacement-modifier)
(transform displacement-modifier)))
;; NOTE: we need applu `shape->rect-shape` 3 times because we need to
;; NOTE: we need apply `shape->rect-shape` 3 times because we need to
;; update the x1 x2 y1 y2 attributes on each step; this is because
;; some transform functions still uses that attributes. WE NEED TO
;; REFACTOR this, and remove any usage of the old xN yN attributes.
(def ^:private xf-resolve-shapes
(def ^:private xf-resolve-shape
(comp (map shape->rect-shape)
(map resolve-modifier)
(map shape->rect-shape)
@ -541,7 +541,7 @@
"Returns a rect that contains all the shapes and is aware of the
rotation of each shape. Mainly used for multiple selection."
[shapes]
(let [shapes (into [] xf-resolve-shapes shapes)
(let [shapes (into [] xf-resolve-shape shapes)
minx (transduce (map :x1) min shapes)
miny (transduce (map :y1) min shapes)
maxx (transduce (map :x2) max shapes)
@ -564,6 +564,52 @@
[shape {:keys [x y] :as frame}]
(move shape (gpt/point (+ x) (+ y))))
;; --- Alignment
(s/def ::axis #{:hleft :hcenter :hright :vtop :vcenter :vbottom})
(declare calc-align-pos)
(defn align-to-rect
"Move the shape so that it is aligned with the given rectangle
in the given axis. Take account the form of the shape and the
possible rotation. What is aligned is the rectangle that wraps
the shape with the given rectangle."
[shape rect axis]
(let [wrapper-rect (selection-rect [shape])
align-pos (calc-align-pos wrapper-rect rect axis)
delta {:x (- (:x align-pos) (:x wrapper-rect))
:y (- (:y align-pos) (:y wrapper-rect))}]
(move shape delta)))
(defn calc-align-pos
[wrapper-rect rect axis]
(case axis
:hleft (let [left (:x rect)]
{:x left
:y (:y wrapper-rect)})
:hcenter (let [center (+ (:x rect) (/ (:width rect) 2))]
{:x (- center (/ (:width wrapper-rect) 2))
:y (:y wrapper-rect)})
:hright (let [right (+ (:x rect) (:width rect))]
{:x (- right (:width wrapper-rect))
:y (:y wrapper-rect)})
:vtop (let [top (:y rect)]
{:x (:x wrapper-rect)
:y top})
:vcenter (let [center (+ (:y rect) (/ (:height rect) 2))]
{:x (:x wrapper-rect)
:y (- center (/ (:height wrapper-rect) 2))})
:vbottom (let [bottom (+ (:y rect) (:height rect))]
{:x (:x wrapper-rect)
:y (- bottom (:height wrapper-rect))})))
;; --- Helpers
(defn contained-in?

View file

@ -0,0 +1,50 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) 2015-2016 Andrey Antukh <niwi@niwi.nz>
;; Copyright (c) 2015-2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>
(ns uxbox.main.ui.workspace.sidebar.align
(:require
[rumext.alpha :as mf]
[uxbox.builtins.icons :as i]
[uxbox.main.refs :as refs]
[uxbox.main.store :as st]
[uxbox.main.data.workspace :as dw]
[uxbox.util.uuid :as uuid]))
(mf/defc align-options
[]
(let [selected (mf/deref refs/selected-shapes)
objects (deref refs/objects) ; don't need to watch objects, only read the value
disabled (cond
(empty? selected) true
(> (count selected) 1) false
:else
(= uuid/zero (:frame-id (get objects (first selected)))))
on-align-button-clicked
(fn [axis] (when-not disabled (st/emit! (dw/align-objects axis))))]
[:div.align-options
[:div.align-button {:class (when disabled "disabled")
:on-click #(on-align-button-clicked :hleft)}
i/shape-halign-left]
[:div.align-button {:class (when disabled "disabled")
:on-click #(on-align-button-clicked :hcenter)}
i/shape-halign-center]
[:div.align-button {:class (when disabled "disabled")
:on-click #(on-align-button-clicked :hright)}
i/shape-halign-right]
[:div.align-button {:class (when disabled "disabled")
:on-click #(on-align-button-clicked :vtop)}
i/shape-valign-top]
[:div.align-button {:class (when disabled "disabled")
:on-click #(on-align-button-clicked :vcenter)}
i/shape-valign-center]
[:div.align-button {:class (when disabled "disabled")
:on-click #(on-align-button-clicked :vbottom)}
i/shape-valign-bottom]]))

View file

@ -13,6 +13,7 @@
[uxbox.main.data.workspace :as udw]
[uxbox.main.store :as st]
[uxbox.main.refs :as refs]
[uxbox.main.ui.workspace.sidebar.align :refer [align-options]]
[uxbox.main.ui.workspace.sidebar.options.frame :as frame]
[uxbox.main.ui.workspace.sidebar.options.group :as group]
[uxbox.main.ui.workspace.sidebar.options.rect :as rect]
@ -55,11 +56,12 @@
[{:keys [page selected] :as props}]
(let [close #(st/emit! (udw/toggle-layout-flag :element-options))
selected (mf/deref refs/selected-shapes)]
[:div.elementa-options.tool-window
[:div.element-options.tool-window
;; [:div.tool-window-bar
;; [:div.tool-window-icon i/options]
;; [:span (tr "ds.settings.element-options")]
;; [:div.tool-window-close {:on-click close} i/close]]
[:& align-options]
[:div.tool-window-content
[:div.element-options
(if (= (count selected) 1)

View file

@ -263,16 +263,16 @@
[:div.row-flex.align-icons
[:span {:class (when (= text-align "left") "current")
:on-click #(on-font-align-change % "left")}
i/align-left]
i/text-align-left]
[:span {:class (when (= text-align "center") "current")
:on-click #(on-font-align-change % "center")}
i/align-center]
i/text-align-center]
[:span {:class (when (= text-align "right") "current")
:on-click #(on-font-align-change % "right")}
i/align-right]
i/text-align-right]
[:span {:class (when (= text-align "justify") "current")
:on-click #(on-font-align-change % "justify")}
i/align-justify]]]]))
i/text-align-justify]]]]))
(def +fonts+
[{:id "sourcesanspro"