Skip to content

Commit 9bd3f1b

Browse files
committed
[ADD] awesome_website: create an image comparison snippet
Problem: There was no snippet to compare images
1 parent f338d5f commit 9bd3f1b

16 files changed

Lines changed: 379 additions & 29 deletions

File tree

awesome_website/__manifest__.py

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,49 @@
11
{
2-
'name': "Awesome Website",
3-
4-
'summary': """
2+
"name": "Awesome Website",
3+
"summary": """
54
Companion addon for the Odoo JS Framework Training
65
""",
7-
8-
'description': """
6+
"description": """
97
Companion addon for the Odoo JS Framework Training
108
""",
11-
12-
'author': "Odoo",
13-
'website': "https://www.odoo.com",
14-
9+
"author": "Odoo",
10+
"website": "https://www.odoo.com",
1511
# Categories can be used to filter modules in modules listing
1612
# Check https://github.com/odoo/odoo/blob/19.0/odoo/addons/base/data/ir_module_category_data.xml
1713
# for the full list
18-
'category': 'Tutorials',
19-
'version': '0.2',
20-
14+
"category": "Tutorials",
15+
"version": "0.2",
2116
# any module necessary for this one to work correctly
22-
'depends': ['website'],
23-
'application': True,
24-
'installable': True,
25-
'data': [
26-
'data/images.xml',
17+
"depends": ["website"],
18+
"application": True,
19+
"installable": True,
20+
"data": [
21+
"data/images.xml",
22+
"views/snippets/s_image_comparison.xml",
23+
"views/snippets/s_timer.xml",
24+
"views/snippets/snippets.xml",
2725
],
28-
'assets': {
26+
"assets": {
27+
"web.assets_frontend": [
28+
"awesome_website/static/src/snippets/**/*.scss",
29+
"awesome_website/static/src/interactions/**/*.js",
30+
"awesome_website/static/src/snippets/s_image_comparison/image_comparison.js",
31+
],
32+
"website.assets_inside_builder_iframe": [
33+
"awesome_website/static/src/snippets/**/*.edit.scss",
34+
],
35+
"html_builder.iframe_add_dialog": [
36+
"awesome_website/static/src/snippets/**/*.preview.scss",
37+
],
38+
"website.website_builder_assets": [
39+
"awesome_website/static/src/website_builder/image_comparison_snippet_option.*",
40+
],
41+
"web.assets_unit_tests": [
42+
"awesome_website/static/tests/**/*",
43+
],
44+
"web.assets_unit_tests_setup": [
45+
"awesome_website/static/src/**/*",
46+
],
2947
},
30-
'license': 'AGPL-3'
48+
"license": "AGPL-3",
3149
}

awesome_website/static/src/interactions/main.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import { registry } from "@web/core/registry";
22
import { Interaction } from "@web/public/interaction";
33

44
class Main extends Interaction {
5-
/* Interaction's lifecycle methods:
5+
static selector = "main";
66

7-
setup() { }
8-
async willStart() { }
9-
start() { }
10-
destroy() { }
7+
dynamicContent = {
8+
_root: {
9+
"t-out": () => (new Date()).toLocaleString(),
10+
},
11+
};
1112

12-
*/
1313
}
1414

15-
registry.category("public.interactions").add("awesome_website.main", Main);
15+
// registry.category("public.interactions").add("awesome_website.main", Main);
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { registry } from "@web/core/registry";
2+
import { Interaction } from "@web/public/interaction";
3+
4+
class CursorFollow extends Interaction {
5+
static selector = "#wrapwrap";
6+
dynamicContent = {
7+
_root: {
8+
"t-on-mousemove": (event) => {
9+
this.x_mouse_follower = event.clientX;
10+
this.y_mouse_follower = event.clientY;
11+
},
12+
},
13+
".x_mouse_follower": {
14+
"t-att-style": () => ({
15+
position: "absolute",
16+
"z-index": "auto",
17+
top: `${this.y_mouse_follower}px`,
18+
left: `${this.x_mouse_follower}px`,
19+
}),
20+
},
21+
};
22+
23+
setup() {
24+
this.x_mouse_follower = 0;
25+
this.y_mouse_follower = 0;
26+
27+
this.cursorEl = document.createElement("span");
28+
this.cursorEl.classList.add("x_mouse_follower");
29+
}
30+
31+
start() {
32+
this.insert(this.cursorEl, this.el);
33+
}
34+
}
35+
36+
// registry
37+
// .category("public.interactions")
38+
// .add("awesome_website.cursor_follow", CursorFollow);
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { Component, xml, useState, onWillStart, onWillDestroy } from "@odoo/owl";
2+
import { registry } from "@web/core/registry";
3+
import { Interaction } from "@web/public/interaction";
4+
5+
class Timer extends Component {
6+
static template = xml`<section class="w-25 mx-auto p-8">
7+
<div class="card">
8+
<div class="card-body">
9+
<t t-out="this.state.time.toLocaleString(this.props.locale)"/>
10+
</div>
11+
</div>
12+
</section>`;
13+
static props = {
14+
locale: {
15+
type: String,
16+
},
17+
};
18+
19+
setup() {
20+
this.state = useState({ time: new Date() });
21+
onWillStart(() => {
22+
this.interval = setInterval(() => (this.state.time = new Date()), 100);
23+
});
24+
onWillDestroy(() => {
25+
if (this.interval) {
26+
clearInterval(this.interval);
27+
}
28+
});
29+
}
30+
}
31+
32+
class OwlInteraction extends Interaction {
33+
static selector = "main";
34+
dynamicContent = {
35+
_root: {
36+
"t-component": () => [Timer, { locale: "fr" }],
37+
},
38+
};
39+
}
40+
41+
registry.category("public_components").add("OwlTimer", Timer);
42+
43+
registry.category("public.interactions").add("OwlTimer", OwlInteraction);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
@property --slider-position {
2+
syntax: "<percentage>";
3+
inherits: true;
4+
initial-value: 50%;
5+
}
6+
7+
@keyframes slide {
8+
0% {
9+
--slider-position: 50%;
10+
}
11+
25% {
12+
--slider-position: 100%;
13+
}
14+
50% {
15+
--slider-position: 50%;
16+
}
17+
75% {
18+
--slider-position: 0%;
19+
}
20+
100% {
21+
--slider-position: 50%;
22+
}
23+
}
24+
25+
.o_snippet_preview_wrap:hover{
26+
.o_image_comparison_container{
27+
animation: 5s linear infinite slide;
28+
}
29+
}

awesome_website/static/src/snippets/s_image_comparison/000.scss

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
1+
.o_image_comparison_s_rounded {
2+
--rounding: 1rem;
3+
}
4+
.o_image_comparison_m_rounded {
5+
--rounding: 2rem;
6+
}
7+
.o_image_comparison_xl_rounded {
8+
--rounding: 4rem;
9+
}
10+
111
.o_image_comparison_container {
212
--slider-position: 50%;
313

414
img {
515
grid-area: 1 / 1;
616
width: 100%;
717
height: 100%;
18+
border-radius: var(--rounding, 1rem);
819

920
&.o_image_after {
1021
clip-path: rect(0 100% 100% var(--slider-position));
@@ -50,3 +61,10 @@
5061
background-color: #fff;
5162
}
5263
}
64+
65+
.o_image_comparison_bw {
66+
img {
67+
filter: grayscale(1);
68+
}
69+
}
70+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { registry } from "@web/core/registry";
2+
import { ImageComparison } from "./image_comparison";
3+
4+
const ImageComparisonEdit = (I) =>
5+
class extends I {
6+
dynamicContent = {
7+
_root: {
8+
"t-att-class": () => ({
9+
"pe-none": true,
10+
}),
11+
},
12+
};
13+
updateSliderPosition() {
14+
return
15+
}
16+
};
17+
18+
registry
19+
.category("public.interactions.edit")
20+
.add("awesome_website.image_comparison", {
21+
Interaction: ImageComparison,
22+
mixin: ImageComparisonEdit,
23+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { registry } from "@web/core/registry";
2+
import { Interaction } from "@web/public/interaction";
3+
4+
export class ImageComparison extends Interaction {
5+
static selector = ".o_image_comparison_container";
6+
7+
dynamicContent = {
8+
".o_image_comparison_slider": {
9+
"t-on-input": this.updateSliderPosition,
10+
},
11+
};
12+
13+
updateSliderPosition(event) {
14+
this.el.style.setProperty("--slider-position", `${event.target.value}%`);
15+
}
16+
}
17+
18+
registry.category("public.interactions").add("awesome_website.image_comparison", ImageComparison);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { registry } from "@web/core/registry";
2+
import { ImageComparison } from "./image_comparison";
3+
4+
const ImageComparisonEdit = (I) =>
5+
class extends I {
6+
updateSliderPosition() {
7+
return
8+
}
9+
};
10+
11+
registry
12+
.category("public.interactions.preview")
13+
.add("awesome_website.image_comparison", {
14+
Interaction: ImageComparison,
15+
mixin: ImageComparisonEdit,
16+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { BaseOptionComponent } from "@html_builder/core/base_option_component";
2+
import { Plugin } from "@html_editor/plugin";
3+
import { registry } from "@web/core/registry";
4+
5+
export class ImageComparisonSnippetOption extends BaseOptionComponent {
6+
static template = "awesome_website.ImageComparisonSnippetOption";
7+
static selector = ".s_image_comparison";
8+
}
9+
10+
export class ImageComparisonSnippetOptionPlugin extends Plugin {
11+
static id = "imageComparisonSnippetOption";
12+
resources = {
13+
builder_options: [ImageComparisonSnippetOption],
14+
};
15+
}
16+
17+
registry
18+
.category("website-plugins")
19+
.add(ImageComparisonSnippetOptionPlugin.id, ImageComparisonSnippetOptionPlugin);

0 commit comments

Comments
 (0)