Skip to content

Commit 649c443

Browse files
committed
[css-paint-api] Add chat images as example.
1 parent bb7841e commit 649c443

File tree

2 files changed

+150
-0
lines changed

2 files changed

+150
-0
lines changed

css-paint-api/chat/chat.js

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
registerPaint('chat', class {
2+
static get inputProperties() { return ['background-image', '--chat-images-num']; }
3+
4+
constructor() {
5+
this.radii = [
6+
0.5,
7+
1 / (2 + 2/Math.SQRT2),
8+
0.25,
9+
0.25,
10+
1 / Math.SQRT2 - 0.5,
11+
];
12+
13+
const fudge = 0.03349;
14+
this.positions = [
15+
[
16+
{x: 0.5, y: 0.5},
17+
],
18+
[
19+
{x: this.radii[1], y: this.radii[1]},
20+
{x: 1-this.radii[1], y: 1-this.radii[1]},
21+
],
22+
[
23+
{x: 0.5, y: 0.25 + fudge},
24+
{x: 0.75, y: 0.75 - fudge},
25+
{x: 0.25, y: 0.75 - fudge},
26+
],
27+
[
28+
{x: 0.25, y: 0.25},
29+
{x: 0.75, y: 0.25},
30+
{x: 0.25, y: 0.75},
31+
{x: 0.75, y: 0.75},
32+
],
33+
[
34+
{x: this.radii[4], y: this.radii[4]},
35+
{x: 1-this.radii[4], y: this.radii[4]},
36+
{x: 0.5, y: 0.5},
37+
{x: 1-this.radii[4], y: 1-this.radii[4]},
38+
{x: this.radii[4], y: 1-this.radii[4]},
39+
],
40+
];
41+
42+
this.colors = [
43+
'#E91E63',
44+
'#9C27B0',
45+
'#2196F3',
46+
'#8BC34A',
47+
'#FF9800',
48+
];
49+
}
50+
51+
paint(ctx, geom, styleMap) {
52+
ctx.fillStyle = '#FFF';
53+
ctx.fillRect(0, 0, geom.width, geom.height);
54+
55+
// Chrome can only use background-images as source images at the moment.
56+
const images = styleMap.getAll('background-image');
57+
58+
const num = styleMap.get('--chat-images-num').value;
59+
const num_low = Math.floor(num);
60+
const num_high = Math.ceil(num);
61+
62+
const dist = (num - num_low);
63+
const size = Math.min(geom.width, geom.height);
64+
65+
const r_low = this.radii[num_low-1];
66+
const r_high = this.radii[num_high-1];
67+
68+
const pos_low = this.positions[num_low-1];
69+
const pos_high = this.positions[num_high-1];
70+
71+
for (let i = 0; i < num_high; i++) {
72+
if (!pos_high) break;
73+
const low = pos_low && pos_low[i];
74+
const high = pos_high[i];
75+
76+
let x, y, r;
77+
if (num_low != num_high && i == num_high - 1) {
78+
x = size * high.x;
79+
y = size * high.y;
80+
r = size * dist * r_high;
81+
} else {
82+
x = size * ((1-dist) * low.x + dist * high.x);
83+
y = size * ((1-dist) * low.y + dist * high.y);
84+
r = size * ((1-dist) * r_low + dist * r_high);
85+
}
86+
87+
ctx.fillStyle = this.colors[i];
88+
ctx.beginPath();
89+
ctx.arc(x, y, 0.95 * r, 0, Math.PI*2);
90+
ctx.fill();
91+
92+
ctx.save();
93+
ctx.beginPath();
94+
ctx.arc(x, y, 0.9 * r, 0, Math.PI * 2);
95+
ctx.clip();
96+
ctx.drawImage(images[i], x - r, y - r, 2*r, 2*r);
97+
ctx.restore();
98+
}
99+
}
100+
});

css-paint-api/chat/index.html

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<!DOCTYPE html>
2+
<style>
3+
#example {
4+
background-image:
5+
url('http://lorempixel.com/200/200/cats/1/'),
6+
url('http://lorempixel.com/200/200/cats/3/'),
7+
url('http://lorempixel.com/200/200/food/1/'),
8+
url('http://lorempixel.com/200/200/food/2/'),
9+
url('http://lorempixel.com/200/200/food/10/');
10+
11+
border: solid 0;
12+
border-image: paint(chat);
13+
border-image-slice: 0 fill;
14+
15+
width: 120px;
16+
height: 120px;
17+
18+
--chat-images-num: 1;
19+
transition: --chat-images-num 0.25s ease-in-out;
20+
}
21+
</style>
22+
23+
<div id="example"></div>
24+
<button id="add">Add</button>
25+
<button id="remove">Remove</button>
26+
27+
<script>
28+
CSS.registerProperty({
29+
name: '--chat-images-num',
30+
syntax: '<number>',
31+
inherits: false,
32+
initialValue: '0',
33+
});
34+
35+
(async function() {
36+
await (CSS.paintWorklet || paintWorklet).import('chat.js');
37+
38+
const elem = document.getElementById('example');
39+
const add = document.getElementById('add');
40+
const remove = document.getElementById('remove');
41+
42+
let num = 1;
43+
add.addEventListener('click', () => {
44+
elem.style = `--chat-images-num: ${++num}`;
45+
});
46+
remove.addEventListener('click', () => {
47+
elem.style = `--chat-images-num: ${--num}`;
48+
});
49+
})();
50+
</script>

0 commit comments

Comments
 (0)