Skip to content

Commit 358172e

Browse files
committed
Add Islamic tile pattern implementation in tile1.html
- Introduced a new HTML file, tile1.html, featuring a dynamic canvas-based Islamic tile pattern. - Implemented JavaScript functions to draw colored triangles, hexagons, and six-pointed stars, creating a visually appealing design. - Added responsive canvas resizing to ensure the pattern adapts to different screen sizes.
1 parent 35830a7 commit 358172e

File tree

1 file changed

+247
-0
lines changed

1 file changed

+247
-0
lines changed

tile1.html

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Islamic Tile Pattern</title>
7+
<style>
8+
body {
9+
margin: 0;
10+
padding: 0;
11+
overflow: hidden;
12+
background: #f5e6d3;
13+
}
14+
canvas {
15+
display: block;
16+
}
17+
</style>
18+
</head>
19+
<body>
20+
<canvas id="canvas"></canvas>
21+
<script>
22+
const canvas = document.getElementById('canvas');
23+
const ctx = canvas.getContext('2d');
24+
25+
canvas.width = window.innerWidth;
26+
canvas.height = window.innerHeight;
27+
28+
const COLORS = {
29+
cream: '#f5e6d3',
30+
darkBlue: '#4a6b8a',
31+
lightBlue: '#6a88a8',
32+
darkGreen: '#3d5f52',
33+
lightGreen: '#5a7a6a',
34+
brown: '#9b7f57',
35+
darkBrown: '#6b5738',
36+
black: '#2a2a2a',
37+
gold: '#c8a870'
38+
};
39+
40+
const TRIANGLE_COLORS = [
41+
COLORS.darkBlue, COLORS.lightBlue, COLORS.darkGreen,
42+
COLORS.lightGreen, COLORS.brown, COLORS.darkBrown, COLORS.black
43+
];
44+
45+
const STAR_COLORS = [
46+
COLORS.darkBlue, COLORS.lightBlue, COLORS.darkGreen,
47+
COLORS.lightGreen, COLORS.brown, COLORS.gold, COLORS.black
48+
];
49+
50+
const TRIANGLE_SIDE_LENGTH = 120;
51+
const TRIANGLE_HEIGHT = TRIANGLE_SIDE_LENGTH * Math.sqrt(3) / 2;
52+
const HALF_SIDE_LENGTH = TRIANGLE_SIDE_LENGTH / 2;
53+
const SEMICIRCLE_AMPLITUDE_FACTOR = 0.7;
54+
const SEMICIRCLE_SEGMENTS = 50;
55+
const STAR_ROTATION_OFFSET = Math.PI / 6;
56+
57+
const INRADIUS = TRIANGLE_SIDE_LENGTH / (2 * Math.sqrt(3));
58+
const HEXAGON_RADIUS = INRADIUS * 0.6;
59+
const STAR_OUTER_RADIUS = INRADIUS * 0.66;
60+
const STAR_INNER_RADIUS = STAR_OUTER_RADIUS * 0.5;
61+
62+
const SEMICIRCLE_DIAMETER = TRIANGLE_SIDE_LENGTH / 2;
63+
const SEMICIRCLE_RADIUS = SEMICIRCLE_DIAMETER / 2;
64+
65+
const TRIANGLE_COLOR_COUNT = TRIANGLE_COLORS.length;
66+
const STAR_COLOR_COUNT = STAR_COLORS.length;
67+
68+
const precomputedStarAngles = [];
69+
const precomputedStarRadii = [];
70+
for (let i = 0; i < 12; i++) {
71+
precomputedStarAngles[i] = (Math.PI / 6) * i - Math.PI / 2 + STAR_ROTATION_OFFSET;
72+
precomputedStarRadii[i] = i % 2 === 0 ? STAR_OUTER_RADIUS : STAR_INNER_RADIUS;
73+
}
74+
75+
const precomputedHexagonAngles = [];
76+
for (let i = 0; i < 6; i++) {
77+
precomputedHexagonAngles[i] = (Math.PI / 3) * i;
78+
}
79+
80+
const precomputedSemicircleProgress = new Float32Array(SEMICIRCLE_SEGMENTS);
81+
for (let i = 0; i < SEMICIRCLE_SEGMENTS; i++) {
82+
precomputedSemicircleProgress[i] = (i + 1) / SEMICIRCLE_SEGMENTS;
83+
}
84+
85+
function getDiagonalColorIndex(diagonal, totalColors) {
86+
return ((diagonal % totalColors) + totalColors) % totalColors;
87+
}
88+
89+
function drawSixPointedStar(centerX, centerY, color) {
90+
ctx.fillStyle = color;
91+
ctx.beginPath();
92+
93+
let x = centerX + Math.cos(precomputedStarAngles[0]) * precomputedStarRadii[0];
94+
let y = centerY + Math.sin(precomputedStarAngles[0]) * precomputedStarRadii[0];
95+
ctx.moveTo(x, y);
96+
97+
for (let i = 1; i < 12; i++) {
98+
x = centerX + Math.cos(precomputedStarAngles[i]) * precomputedStarRadii[i];
99+
y = centerY + Math.sin(precomputedStarAngles[i]) * precomputedStarRadii[i];
100+
ctx.lineTo(x, y);
101+
}
102+
103+
ctx.closePath();
104+
ctx.fill();
105+
}
106+
107+
function drawRegularHexagon(centerX, centerY, color) {
108+
ctx.fillStyle = color;
109+
ctx.beginPath();
110+
111+
let x = centerX + Math.cos(precomputedHexagonAngles[0]) * HEXAGON_RADIUS;
112+
let y = centerY + Math.sin(precomputedHexagonAngles[0]) * HEXAGON_RADIUS;
113+
ctx.moveTo(x, y);
114+
115+
for (let i = 1; i < 6; i++) {
116+
x = centerX + Math.cos(precomputedHexagonAngles[i]) * HEXAGON_RADIUS;
117+
y = centerY + Math.sin(precomputedHexagonAngles[i]) * HEXAGON_RADIUS;
118+
ctx.lineTo(x, y);
119+
}
120+
121+
ctx.closePath();
122+
ctx.fill();
123+
}
124+
125+
function drawSemiCircularWaveSide(x1, y1, x2, y2) {
126+
const dx = x2 - x1;
127+
const dy = y2 - y1;
128+
const invLength = 1 / Math.sqrt(dx * dx + dy * dy);
129+
130+
const unitX = dx * invLength;
131+
const unitY = dy * invLength;
132+
const perpX = -unitY;
133+
const perpY = unitX;
134+
135+
const midX = (x1 + x2) * 0.5;
136+
const midY = (y1 + y2) * 0.5;
137+
138+
const halfDx = (midX - x1);
139+
const halfDy = (midY - y1);
140+
141+
for (let i = 0; i < SEMICIRCLE_SEGMENTS; i++) {
142+
const t = precomputedSemicircleProgress[i];
143+
144+
let pointX, pointY, height;
145+
146+
if (t <= 0.5) {
147+
const s = t * 2;
148+
const alongX = x1 + halfDx * s;
149+
const alongY = y1 + halfDy * s;
150+
const distFromCenter = (s - 0.5) * SEMICIRCLE_DIAMETER;
151+
height = Math.sqrt(SEMICIRCLE_RADIUS * SEMICIRCLE_RADIUS - distFromCenter * distFromCenter) * SEMICIRCLE_AMPLITUDE_FACTOR;
152+
153+
pointX = alongX + perpX * height;
154+
pointY = alongY + perpY * height;
155+
} else {
156+
const s = (t - 0.5) * 2;
157+
const alongX = midX + halfDx * s;
158+
const alongY = midY + halfDy * s;
159+
const distFromCenter = (s - 0.5) * SEMICIRCLE_DIAMETER;
160+
height = Math.sqrt(SEMICIRCLE_RADIUS * SEMICIRCLE_RADIUS - distFromCenter * distFromCenter) * SEMICIRCLE_AMPLITUDE_FACTOR;
161+
162+
pointX = alongX - perpX * height;
163+
pointY = alongY - perpY * height;
164+
}
165+
166+
ctx.lineTo(pointX, pointY);
167+
}
168+
}
169+
170+
function drawTriangleWithCurvedSides(x1, y1, x2, y2, x3, y3, color) {
171+
ctx.beginPath();
172+
ctx.moveTo(x1, y1);
173+
drawSemiCircularWaveSide(x1, y1, x2, y2);
174+
drawSemiCircularWaveSide(x2, y2, x3, y3);
175+
drawSemiCircularWaveSide(x3, y3, x1, y1);
176+
ctx.closePath();
177+
ctx.fillStyle = color;
178+
ctx.fill();
179+
}
180+
181+
function drawColoredTriangleWithHexagon(baseX, baseY, diagonal) {
182+
const x1 = baseX;
183+
const y1 = baseY;
184+
const x2 = baseX + TRIANGLE_SIDE_LENGTH;
185+
const y2 = baseY;
186+
const x3 = baseX + HALF_SIDE_LENGTH;
187+
const y3 = baseY + TRIANGLE_HEIGHT;
188+
189+
const colorIndex = getDiagonalColorIndex(diagonal, TRIANGLE_COLOR_COUNT);
190+
drawTriangleWithCurvedSides(x1, y1, x2, y2, x3, y3, TRIANGLE_COLORS[colorIndex]);
191+
192+
const centroidX = (x1 + x2 + x3) / 3;
193+
const centroidY = (y1 + y2 + y3) / 3;
194+
195+
drawRegularHexagon(centroidX, centroidY, COLORS.cream);
196+
}
197+
198+
function drawWhiteTriangleWithStar(baseX, baseY, diagonal) {
199+
const x1 = baseX + HALF_SIDE_LENGTH;
200+
const y1 = baseY;
201+
const x2 = baseX;
202+
const y2 = baseY + TRIANGLE_HEIGHT;
203+
const x3 = baseX + TRIANGLE_SIDE_LENGTH;
204+
const y3 = baseY + TRIANGLE_HEIGHT;
205+
206+
drawTriangleWithCurvedSides(x1, y1, x2, y2, x3, y3, COLORS.cream);
207+
208+
const centroidX = (x1 + x2 + x3) / 3;
209+
const centroidY = (y1 + y2 + y3) / 3;
210+
211+
const starColorIndex = getDiagonalColorIndex(diagonal + 1, STAR_COLOR_COUNT);
212+
drawSixPointedStar(centroidX, centroidY, STAR_COLORS[starColorIndex]);
213+
}
214+
215+
function drawCompletePattern() {
216+
ctx.fillStyle = COLORS.cream;
217+
ctx.fillRect(0, 0, canvas.width, canvas.height);
218+
219+
const columnCount = Math.ceil(canvas.width / TRIANGLE_SIDE_LENGTH) + 2;
220+
const rowCount = Math.ceil(canvas.height / TRIANGLE_HEIGHT) + 2;
221+
222+
for (let row = -1; row < rowCount; row++) {
223+
const horizontalOffset = (row & 1) * HALF_SIDE_LENGTH;
224+
const yPosition = row * TRIANGLE_HEIGHT;
225+
const diagonal = row;
226+
227+
for (let col = -1; col < columnCount; col++) {
228+
const coloredTriangleX = col * TRIANGLE_SIDE_LENGTH + horizontalOffset;
229+
drawColoredTriangleWithHexagon(coloredTriangleX, yPosition, diagonal - col);
230+
231+
const whiteTriangleX = coloredTriangleX + HALF_SIDE_LENGTH;
232+
drawWhiteTriangleWithStar(whiteTriangleX, yPosition, diagonal - col);
233+
}
234+
}
235+
}
236+
237+
function handleResize() {
238+
canvas.width = window.innerWidth;
239+
canvas.height = window.innerHeight;
240+
drawCompletePattern();
241+
}
242+
243+
drawCompletePattern();
244+
window.addEventListener('resize', handleResize);
245+
</script>
246+
</body>
247+
</html>

0 commit comments

Comments
 (0)