PageSourceSearch

https://fangg.netlify.app/js/apps/practice.js

js fangg.netlify.app collected 2026-10-03 10:43:31 UTC 9,624 bytes, 200 lines download raw bytes

1let practiceCurrentImageIndex = 0;
2let practiceImages = [];
3
4// 加载图片列表
5function loadPracticeImages() {
6    // 直接定义图片列表
7    practiceImages = [
8        { name: 'Day 47 设计', url: 'assets/images/practice/designday47design.jpg' },
9        { name: 'Day 43 挑战 4', url: 'assets/images/practice/designDay43 Design Challenge-4design.jpg' },
10        { name: 'Day 43 挑战 3', url: 'assets/images/practice/designDay43 Design Challenge-3design.jpg' },
11        { name: 'Day 43 挑战 2', url: 'assets/images/practice/designDay43 Design Challenge-2design.jpg' },
12        { name: 'Day 43 挑战 1', url: 'assets/images/practice/designDay43 Design Challenge-1design.jpg' },
13        { name: 'Day 43 挑战', url: 'assets/images/practice/designDay43 Design Challengedesign.jpg' },
14        { name: 'Frame 1171274933', url: 'assets/images/practice/designFrame 1171274933design.jpg' },
15        { name: 'Day 41 设计', url: 'assets/images/practice/designday41design.jpg' },
16        { name: 'Frame 1171274930', url: 'assets/images/practice/designFrame 1171274930design.jpg' },
17        { name: 'Frame 1171274929', url: 'assets/images/practice/designFrame 1171274929design.jpg' },
18        { name: 'Frame 1171274928', url: 'assets/images/practice/designFrame 1171274928design.jpg' },
19        { name: 'Frame 11', url: 'assets/images/practice/designFrame 11design.jpg' },
20        { name: 'Frame 1171274926', url: 'assets/images/practice/designFrame 1171274926design.jpg' },
21        { name: 'Frame 1171274925', url: 'assets/images/practice/designFrame 1171274925design.jpg' },
22        { name: 'Frame 1171274924', url: 'assets/images/practice/designFrame 1171274924design.jpg' },
23        { name: 'Frame 1171274923', url: 'assets/images/practice/designFrame 1171274923design.jpg' },
24        { name: 'Frame 1171274920', url: 'assets/images/practice/designFrame 1171274920design.jpg' },
25        { name: 'Frame 1171274919', url: 'assets/images/practice/designFrame 1171274919design.jpg' },
26        { name: 'Frame 1171274918', url: 'assets/images/practice/designFrame 1171274918design.jpg' },
27        { name: 'Frame 1171274917', url: 'assets/images/practice/designFrame 1171274917design.jpg' },
28        { name: 'Frame 1171274916', url: 'assets/images/practice/designFrame 1171274916design.jpg' },
29        { name: 'Frame 1171274915', url: 'assets/images/practice/designFrame 1171274915design.jpg' },
30        { name: 'Frame 1171274914', url: 'assets/images/practice/designFrame 1171274914design.jpg' },
31        { name: 'Frame 1171274913', url: 'assets/images/practice/designFrame 1171274913design.jpg' },
32        { name: 'Frame 1171274912', url: 'assets/images/practice/designFrame 1171274912design.jpg' },
33        { name: 'Frame 1171274911', url: 'assets/images/practice/designFrame 1171274911design.jpg' },
34        { name: 'Frame 1171274910', url: 'assets/images/practice/designFrame 1171274910design.jpg' },
35        { name: 'Frame 1171274860', url: 'assets/images/practice/designFrame 1171274860design.jpg' },
36        { name: 'Frame 1171274858', url: 'assets/images/practice/designFrame 1171274858design.jpg' },
37        { name: 'Frame 1171274857', url: 'assets/images/practice/designFrame 1171274857design.jpg' },
38        { name: 'Frame 1171274856', url: 'assets/images/practice/designFrame 1171274856design.jpg' },
39        { name: 'Frame 1171274855', url: 'assets/images/practice/designFrame 1171274855design.jpg' },
40        { name: 'Frame 1171274854', url: 'assets/images/practice/designFrame 1171274854design.jpg' },
41        { name: 'Frame 1171274859', url: 'assets/images/practice/designFrame 1171274859design.jpg' },
42        { name: 'Frame 1171274853', url: 'assets/images/practice/designFrame 1171274853design.jpg' },
43        { name: 'Frame 1171274852', url: 'assets/images/practice/designFrame 1171274852design.jpg' },
44        { name: 'Frame 1171274850', url: 'assets/images/practice/designFrame 1171274850design.jpg' },
45        { name: 'Frame 1171274848', url: 'assets/images/practice/designFrame 1171274848design.jpg' },
46        { name: 'Frame 1171274847', url: 'assets/images/practice/designFrame 1171274847design.jpg' },
47        { name: 'Frame 86', url: 'assets/images/practice/designFrame 86design.jpg' },
48        { name: 'Frame 85', url: 'assets/images/practice/designFrame 85design.jpg' },
49        { name: 'Frame 84', url: 'assets/images/practice/designFrame84design.jpg' },
50        { name: 'Frame 81', url: 'assets/images/practice/designFrame 81design.jpg' },
51        { name: 'Frame 79', url: 'assets/images/practice/designFrame 79design.jpg' },
52        { name: 'Frame 14', url: 'assets/images/practice/designFrame 14design.jpg' },
53        { name: 'Frame 13', url: 'assets/images/practice/designFrame 13design.jpg' },
54        { name: 'Frame 9', url: 'assets/images/practice/designFrame 9design.jpg' },
55        { name: 'Frame 8', url: 'assets/images/practice/designFrame 8design.jpg' },
56    ];
57    displayPracticeImages();
58}
59
60// 显示图片网格
61function displayPracticeImages() {
62    const container = document.querySelector('#practice-window .practice-container');
63    if (!container) return;
64
65    const imageGrid = document.createElement('div');
66    imageGrid.className = 'practice-grid';
67
68    practiceImages.forEach((image, index) => {
69        const imageItem = document.createElement('div');
70        imageItem.className = 'practice-item';
71        imageItem.innerHTML = `
72            <img src="${image.url}" alt="${image.name}" loading="lazy" draggable="false">
73        `;
74        
75        let isDragging = false;
76        let startX, startY;
77        let clickTimer = null;
78        
79        // 阻止默认拖拽行为
80        imageItem.addEventListener('dragstart', (e) => {
81            e.preventDefault();
82        });
83        
84        imageItem.addEventListener('mousedown', (e) => {
85            isDragging = false;
86            startX = e.pageX;
87            startY = e.pageY;
88            
89            // 添加全局鼠标移动监听
90            document.addEventListener('mousemove', handleMouseMove);
91            document.addEventListener('mouseup', handleMouseUp, { once: true });
92        });
93        
94        const handleMouseMove = (e) => {
95            if (e.buttons === 1) {
96                const moveX = Math.abs(e.pageX - startX);
97                const moveY = Math.abs(e.pageY - startY);
98                if (moveX > 3 || moveY > 3) {
99                    isDragging = true;
100                }
101            }
102        };
103        
104        const handleMouseUp = (e) => {
105            document.removeEventListener('mousemove', handleMouseMove);
106            
107            if (!isDragging) {
108                // 使用短延时确保不是拖拽
109                setTimeout(() => {
110                    if (!isDragging) {
111                        openPracticeImageViewer(index);
112                    }
113                }, 50);
114            }
115            isDragging = false;
116        };
117        
118        imageGrid.appendChild(imageItem);
119    });
120
121    container.innerHTML = '';
122    container.appendChild(imageGrid);
123}
124
125// 打开图片查看器
126function openPracticeImageViewer(index) {
127    practiceCurrentImageIndex = index;
128    const viewer = document.querySelector('#practice-window .image-viewer');
129    const viewerImg = viewer.querySelector('.viewer-content img');
130    
131    viewerImg.src = practiceImages[index].url;
132    viewer.classList.add('active');
133
134    // 添加点击事件监听器
135    viewer.onclick = (e) => {
136        // 如果点击的是图片查看器的背景(而不是图片内容),则关闭查看器
137        if (e.target === viewer) {
138            closePracticeImageViewer();
139        }
140    };
141}
142
143// 关闭图片查看器
144function closePracticeImageViewer() {
145    const viewer = document.querySelector('#practice-window .image-viewer');
146    viewer.classList.remove('active');
147}
148
149// 显示下一张图片
150function showNextPracticeImage() {
151    practiceCurrentImageIndex = (practiceCurrentImageIndex + 1) % practiceImages.length;
152    const viewerImg = document.querySelector('#practice-window .viewer-content img');
153    viewerImg.src = practiceImages[practiceCurrentImageIndex].url;
154}
155
156// 显示上一张图片
157function showPrevPracticeImage() {
158    practiceCurrentImageIndex = (practiceCurrentImageIndex - 1 + practiceImages.length) % practiceImages.length;
159    const viewerImg = document.querySelector('#practice-window .viewer-content img');
160    viewerImg.src = practiceImages[practiceCurrentImageIndex].url;
161}
162
163// 键盘事件处理
164document.addEventListener('keydown', (e) => {
165    const viewer = document.querySelector('#practice-window .image-viewer');
166    if (!viewer.classList.contains('active')) return;
167
168    switch(e.key) {
169        case 'Escape':
170            closePracticeImageViewer();
171            break;
172        case 'ArrowRight':
173            showNextPracticeImage();
174            break;
175        case 'ArrowLeft':
176            showPrevPracticeImage();
177            break;
178    }
179});
180
181// 窗口加载完成后初始化
182window.addEventListener('load', () => {
183    // 当练习相册窗口打开时加载图片
184    const practiceWindow = document.getElementById('practice-window');
185    if (practiceWindow) {
186        const observer = new MutationObserver((mutations) => {
187            mutations.forEach((mutation) => {
188                if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
189                    if (practiceWindow.style.display !== 'none') {
190                        loadPracticeImages();
191                    }
192                }
193            });
194        });
195
196        observer.observe(practiceWindow, {
197            attributes: true
198        });
199    }
200});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.