mirror of
https://github.com/odoo/documentation.git
synced 2026-03-27 14:10:23 +07:00
[IMP] howtos/website_themes: Adapts "Shapes" chapter
closes odoo/documentation#16960
X-original-commit: 5621ff2122
Signed-off-by: Brandon Mercier (bram) <bram@odoo.com>
This commit is contained in:
@@ -2,32 +2,33 @@
|
||||
Shapes
|
||||
======
|
||||
|
||||
Shapes are handy if you want to add personality to your website.
|
||||
Shapes are handy if you want to add personality to your website. In this chapter, you will learn
|
||||
how to add standard and custom background/image shapes.
|
||||
|
||||
In this chapter, you will learn how to add standard and custom background and image shapes.
|
||||
They are SVG files that you can add as a decorative background in your different
|
||||
sections or directly on your images. Each shape has one or several customizable colors, and some of
|
||||
them are animated.
|
||||
|
||||
.. warning::
|
||||
Odoo's default shapes use the `Odoo default colors palette <https://github.com/odoo/odoo/blob/b6628011e86f3c8469dea5452ecbce778ece0755/addons/html_editor/static/src/utils/color.js#L19>`_
|
||||
map as reference. This way, colors will be automatically adapted to a new
|
||||
:ref:`palette <theming/module/variables/colors>` everytime it changes:
|
||||
|
||||
.. code-block:: scss
|
||||
|
||||
default_palette = {
|
||||
'1': '#3AADAA',
|
||||
'2': '#7C6576',
|
||||
'3': '#F6F6F6',
|
||||
'4': '#FFFFFF',
|
||||
'5': '#383E45',
|
||||
}
|
||||
|
||||
.. _website_themes/shapes/bg:
|
||||
|
||||
Background shapes
|
||||
=================
|
||||
|
||||
Background shapes are SVG files that you can add as a decorative background in your different
|
||||
sections. Each shape has one or several customizable colors, and some of them are animated.
|
||||
|
||||
.. warning::
|
||||
Odoo's default shapes use the Odoo default colors palette map as reference. This way, colors
|
||||
will be automatically adapted to a new palette everytime it changes:
|
||||
|
||||
.. code-block:: scss
|
||||
|
||||
default_palette = {
|
||||
'1': '#3AADAA',
|
||||
'2': '#7C6576',
|
||||
'3': '#F6F6F6',
|
||||
'4': '#FFFFFF',
|
||||
'5': '#383E45',
|
||||
}
|
||||
|
||||
.. _website_themes/shapes/bg/standard:
|
||||
|
||||
Standard
|
||||
@@ -35,15 +36,18 @@ Standard
|
||||
|
||||
A large selection of default background shapes is available.
|
||||
|
||||
**Use**
|
||||
.. _website_themes/shapes/bg/standard/usage:
|
||||
|
||||
Usage
|
||||
~~~~~
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<section data-oe-shape-data="{'shape':'html_builder/Zigs/06'}">
|
||||
<div class="o_we_shape o_html_builder_Zigs_06"/>
|
||||
<div class="container">
|
||||
<!-- Content -->
|
||||
</div>
|
||||
<div class="o_we_shape o_html_builder_Zigs_06" />
|
||||
<div class="container">
|
||||
<!-- Content -->
|
||||
</div>
|
||||
</section>
|
||||
|
||||
`data-oe-shape-data` is a JSON object containing information about your shape like the location
|
||||
@@ -55,10 +59,10 @@ this:
|
||||
.. code-block:: xml
|
||||
|
||||
<section data-oe-shape-data="{'shape':'html_builder/Zigs/06','flip':['x','y']}">
|
||||
<div class="o_we_shape o_html_builder_Zigs_06"/>
|
||||
<div class="container">
|
||||
<!-- Content -->
|
||||
</div>
|
||||
<div class="o_we_shape o_html_builder_Zigs_06" />
|
||||
<div class="container">
|
||||
<!-- Content -->
|
||||
</div>
|
||||
</section>
|
||||
|
||||
.. _website_themes/shapes/bg/standard/colors:
|
||||
@@ -81,20 +85,20 @@ First, we can use a shape like this:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="none" width="100%" height="100%">
|
||||
<defs>
|
||||
<svg id="zigs06_top" viewBox="0 0 30 30" preserveAspectRatio="xMinYMin meet" fill="#383E45" width="100%">
|
||||
<path d="M30,7.9C22.5,7.9,22.5,20,15,20S7.5,7.9,0,7.9V0h30V7.9z"/>
|
||||
</svg>
|
||||
<svg id="zigs06_bottom" viewBox="0 0 30 30" preserveAspectRatio="xMinYMax meet" fill="#FFFFFF" width="100%">
|
||||
<path d="M0,22.1C7.5,22.1,7.5,10,15,10s7.5,12.1,15,12.1V30H0V22.1z"/>
|
||||
</svg>
|
||||
</defs>
|
||||
<svg>
|
||||
<use xlink:href="#zigs06_top"/>
|
||||
<use xlink:href="#zigs06_bottom"/>
|
||||
</svg>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="none" width="100%" height="100%">
|
||||
<defs>
|
||||
<svg id="zigs06_top" viewBox="0 0 30 30" preserveAspectRatio="xMinYMin meet" fill="#383E45" width="100%">
|
||||
<path d="M30,7.9C22.5,7.9,22.5,20,15,20S7.5,7.9,0,7.9V0h30V7.9z" />
|
||||
</svg>
|
||||
<svg id="zigs06_bottom" viewBox="0 0 30 30" preserveAspectRatio="xMinYMax meet" fill="#FFFFFF" width="100%">
|
||||
<path d="M0,22.1C7.5,22.1,7.5,10,15,10s7.5,12.1,15,12.1V30H0V22.1z" />
|
||||
</svg>
|
||||
</defs>
|
||||
<svg>
|
||||
<use xlink:href="#zigs06_top" />
|
||||
<use xlink:href="#zigs06_bottom" />
|
||||
</svg>
|
||||
</svg>
|
||||
|
||||
Here, we use `#383E45` and `#FFFFFF` which corresponds to the 5th and 4th colors in the Odoo's
|
||||
default color palette.
|
||||
@@ -154,10 +158,10 @@ keeping the original.
|
||||
.. code-block:: xml
|
||||
|
||||
<section data-oe-shape-data="{'shape':'html_builder/Zigs/06'}">
|
||||
<div class="o_we_shape o_html_builder_Zigs_06 o_second_extra_shape_mapping"/>
|
||||
<div class="container">
|
||||
<!-- Content -->
|
||||
</div>
|
||||
<div class="o_we_shape o_html_builder_Zigs_06 o_second_extra_shape_mapping" />
|
||||
<div class="container">
|
||||
<!-- Content -->
|
||||
</div>
|
||||
</section>
|
||||
|
||||
.. _website_themes/shapes/bg/custom:
|
||||
@@ -173,20 +177,13 @@ Firstly, you need to create an SVG file for your shape.
|
||||
:caption: ``/website_airproof/static/shapes/hexagons/01.svg``
|
||||
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="86" height="100">
|
||||
<polygon points="0 25, 43 0, 86 25, 86 75, 43 100, 0 75" style="fill: #3AADAA;"/>
|
||||
<polygon points="0 25, 43 0, 86 25, 86 75, 43 100, 0 75" style="fill: #3AADAA;" />
|
||||
</svg>
|
||||
|
||||
Make sure to use colors from the default Odoo palette for your shape (as explained :ref:`above <website_themes/shapes/bg>`).
|
||||
.. important::
|
||||
Make sure to use colors from the default Odoo palette for your shape
|
||||
(as explained :ref:`above <website_themes/shapes/bg>`).
|
||||
|
||||
.. code-block:: scss
|
||||
|
||||
default_palette = {
|
||||
'1': '#3AADAA',
|
||||
'2': '#7C6576',
|
||||
'3': '#F6F6F6',
|
||||
'4': '#FFFFFF',
|
||||
'5': '#383E45',
|
||||
}
|
||||
.. _website_themes/shapes/bg/custom/attachment:
|
||||
|
||||
Attachment
|
||||
@@ -198,10 +195,10 @@ Declare your shape file.
|
||||
:caption: ``/website_airproof/data/shapes.xml``
|
||||
|
||||
<record id="shape_hexagon_01" model="ir.attachment">
|
||||
<field name="name">01.svg</field>
|
||||
<field name="datas" type="base64" file="website_airproof/static/shapes/hexagons/01.svg"/>
|
||||
<field name="url">/html_editor/shape/illustration/hexagons/01.svg</field>
|
||||
<field name="public" eval="True"/>
|
||||
<field name="name">01.svg</field>
|
||||
<field name="datas" type="base64" file="website_airproof/static/shapes/hexagons/01.svg" />
|
||||
<field name="url">/html_editor/shape/illustration/hexagons/01.svg</field>
|
||||
<field name="public" eval="True" />
|
||||
</record>
|
||||
|
||||
.. list-table::
|
||||
@@ -274,36 +271,36 @@ Lastly, add your shape to the list of shapes available on the Website Builder by
|
||||
`background_shape_groups_providers` resource.
|
||||
|
||||
.. code-block:: javascript
|
||||
:caption: ``/website_airproof/static/src/builder/airproof_background_shapes.js``
|
||||
:caption: ``/website_airproof/static/src/builder/background_shapes_option_plugin.js``
|
||||
|
||||
import { Plugin } from "@html_editor/plugin";
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
import { registry } from "@web/core/registry";
|
||||
|
||||
export class AirproofBackgroundShapesPlugin extends Plugin {
|
||||
static id = "airproofBackgroundShapes";
|
||||
resources = {
|
||||
background_shape_groups_providers: () => ({
|
||||
airproof: {
|
||||
label: _t("Airproof"),
|
||||
subgroups: {
|
||||
airproof: {
|
||||
label: _t("Airproof"),
|
||||
shapes: {
|
||||
"illustration/airproof/01": {
|
||||
selectLabel: _t("Airproof 01"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
export class AirproofBackgroundShapesOptionPlugin extends Plugin {
|
||||
static id = "airproofBackgroundShapesOption";
|
||||
resources = {
|
||||
background_shape_groups_providers: () => ({
|
||||
airproof: {
|
||||
label: _t("Airproof"),
|
||||
subgroups: {
|
||||
airproof: {
|
||||
label: _t("Airproof"),
|
||||
shapes: {
|
||||
"website_airproof/waves/01": {
|
||||
selectLabel: _t("Airproof 01"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
};
|
||||
},
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
registry.category("website-plugins").add(
|
||||
AirproofBackgroundShapesPlugin.id,
|
||||
AirproofBackgroundShapesPlugin
|
||||
AirproofBackgroundShapesOptionPlugin.id,
|
||||
AirproofBackgroundShapesOptionPlugin
|
||||
);
|
||||
|
||||
.. note::
|
||||
@@ -318,11 +315,484 @@ In your XML pages, you can use your shape in the same way as the others.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<section class="..." data-oe-shape-data="{'shape': 'illustration/airproof/01', 'colors': {'c4': '#8595A2', 'c5': 'rgba(0, 255, 0)'}}">
|
||||
<div class="o_we_shape o_illustration_airproof_01"/>
|
||||
<div class="container">
|
||||
<!-- Content -->
|
||||
</div>
|
||||
</section>
|
||||
<section class="..." data-oe-shape-data="{'shape': 'illustration/airproof/01', 'colors': {'c4': '#8595A2', 'c5': 'rgba(0, 255, 0)'}}">
|
||||
<div class="o_we_shape o_illustration_airproof_01" />
|
||||
<div class="container">
|
||||
<!-- Content -->
|
||||
</div>
|
||||
</section>
|
||||
|
||||
You can also redefine colors using the `data-oe-shape-data attribute`, but this is optional.
|
||||
You can also redefine colors using the `data-oe-shape-data` attribute, but this is optional.
|
||||
|
||||
.. _website_themes/shapes/img:
|
||||
|
||||
Image shapes
|
||||
============
|
||||
|
||||
Image shapes are SVG files you can add as a clipping mask on your images. Some shapes have
|
||||
customizable colors, and some are animated.
|
||||
|
||||
.. _website_themes/shapes/img/standard:
|
||||
|
||||
Standard
|
||||
--------
|
||||
|
||||
A large selection of default image shapes is available.
|
||||
|
||||
.. _website_themes/shapes/img/standard/use:
|
||||
|
||||
Usage
|
||||
~~~~~
|
||||
|
||||
A shape can only be applied on an image that has been previously declared in an `ir.attachment`
|
||||
record as the Website Builder needs to re-process the image. To summarize, the system injects the
|
||||
original image into a SVG file containing both the image and the shape.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<img
|
||||
src="..."
|
||||
class="img img-fluid mx-auto"
|
||||
alt="..."
|
||||
data-shape="html_builder/solid/solid_blob_2"
|
||||
data-shape-colors="#0B8EE6;;;;"
|
||||
data-mimetype="image/svg+xml"
|
||||
data-mimetype-before-conversion="image/jpeg"
|
||||
data-original-src="/website/static/src/img/snippets_demo/s_picture.jpg"
|
||||
data-file-name="s_text_image.svg"
|
||||
data-original-id="590"
|
||||
data-attachment-id="590" />
|
||||
|
||||
Once the shape applied, the `img` includes different data attributes allowing the Website Builder
|
||||
to re-process the image if it is edited again:
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:stub-columns: 1
|
||||
:widths: 20 80
|
||||
|
||||
* - Attribute
|
||||
- Description
|
||||
* - data-shape
|
||||
- Location of the shape
|
||||
* - data-shape-colors
|
||||
- Colors (5 max) applied to the shape (each value, even if empty, are separated by a semicolon)
|
||||
* - data-mimetype
|
||||
- Mimetype of the shaped image
|
||||
* - data-mimetype-before-conversion
|
||||
- Mimetype of the original image
|
||||
* - data-original-src
|
||||
- Path to the original image file
|
||||
* - data-file-name
|
||||
- Name of the file which is created after a shape modification (Always use `.svg` extension as
|
||||
the image shape is applied into an SVG file containing the shape and the original image).
|
||||
* - data-original-id
|
||||
- Identifier of the original `ir.attachment` (related to the uploaded image)
|
||||
* - data-attachment-id
|
||||
- Identifier of the `ir.attachment` related to the shaped image.
|
||||
|
||||
**Call the shape**
|
||||
|
||||
Insert a shaped image requires to call the processed attachment, not just the original image.
|
||||
When a shape is manually applied with the Website Builder:
|
||||
|
||||
#. The original record is processed and the `src` attribute is updated with a `base64` image.
|
||||
#. Once the page is saved, the base64 image is moved into the final SVG (specified in `data-file-name`).
|
||||
#. Finally, the `src` attribute is updated with the following path structure:
|
||||
`/web/image/<attachment_id>-<attachment_checksum>/<finale_image>.svg`
|
||||
|
||||
But here are 2 issues:
|
||||
|
||||
#. Convert the final image into `base64` format is not that easy (as this is not really *human readable*).
|
||||
#. The `checksum` computation of the final `ir.attachment` uses an algorithm.
|
||||
|
||||
In a way or another, an external tool would be required but the `html_editor` module provides a
|
||||
controller with a useful route that can mix an image shape and an image file:
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 3
|
||||
|
||||
@http.route([
|
||||
'/web_editor/image_shape/<string:img_key>/<module>/<path:filename>',
|
||||
'/html_editor/image_shape/<string:img_key>/<module>/<path:filename>'],
|
||||
type='http', auth="public", website=True)
|
||||
|
||||
.. seealso::
|
||||
`HTML Editor - Image shape route <https://github.com/odoo/odoo/blob/3e47cbf5a634a48ee22c223cc2c3c6a151ad350a/addons/html_editor/controllers/main.py#L583>`_
|
||||
|
||||
Focus on `/html_editor` path, which is the "new name" for the old Web Editor used
|
||||
up to Odoo 18, and replace the placeholders with real data:
|
||||
|
||||
.. code-block:: xml
|
||||
:emphasize-lines: 2
|
||||
|
||||
<img
|
||||
src="/html_editor/image_shape/website_airproof.img_drone_robin/html_builder/solid/solid_blob_2.svg"
|
||||
class="img img-fluid mx-auto"
|
||||
alt="..."
|
||||
data-shape="html_builder/solid/solid_blob_2"
|
||||
data-shape-colors="#0B8EE6;;;;"
|
||||
data-mimetype="image/svg+xml"
|
||||
data-mimetype-before-conversion="image/webp"
|
||||
data-original-src="website_airproof/static/src/img/content/drone-robin.webp"
|
||||
data-file-name="drone-robin.svg"
|
||||
data-original-id="560"
|
||||
data-attachment-id="560" />
|
||||
|
||||
.. important::
|
||||
Keep in mind that as long as the image is not saved manually with the Website Builder, it is not
|
||||
stored in the database as a record, **it is generated in real time for each visitor displaying
|
||||
the page**. So it can have an impact on the loading performances of the website.
|
||||
|
||||
.. _website_themes/shapes/img/standard/colors:
|
||||
|
||||
Colors
|
||||
~~~~~~
|
||||
|
||||
The image shapes can include up to 5 colors. As the SVG file contains colors related to the Odoo
|
||||
default colors palette, the system is able to map the colors existing in the file and match the ones
|
||||
called in the `data-shape-colors` attribute of the image.
|
||||
|
||||
.. code-block:: xml
|
||||
:emphasize-lines: 6
|
||||
|
||||
<img
|
||||
src="..."
|
||||
class="img img-fluid mx-auto"
|
||||
alt="..."
|
||||
data-shape="html_builder/solid/solid_blob_2"
|
||||
data-shape-colors="#0B8EE6;;;;"
|
||||
data-mimetype="image/svg+xml"
|
||||
data-mimetype-before-conversion="image/jpeg"
|
||||
data-original-src="/website/static/src/img/snippets_demo/s_picture.jpg"
|
||||
data-file-name="s_text_image.svg"
|
||||
data-original-id="590"
|
||||
data-attachment-id="590" />
|
||||
|
||||
In the example above, the color `#0B8EE6` is applied as the first color of the palette. Considering
|
||||
the first color in the default palette is `#3AADAA`, the Website Builder replaces `#3AADAA` by
|
||||
`#0B8EE6`.
|
||||
|
||||
.. image:: shapes/image-shape-colors-example.jpg
|
||||
:alt: Color edition
|
||||
|
||||
.. _website_themes/shapes/img/standard/transform:
|
||||
|
||||
Transformations & Stretch
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Some shapes can be adjusted with transformations (Flip, rotate):
|
||||
|
||||
.. image:: shapes/img-shape-slanted-transform.png
|
||||
:alt: Transformations and stretch options
|
||||
|
||||
.. code-block:: xml
|
||||
:emphasize-lines: 6-8
|
||||
|
||||
<img
|
||||
src="..."
|
||||
class="img img-fluid mx-auto"
|
||||
alt="..."
|
||||
data-shape="html_builder/geometric/geo_slanted"
|
||||
data-shape-flip="xy"
|
||||
data-shape-rotate="90"
|
||||
data-aspect-ratio="1/1"
|
||||
data-mimetype="image/svg+xml"
|
||||
data-mimetype-before-conversion="image/jpeg"
|
||||
data-original-src="/website/static/src/img/snippets_demo/s_picture.jpg"
|
||||
data-file-name="s_text_image.svg"
|
||||
data-original-id="590"
|
||||
data-attachment-id="590" />
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:stub-columns: 1
|
||||
:widths: 20 80
|
||||
|
||||
* - Attribute
|
||||
- Description
|
||||
* - data-shape-flip
|
||||
- Flips the shape along the x-axis(`x`), y-axis(`y`) or both(`xy`).
|
||||
* - data-shape-rotate
|
||||
- Rotates the shape by 90 degrees (`90`, `180`, `270`).
|
||||
* - data-aspect-ratio
|
||||
- Stretch the shape to the image ratio: `1/1` (by default, the image fills the shape) or `0/0`
|
||||
(:guilabel:`Stretch` option is enabled and the shape fits the image aspect ratio)
|
||||
|
||||
.. _website_themes/shapes/img/standard/animation:
|
||||
|
||||
Animation
|
||||
~~~~~~~~~
|
||||
|
||||
Some shapes are animated and their velocity can be adjusted:
|
||||
|
||||
.. image:: shapes/img-shape-speed.png
|
||||
:alt: Speed option for animated image shapes
|
||||
|
||||
.. code-block:: xml
|
||||
:emphasize-lines: 6
|
||||
|
||||
<img
|
||||
src="..."
|
||||
class="img img-fluid mx-auto"
|
||||
alt="..."
|
||||
data-shape="html_builder/geometric/geo_square_1"
|
||||
data-shape-animation-speed="2"
|
||||
data-mimetype="image/svg+xml"
|
||||
data-mimetype-before-conversion="image/jpeg"
|
||||
data-original-src="/website/static/src/img/snippets_demo/s_picture.jpg"
|
||||
data-file-name="s_text_image.svg"
|
||||
data-original-id="590"
|
||||
data-attachment-id="590" />
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:stub-columns: 1
|
||||
:widths: 20 80
|
||||
|
||||
* - Attribute
|
||||
- Description
|
||||
* - data-shape-animation-speed
|
||||
- Animation velocity (Range from `-2` to `2` with steps of `0.1`)
|
||||
|
||||
.. _website_themes/shapes/img/custom:
|
||||
|
||||
Custom
|
||||
------
|
||||
|
||||
The creation of a custom image shape is quite simple and relies on 2 steps:
|
||||
#. Create an SVG file with a specific structure
|
||||
#. Add the custom shape to the list
|
||||
|
||||
.. _website_themes/shapes/img/custom/svg:
|
||||
|
||||
Create the SVG
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Firstly, create an SVG file for your image shape.
|
||||
|
||||
.. code-block:: xml
|
||||
:caption: ``/website_airproof/static/image_shapes/duo/01.svg``
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="800"
|
||||
height="800">
|
||||
<defs>
|
||||
<!-- Mask -->
|
||||
<clipPath id="clip-path" clipPathUnits="objectBoundingBox">
|
||||
<use xlink:href="#filterPath" fill="none" />
|
||||
</clipPath>
|
||||
<!-- Vector used in the mask definition (Clip-path) -->
|
||||
<path id="filterPath" d="M0.325,0.75H0.125c-0.069,0-0.125-0.056-0.125-0.125V0.125C0,0.056,
|
||||
0.056,0,0.125,0h0.2c0.069,0,0.125,0.056,0.125,0.125v0.5c0,0.069-0.056,0.125-0.125,0.125ZM1,
|
||||
0.875v-0.5c0-0.069-0.056-0.125-0.125-0.125h-0.2c-0.069,0-0.125,0.056-0.125,0.125v0.5c0,
|
||||
0.069,0.056,0.125,0.125,0.125h0.2c0.069,0,0.125-0.056,0.125-0.125Z" />
|
||||
</defs>
|
||||
|
||||
<!-- Other decorative element around (not used as a mask) -->
|
||||
<svg viewBox="0 0 1 1" preserveAspectRatio="none">
|
||||
<rect x="0.494"
|
||||
y="0.325"
|
||||
width="0.0125"
|
||||
height="0.35"
|
||||
rx="0.00625"
|
||||
ry="0.00625"
|
||||
fill="#7C6576" />
|
||||
</svg>
|
||||
|
||||
<!-- Preview of the Path declared in the <defs> -->
|
||||
<svg viewBox="0 0 1 1" id="preview" preserveAspectRatio="none">
|
||||
<use xlink:href="#filterPath" fill="darkgrey" />
|
||||
</svg>
|
||||
|
||||
<!-- Future image that on wich the mask is applied -->
|
||||
<image xlink:href="" clip-path="url(#clip-path)">
|
||||
<!-- Compatibility hack (Safari, Firefox) for non-animated shapes -->
|
||||
<animateMotion dur="1ms" repeatCount="indefinite" />
|
||||
</image>
|
||||
</svg>
|
||||
|
||||
The SVG file can be created in any vector editing software but requires some adaptations to work
|
||||
properly with the Website Builder. Let's break down the example above.
|
||||
|
||||
**Main SVG**
|
||||
|
||||
The Image Shape is wrapped into a single main SVG object with explicit `width` and `height` attributes
|
||||
in pixels:
|
||||
|
||||
.. code-block:: xml
|
||||
:emphasize-lines: 4-5
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="800"
|
||||
height="800">
|
||||
...
|
||||
</svg>
|
||||
|
||||
**Mask**
|
||||
|
||||
The mask is defined into a `<defs>` tag in order to be reusable (even if it's not). It's compound
|
||||
by 2 elements : a `clip-path` and a vector (a `path` in our shape).At this step, what's set into
|
||||
`defs` does not appear.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<defs>
|
||||
<!-- Mask -->
|
||||
<clipPath id="clip-path" clipPathUnits="objectBoundingBox">
|
||||
<use xlink:href="#filterPath" fill="none" />
|
||||
</clipPath>
|
||||
<!-- Vector used in the mask definition (Clip-path) -->
|
||||
<path id="filterPath" d="M0.325,0.75H0.125c-0.069,0-0.125-0.056-0.125-0.125V0.125C0,0.056,
|
||||
0.056,0,0.125,0h0.2c0.069,0,0.125,0.056,0.125,0.125v0.5c0,0.069-0.056,0.125-0.125,0.125ZM1,
|
||||
0.875v-0.5c0-0.069-0.056-0.125-0.125-0.125h-0.2c-0.069,0-0.125,0.056-0.125,0.125v0.5c0,
|
||||
0.069,0.056,0.125,0.125,0.125h0.2c0.069,0,0.125-0.056,0.125-0.125Z" />
|
||||
</defs>
|
||||
|
||||
**Additional decorations**
|
||||
|
||||
If the shape contains any other decorative element, they are set into the main SVG but outside the
|
||||
`defs`
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<svg viewBox="0 0 1 1" preserveAspectRatio="none">
|
||||
<rect
|
||||
x="0.494"
|
||||
y="0.325"
|
||||
width="0.0125"
|
||||
height="0.35"
|
||||
rx="0.00625"
|
||||
ry="0.00625"
|
||||
fill="#7C6576" />
|
||||
</svg>
|
||||
|
||||
.. tip::
|
||||
The main SVG has `width` and `height` attributes expressed in pixels (800 in this example) but
|
||||
the viewBox is always normalized to values between 0 and 1. As the SVG is a scalable format, it
|
||||
ensures the image to be sharp no matter its rendered size.
|
||||
|
||||
This decoration has a `fill` color that can be edited with the Website Builder:
|
||||
|
||||
.. image:: shapes/img-shape-colors.png
|
||||
:alt: Color edition
|
||||
|
||||
.. important::
|
||||
|
||||
Do not forget to use a color coming from the Odoo default colors palette to make it editable by
|
||||
the Website Builder (as explained :ref:`above <website_themes/shapes/bg>`).
|
||||
|
||||
**Preview**
|
||||
|
||||
Then render the mask in a "preview" by using a reference to the `ìd` set before (`filterPath`):
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<svg viewBox="0 0 1 1" id="preview" preserveAspectRatio="none">
|
||||
<use xlink:href="#filterPath" fill="darkgrey" />
|
||||
</svg>
|
||||
|
||||
**Image**
|
||||
|
||||
Finally, add an `image` tag with a `clip-path` reference. It will receive your future image (in
|
||||
`base64` format).
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<image xlink:href="" clip-path="url(#clip-path)">
|
||||
<!-- Compatibility hack (Safari, Firefox) for non-animated shapes -->
|
||||
<animateMotion dur="1ms" repeatCount="indefinite" />
|
||||
</image>
|
||||
|
||||
.. tip::
|
||||
Feel free to `run this tool <{GITHUB_PATH}/addons/html_builder/static/image_shapes/convert-to-percentages.html>`_
|
||||
in your browser to convert your source SVG file into an image shape compatible file.
|
||||
|
||||
.. _website_themes/shapes/img/custom/option:
|
||||
|
||||
Add it to the list
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Finally, add the custom shape to the list:
|
||||
|
||||
.. code-block:: javascript
|
||||
:caption: ``/website_airproof/static/src/website_builder/image_shapes_option_plugin.js``
|
||||
|
||||
import { Plugin } from "@html_editor/plugin";
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
import { registry } from "@web/core/registry";
|
||||
export class AirproofImageShapesOptionPlugin extends Plugin {
|
||||
static id = "airproofImageShapesOption";
|
||||
resources = {
|
||||
image_shape_groups_providers: () => ({
|
||||
airproof: {
|
||||
label: _t("Airproof"),
|
||||
subgroups: {
|
||||
airproof_duo: {
|
||||
label: _t("Duo"),
|
||||
shapes: {
|
||||
"website_airproof/duo/01": {
|
||||
selectLabel: _t("Airproof 01"),
|
||||
transform: true,
|
||||
togglableRatio: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
registry.category("website-plugins").add(
|
||||
AirproofImageShapesOptionPlugin.id,
|
||||
AirproofImageShapesOptionPlugin
|
||||
);
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:stub-columns: 1
|
||||
:widths: 20 80
|
||||
|
||||
* - Property
|
||||
- Description
|
||||
* - selectLabel
|
||||
- Name of the shape displayed in the list
|
||||
* - transform
|
||||
- Show/hide the transformation option (vertical and horizontal mirror, left and right rotation).
|
||||
* - togglableRatio
|
||||
- Show/hide the stretch option.
|
||||
* - animated
|
||||
- Indicates if the shape contains some animations
|
||||
* - imgSize
|
||||
- Set the image ratio used for :guilabel:`Devices` (example: `0.46:1`)
|
||||
|
||||
.. figure:: shapes/img-shape-transform-ratio.png
|
||||
:alt: Transform and Stretch options
|
||||
|
||||
Transform and Stretch options
|
||||
|
||||
.. _website_themes/shapes/img/custom/use:
|
||||
|
||||
Use it into your pages
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Custom image shapes can be now applied on images, for example, in your static pages:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<img
|
||||
src="/html_editor/image_shape/website_airproof.img_drone_robin/website_airproof/duo/01.svg"
|
||||
class="img img-fluid mx-auto"
|
||||
alt="..."
|
||||
data-shape="website_airproof/duo/01"
|
||||
data-shape-colors=";#0B8EE6;;;"
|
||||
data-mimetype="image/svg+xml"
|
||||
data-mimetype-before-conversion="image/webp"
|
||||
data-original-src="website_airproof/static/src/img/content/drone-robin.webp"
|
||||
data-file-name="drone-robin.svg"
|
||||
data-original-id="560"
|
||||
data-attachment-id="560" />
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 7.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
Reference in New Issue
Block a user