document.addEventListener('DOMContentLoaded', function() { // Initialize canvas for pattern drawing const canvas = document.getElementById('drawingCanvas'); const ctx = canvas.getContext('2d'); let isDrawing = false; let lastX = 0; let lastY = 0; let drawingHistory = []; let currentStep = -1; // Set canvas dimensions function resizeCanvas() { const rect = canvas.getBoundingClientRect(); canvas.width = rect.width; canvas.height = rect.height; redrawCanvas(); } // Redraw canvas from history function redrawCanvas() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.strokeStyle = '#4f46e5'; ctx.lineWidth = 2; ctx.lineJoin = 'round'; ctx.lineCap = 'round'; for(let i = 0; i <= currentStep; i++) { const path = drawingHistory[i]; if(path.length > 0) { ctx.beginPath(); ctx.moveTo(path[0].x, path[0].y); for(let j = 1; j < path.length; j++) { ctx.lineTo(path[j].x, path[j].y); } ctx.stroke(); } } } // Canvas event listeners canvas.addEventListener('mousedown', startDrawing); canvas.addEventListener('touchstart', handleTouchStart); canvas.addEventListener('mousemove', draw); canvas.addEventListener('touchmove', handleTouchMove); canvas.addEventListener('mouseup', stopDrawing); canvas.addEventListener('mouseout', stopDrawing); canvas.addEventListener('touchend', stopDrawing); function startDrawing(e) { isDrawing = true; const pos = getPosition(e); lastX = pos.x; lastY = pos.y; // Start a new path in history currentStep++; drawingHistory = drawingHistory.slice(0, currentStep); drawingHistory.push([]); drawingHistory[currentStep].push({x: lastX, y: lastY}); } function draw(e) { if(!isDrawing) return; const pos = getPosition(e); ctx.beginPath(); ctx.moveTo(lastX, lastY); ctx.lineTo(pos.x, pos.y); ctx.stroke(); lastX = pos.x; lastY = pos.y; drawingHistory[currentStep].push({x: lastX, y: lastY}); } function stopDrawing() { isDrawing = false; } function handleTouchStart(e) { e.preventDefault(); const touch = e.touches[0]; const mouseEvent = new MouseEvent('mousedown', { clientX: touch.clientX, clientY: touch.clientY }); canvas.dispatchEvent(mouseEvent); } function handleTouchMove(e) { e.preventDefault(); const touch = e.touches[0]; const mouseEvent = new MouseEvent('mousemove', { clientX: touch.clientX, clientY: touch.clientY }); canvas.dispatchEvent(mouseEvent); } function getPosition(e) { const rect = canvas.getBoundingClientRect(); return { x: (e.clientX || e.touches[0].clientX) - rect.left, y: (e.clientY || e.touches[0].clientY) - rect.top }; } // Clear and Undo buttons document.getElementById('clearCanvas').addEventListener('click', function() { ctx.clearRect(0, 0, canvas.width, canvas.height); drawingHistory = []; currentStep = -1; }); document.getElementById('undoCanvas').addEventListener('click', function() { if(currentStep >= 0) { currentStep--; redrawCanvas(); } }); // File upload handling document.getElementById('patternUpload').addEventListener('change', function(e) { const file = e.target.files[0]; if(file) { document.getElementById('fileName').textContent = file.name; const reader = new FileReader(); reader.onload = function(event) { const img = new Image(); img.onload = function() { // Clear canvas and draw the image ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(img, 0, 0, canvas.width, canvas.height); // Reset drawing history drawingHistory = []; currentStep = -1; }; img.src = event.target.result; }; reader.readAsDataURL(file); } }); // Platform selection const platformButtons = document.querySelectorAll('.platform-btn'); platformButtons.forEach(button => { button.addEventListener('click', function() { platformButtons.forEach(btn => btn.classList.remove('active')); this.classList.add('active'); }); }); // Range sliders const matchStrength = document.getElementById('matchStrength'); const matchValue = document.getElementById('matchValue'); const lookbackPeriod = document.getElementById('lookbackPeriod'); const lookbackValue = document.getElementById('lookbackValue'); matchStrength.addEventListener('input', function() { matchValue.textContent = `${this.value}% match`; }); lookbackPeriod.addEventListener('input', function() { lookbackValue.textContent = `${this.value} candles`; }); // Save pattern document.getElementById('savePattern').addEventListener('click', function() { const patternName = document.getElementById('patternName').value.trim(); const patternType = document.getElementById('patternType').value; if(!patternName) { alert('Please enter a pattern name'); return; } if(drawingHistory.length === 0) { alert('Please draw or upload a pattern first'); return; } // In a real app, you would save this to a database // For demo, we'll just add it to the pattern selector const option = document.createElement('option'); option.value = patternName.toLowerCase().replace(/\s+/g, '-'); option.textContent = `${patternName} (${patternType})`; document.getElementById('selectedPattern').appendChild(option); // Show success message alert(`Pattern "${patternName}" saved successfully!`); }); // Start scan document.getElementById('startScan').addEventListener('click', function() { const selectedPattern = document.getElementById('selectedPattern').value; const instrument = document.getElementById('marketInstrument').value.trim(); const timeframe = document.getElementById('timeframe').value; const timeFilter = document.getElementById('timeFilter').value; if(selectedPattern === 'Select a saved pattern...') { alert('Please select a pattern to scan for'); return; } if(!instrument) { alert('Please enter a market instrument'); return; } // Show loading state const resultsContainer = document.getElementById('resultsContainer'); resultsContainer.innerHTML = `

Scanning market for patterns...

`; // Show results section document.getElementById('resultsSection').classList.remove('hidden'); // Simulate API call with timeout setTimeout(() => { // Mock results with timestamps that respect the time filter const now = new Date(); const mockResults = []; // Generate results based on time filter if (timeFilter === '0' || timeFilter === '24') { mockResults.push({ match: 92, date: new Date(now.getTime() - 6 * 60 * 60 * 1000).toISOString().replace('T', ' ').substring(0, 16), timeframe: '1h', instrument: instrument, preview: 'http://static.photos/finance/320x240/1' }); } if (timeFilter === '0' || timeFilter === '8' || timeFilter === '24') { mockResults.push({ match: 87, date: new Date(now.getTime() - 3 * 60 * 60 * 1000).toISOString().replace('T', ' ').substring(0, 16), timeframe: '4h', instrument: instrument, preview: 'http://static.photos/finance/320x240/2' }); } if (timeFilter === '0') { mockResults.push({ match: 85, date: new Date(now.getTime() - 48 * 60 * 60 * 1000).toISOString().replace('T', ' ').substring(0, 16), timeframe: timeframe, instrument: instrument, preview: 'http://static.photos/finance/320x240/3' }); } // Add recent results if time filter is short if (timeFilter !== '0') { const hoursAgo = parseFloat(timeFilter); const maxAge = hoursAgo * 60 * 60 * 1000; // Add some recent results for (let i = 1; i <= 3; i++) { const minutesAgo = Math.floor(Math.random() * hoursAgo * 60); if (minutesAgo * 60 * 1000 <= maxAge) { mockResults.push({ match: 80 + Math.floor(Math.random() * 15), date: new Date(now.getTime() - minutesAgo * 60 * 1000).toISOString().replace('T', ' ').substring(0, 16), timeframe: ['5m','15m','30m','1h'][Math.floor(Math.random() * 4)], instrument: instrument, preview: `http://static.photos/finance/320x240/${3+i}` }); } } } // Display results displayResults(mockResults); }, 2000); }); // Display scan results function displayResults(results) { const resultsContainer = document.getElementById('resultsContainer'); if(results.length === 0) { resultsContainer.innerHTML = `

No matching patterns found

`; feather.replace(); return; } resultsContainer.innerHTML = results.map(result => `
Pattern preview

${result.instrument} (${result.timeframe})

${result.date}

${result.match}% Match
`).join(''); feather.replace(); // Add event listeners to view chart buttons document.querySelectorAll('.view-chart-btn').forEach(button => { button.addEventListener('click', () => { const detail = { instrument: button.dataset.instrument, timeframe: button.dataset.timeframe, match: button.dataset.match }; const event = new CustomEvent('viewChart', { detail }); document.dispatchEvent(event); }); }); } // Initialize resizeCanvas(); window.addEventListener('resize', resizeCanvas); });