迁移仓库
This commit is contained in:
commit
0238605978
108
.gitignore
vendored
Normal file
108
.gitignore
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
# Created by .ignore support plugin (hsz.mobi)
|
||||
### Python template
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# celery beat schedule file
|
||||
celerybeat-schedule
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
|
||||
.idea
|
||||
status/img
|
34
README.md
Normal file
34
README.md
Normal file
@ -0,0 +1,34 @@
|
||||
# 个人相册
|
||||
简单个人相册
|
||||
|
||||
[相册demo](http://www.zeekling.cn/allPhotos/)
|
||||
|
||||
|
||||
## 配置
|
||||
|
||||
### photo.properties 文件
|
||||
|
||||
主要是配置相册中图片的位置
|
||||
```
|
||||
img.url=/home/zeek/project/photo/static/img
|
||||
```
|
||||
|
||||
### 相册配置
|
||||
|
||||
相册是按照配置相册的目录分类的,一个子文件夹就是一个相册.每个子文件夹都需要一个`info.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"name":"小令童鞋",
|
||||
"des":"小令童鞋个人相册"
|
||||
}
|
||||
```
|
||||
|
||||
## 启动
|
||||
|
||||
执行下面脚本
|
||||
|
||||
```sh
|
||||
bash startup.sh
|
||||
```
|
||||
|
BIN
db.sqlite3
Normal file
BIN
db.sqlite3
Normal file
Binary file not shown.
15
manage.py
Executable file
15
manage.py
Executable file
@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
|
||||
if __name__ == '__main__':
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'photo.settings')
|
||||
try:
|
||||
from django.core.management import execute_from_command_line
|
||||
except ImportError as exc:
|
||||
raise ImportError(
|
||||
"Couldn't import Django. Are you sure it's installed and "
|
||||
"available on your PYTHONPATH environment variable? Did you "
|
||||
"forget to activate a virtual environment?"
|
||||
) from exc
|
||||
execute_from_command_line(sys.argv)
|
1
photo.properties
Normal file
1
photo.properties
Normal file
@ -0,0 +1 @@
|
||||
img.url=/home/pi/bigdisk/data/opt/photo/static/img
|
134
photo/settings.py
Normal file
134
photo/settings.py
Normal file
@ -0,0 +1,134 @@
|
||||
"""
|
||||
Django settings for photo project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 2.1.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/2.1/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/2.1/ref/settings/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = 'wtbz+o+$z3qd^7yqqu=fxr218s_i0hftkwlbpjtu79^l9xsfkw'
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = []
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'photo.urls'
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [os.path.join(BASE_DIR, 'templates')]
|
||||
,
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.debug',
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = 'photo.wsgi.application'
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/2.1/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
TIME_ZONE = 'UTC'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_L10N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/2.1/howto/static-files/
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
## add
|
||||
|
||||
|
||||
STATICFILES_DIRS = (
|
||||
os.path.join(BASE_DIR, "static"),
|
||||
# os.path.join(BASE_DIR, 'static').replace('\\', '/'),
|
||||
)
|
||||
|
||||
STATICFILES_FINDERS = (
|
||||
"django.contrib.staticfiles.finders.FileSystemFinder",
|
||||
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
|
||||
)
|
25
photo/urls.py
Normal file
25
photo/urls.py
Normal file
@ -0,0 +1,25 @@
|
||||
"""photo2 URL Configuration
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/2.1/topics/http/urls/
|
||||
Examples:
|
||||
Function views
|
||||
1. Add an import: from my_app import views
|
||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||
Class-based views
|
||||
1. Add an import: from other_app.views import Home
|
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||
Including another URLconf
|
||||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import path
|
||||
from . import view
|
||||
|
||||
urlpatterns = [
|
||||
path(r'admin/', admin.site.urls, name='admin'),
|
||||
path(r'photo/data/data.json', view.photo_qry, name='data'),
|
||||
path(r'photo/', view.photo, name='photo'),
|
||||
path(r'allPhotos/', view.photo_all, name='allPhotos')
|
||||
]
|
48
photo/util/fileUtil.py
Normal file
48
photo/util/fileUtil.py
Normal file
@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: UTF-8 -*-
|
||||
import os
|
||||
import json
|
||||
|
||||
allow_pics = ['png', 'jpg', 'jpeg']
|
||||
|
||||
|
||||
def get_all_pics(path):
|
||||
pics = []
|
||||
for file in os.listdir(path):
|
||||
file_path = os.path.join(path, file)
|
||||
if os.path.isdir(file_path):
|
||||
continue
|
||||
allow_type = False
|
||||
for pic_type in allow_pics:
|
||||
if str(file).lower().endswith(pic_type):
|
||||
allow_type = True
|
||||
break
|
||||
if allow_type:
|
||||
pics.append(file)
|
||||
return pics
|
||||
|
||||
|
||||
def get_all_folds(path):
|
||||
folds = []
|
||||
for fold in os.listdir(path):
|
||||
fold_path = os.path.join(path, fold)
|
||||
if os.path.isdir(fold_path):
|
||||
entity = {'fold': fold, 'fold_path': fold_path}
|
||||
folds.append(entity)
|
||||
|
||||
return folds
|
||||
|
||||
|
||||
def read_file_json(path):
|
||||
if not os.path.exists(path) or not os.path.isfile(path):
|
||||
return json.loads('{"name": "default", "des":"默认描述"}')
|
||||
f = open(path, 'r')
|
||||
lines = f.readlines()
|
||||
json_str = ""
|
||||
for line in lines:
|
||||
json_str += line
|
||||
return json.loads(json_str)
|
||||
|
||||
# path = "/home/zeek/project/photo/static/img"
|
||||
# pics = get_all_pics(path)
|
||||
# print(pics)
|
28
photo/util/properties.py
Normal file
28
photo/util/properties.py
Normal file
@ -0,0 +1,28 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
|
||||
|
||||
class properties(object):
|
||||
|
||||
def __init__(self, filename):
|
||||
self.filename = filename
|
||||
self.properties = {}
|
||||
|
||||
def get_properties(self):
|
||||
try:
|
||||
pro_file = open(self.filename)
|
||||
for line in pro_file.readlines():
|
||||
line = line.strip().replace('\n', '')
|
||||
if line.find('=') > 0:
|
||||
s = line.split('=')
|
||||
self.properties[s[0].strip()] = s[1]
|
||||
else:
|
||||
self.properties[line] = ''
|
||||
except Exception as e:
|
||||
raise e
|
||||
else:
|
||||
pro_file.close()
|
||||
return self.properties
|
||||
|
||||
|
||||
# tmp = properties('../photo.properties').get_properties()
|
||||
# print(tmp)
|
89
photo/view.py
Normal file
89
photo/view.py
Normal file
@ -0,0 +1,89 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
|
||||
import json
|
||||
from django.shortcuts import render
|
||||
from django.http import HttpResponse
|
||||
from photo.util import fileUtil, properties
|
||||
import os
|
||||
|
||||
|
||||
prop = properties.properties(os.path.abspath("photo.properties")).get_properties()
|
||||
|
||||
|
||||
def photo(request):
|
||||
path = prop['img.url']
|
||||
fold = ""
|
||||
if request.method == "GET":
|
||||
fold = request.GET.get("name", "")
|
||||
|
||||
if request.method == "POST":
|
||||
fold = request.POST.get("name", "")
|
||||
new_path = path + "/" + fold
|
||||
context = {'index': 'Hello World!', 'name': fold}
|
||||
info = fileUtil.read_file_json(new_path + '/info.json')
|
||||
if 'name' in info:
|
||||
context['title'] = info['name']
|
||||
return render(request, 'photo/index.html', context)
|
||||
|
||||
|
||||
def get_pics(path, fold=""):
|
||||
pics = fileUtil.get_all_pics(path)
|
||||
data = []
|
||||
for pic in pics:
|
||||
if fold != "":
|
||||
tmp_pic = {'name': 'img/' + fold + "/" + pic, 'caption': ''}
|
||||
else:
|
||||
tmp_pic = {'name': 'img/' + pic, 'caption': ''}
|
||||
data.append(tmp_pic)
|
||||
|
||||
if len(data) >= 2:
|
||||
data.append(data[1])
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def photo_all(request):
|
||||
path = prop['img.url']
|
||||
data = []
|
||||
folds = fileUtil.get_all_folds(path)
|
||||
folds.append({'fold': '', 'fold_path': path})
|
||||
for fold in folds:
|
||||
pics = fileUtil.get_all_pics(fold['fold_path'])
|
||||
if len(pics) == 0:
|
||||
continue
|
||||
info = fileUtil.read_file_json(fold['fold_path'] + '/info.json')
|
||||
entity = {'name': info['name'], 'des': info['des'],
|
||||
'fold': fold['fold']}
|
||||
if fold['fold'] == '':
|
||||
entity['pic'] = 'img/' + pics[0]
|
||||
else:
|
||||
entity['pic'] = 'img/' + fold['fold'] + '/' + pics[0]
|
||||
data.append(entity)
|
||||
context = {'data': data, 'success': 'true'}
|
||||
print(context)
|
||||
# return HttpResponse(json.dumps(data), content_type="application/json")
|
||||
return render(request, 'photo/photos.html', context)
|
||||
|
||||
|
||||
def photo_qry(request):
|
||||
path = prop['img.url']
|
||||
fold = ""
|
||||
if request.method == "GET":
|
||||
fold = request.GET.get("name", "")
|
||||
|
||||
if request.method == "POST":
|
||||
fold = request.POST.get("name", "")
|
||||
|
||||
new_path = ""
|
||||
data = []
|
||||
if fold != "":
|
||||
new_path = path + "/" + fold
|
||||
data = get_pics(new_path, fold=fold)
|
||||
|
||||
if len(data) == 0:
|
||||
if fold != "":
|
||||
print("fold %s has none pics" % fold)
|
||||
data = get_pics(path)
|
||||
# print(data)
|
||||
return HttpResponse(json.dumps(data), content_type="application/json")
|
||||
|
16
photo/wsgi.py
Normal file
16
photo/wsgi.py
Normal file
@ -0,0 +1,16 @@
|
||||
"""
|
||||
WSGI config for photo2 project.
|
||||
|
||||
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'photo.settings')
|
||||
|
||||
application = get_wsgi_application()
|
2
startup.sh
Executable file
2
startup.sh
Executable file
@ -0,0 +1,2 @@
|
||||
#/usr/bin/python3 manage.py runserver 127.0.0.1:8008 >/tmp/photo.log 2>&1 &
|
||||
/usr/bin/python3 manage.py runserver 127.0.0.1:8008 >/dev/null &
|
1
static/.gitignore
vendored
Normal file
1
static/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
img/
|
61
static/css/polaroid-gallery.css
Normal file
61
static/css/polaroid-gallery.css
Normal file
@ -0,0 +1,61 @@
|
||||
body {
|
||||
background-color: #F2EBE2;
|
||||
}
|
||||
|
||||
.fullscreen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
figure {
|
||||
width: 200px;
|
||||
position: absolute;
|
||||
padding: 10px;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
background-color: white;
|
||||
-webkit-transition: all 0.6s;
|
||||
-moz-transition: all 0.6s;
|
||||
transition: all 0.6s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
figure img {
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
figure figcaption {
|
||||
font-family: Comic Sans, Comic Sans MS, cursive;
|
||||
color: #8F8476;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
background-color: black;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: transparent;
|
||||
padding: 10px 24px;
|
||||
color: #ffffff;
|
||||
border: 2px solid black;
|
||||
-webkit-transition-duration: 0.4s;
|
||||
transition-duration: 0.4s;
|
||||
transition: 0.4s;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #f44336;
|
||||
color: white;
|
||||
}
|
1
static/css/reset.css
Normal file
1
static/css/reset.css
Normal file
@ -0,0 +1 @@
|
||||
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}table{border-collapse:collapse;border-spacing:0}
|
108
static/css/style.css
Normal file
108
static/css/style.css
Normal file
@ -0,0 +1,108 @@
|
||||
|
||||
@import url(http://weloveiconfonts.com/api/?family=entypo);
|
||||
[class*="entypo-"]:before {
|
||||
font-family: 'entypo', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #eaeaea;
|
||||
font-family: 'Roboto';
|
||||
}
|
||||
|
||||
.center-block, .carrousel, .carrousel .wrapper {
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.gallery {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.portrait {
|
||||
width: 150px;
|
||||
box-shadow: 0 0 3px #555;
|
||||
background-color: #FFF;
|
||||
padding: 5px;
|
||||
margin: 7px 0px 0px 7px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
float: left;
|
||||
-moz-transition: all 0.3s ease;
|
||||
-o-transition: all 0.3s ease;
|
||||
-webkit-transition: all 0.3s ease;
|
||||
transition: all 0.3s ease;
|
||||
-webkit-filter: grayscale(100%);
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
.portrait:hover {
|
||||
-moz-transform: scale(1.04, 1.04);
|
||||
-ms-transform: scale(1.04, 1.04);
|
||||
-webkit-transform: scale(1.04, 1.04);
|
||||
transform: scale(1.04, 1.04);
|
||||
box-shadow: 0 0 5px #555;
|
||||
-webkit-filter: grayscale(0%);
|
||||
filter: grayscale(0%);
|
||||
}
|
||||
.portrait .pic {
|
||||
width: 150px;
|
||||
height: 210px;
|
||||
margin: 5px 0;
|
||||
}
|
||||
.portrait .date {
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.portrait .foot {
|
||||
font-size: 11px;
|
||||
}
|
||||
.portrait .foot .heart {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.carrousel {
|
||||
position: fixed;
|
||||
background-color: rgba(10, 10, 10, 0.8);
|
||||
display: none;
|
||||
}
|
||||
.carrousel .wrapper {
|
||||
width: 600px;
|
||||
height: 600px;
|
||||
overflow: hidden;
|
||||
/*.loading{
|
||||
color: #FFF;
|
||||
font-size: 24px;
|
||||
margin: 40% 40%;
|
||||
display: none;
|
||||
}*/
|
||||
}
|
||||
.carrousel .wrapper > img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.close {
|
||||
cursor: pointer;
|
||||
color: #FFF;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 8px;
|
||||
font-size: 18px;
|
||||
}
|
||||
.close:hover {
|
||||
font-size: 20px;
|
||||
color: #DDD;
|
||||
}
|
||||
|
||||
.content{
|
||||
width: 85%;
|
||||
margin: auto;
|
||||
}
|
||||
.brief{
|
||||
width:85%;
|
||||
margin: auto;
|
||||
margin-top:20px;
|
||||
margin-bottom:20px;
|
||||
}
|
101
static/css/style.scss
Normal file
101
static/css/style.scss
Normal file
@ -0,0 +1,101 @@
|
||||
@import "compass/css3";
|
||||
|
||||
@import url(http://fonts.googleapis.com/css?family=Roboto:300,400,500,700);
|
||||
@import url(http://weloveiconfonts.com/api/?family=entypo);
|
||||
|
||||
[class*="entypo-"]:before {
|
||||
font-family: 'entypo', sans-serif;
|
||||
}
|
||||
|
||||
body{
|
||||
background-color: #eaeaea;
|
||||
font-family: 'Roboto';
|
||||
}
|
||||
|
||||
.center-block{
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.gallery{
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
//gallery items width
|
||||
$width: 150px;
|
||||
//preview image size
|
||||
$width-wide: 600px;
|
||||
$height-wide: 600px;
|
||||
|
||||
.portrait{
|
||||
width: $width;
|
||||
box-shadow: 0 0 3px #555;
|
||||
background-color: #FFF;
|
||||
padding: 5px;
|
||||
margin: 7px 0px 0px 7px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
float: left;
|
||||
@include transition( all 0.3s ease );
|
||||
@include filter(grayscale(100%));
|
||||
|
||||
&:hover{
|
||||
@include scale(1.04);
|
||||
box-shadow: 0 0 5px #555;
|
||||
@include filter(grayscale(0%));
|
||||
}
|
||||
.pic{
|
||||
width: 100%;
|
||||
margin: 5px 0;
|
||||
}
|
||||
.date{
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.foot{
|
||||
font-size: 11px;
|
||||
.comment{}
|
||||
.heart{
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
}//.portrait
|
||||
|
||||
.carrousel{
|
||||
@extend .center-block;
|
||||
position: fixed;
|
||||
background-color: rgba(10, 10, 10, 0.8);
|
||||
display: none;
|
||||
.wrapper{
|
||||
@extend .center-block;
|
||||
width: $width-wide;
|
||||
height: $height-wide;
|
||||
overflow: hidden;
|
||||
/*.loading{
|
||||
color: #FFF;
|
||||
font-size: 24px;
|
||||
margin: 40% 40%;
|
||||
display: none;
|
||||
}*/
|
||||
>img{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.close{
|
||||
cursor: pointer;
|
||||
color: #FFF;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 8px;
|
||||
font-size: 18px;
|
||||
&:hover{
|
||||
font-size: 20px;
|
||||
color: #DDD;
|
||||
}
|
||||
}
|
62
static/data/data.json
Normal file
62
static/data/data.json
Normal file
@ -0,0 +1,62 @@
|
||||
[
|
||||
{
|
||||
"name": "../img/1.jpg",
|
||||
"caption": "girl-1"
|
||||
},
|
||||
{
|
||||
"name": "../img/2.jpg",
|
||||
"caption": "girl-2"
|
||||
},
|
||||
{
|
||||
"name": "../img/3.jpg",
|
||||
"caption": "girl-3"
|
||||
},
|
||||
{
|
||||
"name": "../img/4.jpg",
|
||||
"caption": "girl-4"
|
||||
},
|
||||
{
|
||||
"name": "../img/5.jpg",
|
||||
"caption": "girl-5"
|
||||
},
|
||||
{
|
||||
"name": "../img/6.jpg",
|
||||
"caption": "girl-6"
|
||||
},
|
||||
{
|
||||
"name": "../img/7.jpg",
|
||||
"caption": "girl-7"
|
||||
},
|
||||
{
|
||||
"name": "../img/8.jpg",
|
||||
"caption": "girl-8"
|
||||
},
|
||||
{
|
||||
"name": "../img/9.jpg",
|
||||
"caption": "girl-9"
|
||||
},
|
||||
{
|
||||
"name": "../img/10.jpg",
|
||||
"caption": "girl-10"
|
||||
},
|
||||
{
|
||||
"name": "../img/11.jpg",
|
||||
"caption": "girl-11"
|
||||
},
|
||||
{
|
||||
"name": "../img/12.jpg",
|
||||
"caption": "girl-12"
|
||||
},
|
||||
{
|
||||
"name": "../img/13.jpg",
|
||||
"caption": "girl-13"
|
||||
},
|
||||
{
|
||||
"name": "../img/14.jpg",
|
||||
"caption": "girl-14"
|
||||
},
|
||||
{
|
||||
"name": "../img/15.jpg",
|
||||
"caption": "girl-15"
|
||||
}
|
||||
]
|
12
static/js/index.js
Normal file
12
static/js/index.js
Normal file
@ -0,0 +1,12 @@
|
||||
var carrousel = $( ".carrousel" );
|
||||
|
||||
$( ".portrait" ).click( function(e){
|
||||
var src = $(this).find(".pic").attr( "data-src-wide" );
|
||||
carrousel.find("img").attr( "src", src );
|
||||
carrousel.fadeIn( 200 );
|
||||
});
|
||||
|
||||
carrousel.find( ".close" ).click( function(e){
|
||||
carrousel.find( "img" ).attr( "src", '' );
|
||||
carrousel.fadeOut( 200 );
|
||||
} );
|
16
static/js/jquery.js
vendored
Normal file
16
static/js/jquery.js
vendored
Normal file
File diff suppressed because one or more lines are too long
175
static/js/polaroid-gallery.js
Normal file
175
static/js/polaroid-gallery.js
Normal file
@ -0,0 +1,175 @@
|
||||
var polaroidGallery = (function () {
|
||||
var dataSize = {};
|
||||
var dataLength = 0;
|
||||
var currentItem = null;
|
||||
var navbarHeight = 60;
|
||||
var resizeTimeout = null;
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
var url = "data/data.json";
|
||||
|
||||
function polaroidGallery(url) {
|
||||
observe();
|
||||
xmlhttp.onreadystatechange = function () {
|
||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||
var myArr = JSON.parse(xmlhttp.responseText);
|
||||
setGallery(myArr);
|
||||
|
||||
init();
|
||||
}
|
||||
};
|
||||
xmlhttp.open("GET", url, true);
|
||||
xmlhttp.send();
|
||||
}
|
||||
|
||||
function setGallery(arr) {
|
||||
var out = "";
|
||||
var i;
|
||||
for (i = 0; i < arr.length; i++) {
|
||||
out += '<figure id="' + i + '">' +
|
||||
'<img src="/static/' + arr[i].name + '" alt="' + arr[i].name + '"/>' +
|
||||
'<figcaption>' + arr[i].caption + '</figcaption>' +
|
||||
'</figure>';
|
||||
}
|
||||
document.getElementById("gallery").innerHTML = out;
|
||||
}
|
||||
|
||||
function observe() {
|
||||
var observeDOM = (function () {
|
||||
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver,
|
||||
eventListenerSupported = window.addEventListener;
|
||||
|
||||
return function (obj, callback) {
|
||||
if (MutationObserver) {
|
||||
var obs = new MutationObserver(function (mutations, observer) {
|
||||
if( mutations[0].addedNodes.length || mutations[0].removedNodes.length )
|
||||
callback(mutations);
|
||||
});
|
||||
|
||||
obs.observe(obj, { childList: true, subtree: false });
|
||||
}
|
||||
else if (eventListenerSupported) {
|
||||
obj.addEventListener('DOMNodeInserted', callback, false);
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
observeDOM(document.getElementById('gallery'), function (mutations) {
|
||||
var gallery = [].slice.call(mutations[0].addedNodes);
|
||||
var zIndex = 1;
|
||||
gallery.forEach(function (item) {
|
||||
var img = item.getElementsByTagName('img')[0];
|
||||
var first = true;
|
||||
img.addEventListener('load', function () {
|
||||
if (first) {
|
||||
currentItem = item;
|
||||
first = false;
|
||||
}
|
||||
dataSize[item.id] = {item: item, width: item.offsetWidth, height: item.offsetHeight};
|
||||
|
||||
dataLength++;
|
||||
|
||||
item.addEventListener('click', function () {
|
||||
select(item);
|
||||
shuffleAll();
|
||||
});
|
||||
|
||||
shuffle(item, zIndex++);
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function init() {
|
||||
navbarHeight = document.getElementById("nav").offsetHeight;
|
||||
navigation();
|
||||
|
||||
window.addEventListener('resize', function () {
|
||||
if (resizeTimeout) {
|
||||
clearTimeout(resizeTimeout);
|
||||
}
|
||||
resizeTimeout = setTimeout(function () {
|
||||
shuffleAll();
|
||||
if (currentItem) {
|
||||
select(currentItem);
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
|
||||
function select(item) {
|
||||
var scale = 1.8;
|
||||
var rotRandomD = 0;
|
||||
|
||||
var initWidth = dataSize[item.id].width;
|
||||
var initHeight = dataSize[item.id].height;
|
||||
|
||||
var newWidth = (initWidth * scale);
|
||||
var newHeight = initHeight * (newWidth / initWidth);
|
||||
|
||||
var x = (window.innerWidth - newWidth) / 2;
|
||||
var y = (window.innerHeight - navbarHeight - newHeight) / 2;
|
||||
|
||||
item.style.transformOrigin = '0 0';
|
||||
item.style.WebkitTransform = 'translate(' + x + 'px,' + y + 'px) rotate(' + rotRandomD + 'deg) scale(' + scale + ',' + scale + ')';
|
||||
item.style.msTransform = 'translate(' + x + 'px,' + y + 'px) rotate(' + rotRandomD + 'deg) scale(' + scale + ',' + scale + ')';
|
||||
item.style.transform = 'translate(' + x + 'px,' + y + 'px) rotate(' + rotRandomD + 'deg) scale(' + scale + ',' + scale + ')';
|
||||
item.style.zIndex = 999;
|
||||
|
||||
currentItem = item;
|
||||
}
|
||||
|
||||
function shuffle(item, zIndex) {
|
||||
var randomX = Math.random();
|
||||
var randomY = Math.random();
|
||||
var maxR = 45;
|
||||
var minR = -45;
|
||||
var rotRandomD = Math.random() * (maxR - minR) + minR;
|
||||
var rotRandomR = rotRandomD * Math.PI / 180;
|
||||
|
||||
var rotatedW = Math.abs(item.offsetWidth * Math.cos(rotRandomR)) + Math.abs(item.offsetHeight * Math.sin(rotRandomR));
|
||||
var rotatedH = Math.abs(item.offsetWidth * Math.sin(rotRandomR)) + Math.abs(item.offsetHeight * Math.cos(rotRandomR));
|
||||
|
||||
var x = Math.floor((window.innerWidth - rotatedW) * randomX);
|
||||
var y = Math.floor((window.innerHeight - rotatedH) * randomY);
|
||||
|
||||
item.style.transformOrigin = '0 0';
|
||||
item.style.WebkitTransform = 'translate(' + x + 'px,' + y + 'px) rotate(' + rotRandomD + 'deg) scale(1)';
|
||||
item.style.msTransform = 'translate(' + x + 'px,' + y + 'px) rotate(' + rotRandomD + 'deg) scale(1)';
|
||||
item.style.transform = 'translate(' + x + 'px,' + y + 'px) rotate(' + rotRandomD + 'deg) scale(1)';
|
||||
item.style.zIndex = zIndex;
|
||||
}
|
||||
|
||||
function shuffleAll() {
|
||||
var zIndex = 0;
|
||||
for (var id in dataSize) {
|
||||
if (id != currentItem.id) {
|
||||
shuffle(dataSize[id].item, zIndex++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function navigation() {
|
||||
var next = document.getElementById('next');
|
||||
var preview = document.getElementById('preview');
|
||||
|
||||
next.addEventListener('click', function () {
|
||||
var currentIndex = Number(currentItem.id) + 1;
|
||||
if (currentIndex >= dataLength) {
|
||||
currentIndex = 0
|
||||
}
|
||||
select(dataSize[currentIndex].item);
|
||||
shuffleAll();
|
||||
});
|
||||
|
||||
preview.addEventListener('click', function () {
|
||||
var currentIndex = Number(currentItem.id) - 1;
|
||||
if (currentIndex < 0) {
|
||||
currentIndex = dataLength - 1
|
||||
}
|
||||
select(dataSize[currentIndex].item);
|
||||
shuffleAll();
|
||||
})
|
||||
}
|
||||
|
||||
return polaroidGallery;
|
||||
})();
|
29
templates/photo/index.html
Normal file
29
templates/photo/index.html
Normal file
@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
{% load static %}
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{ title }}</title>
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'css/polaroid-gallery.css'%}"/>
|
||||
<!--[if IE]>
|
||||
<script src="http://libs.baidu.com/html5shiv/3.7/html5shiv.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body class="fullscreen">
|
||||
<div id="gallery" class="fullscreen"></div>
|
||||
<div id="nav" class="navbar">
|
||||
<button id="preview">< 前一张</button>
|
||||
<button id="next">下一张 ></button>
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript" src="{% static 'js/polaroid-gallery.js' %}"></script>
|
||||
<script>
|
||||
window.onload = function () {
|
||||
new polaroidGallery("/photo/data/data.json?name={{ name }}");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
50
templates/photo/photos.html
Normal file
50
templates/photo/photos.html
Normal file
@ -0,0 +1,50 @@
|
||||
<!DOCTYPE html>
|
||||
{% load static %}
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
|
||||
<title>小令童鞋相册</title>
|
||||
<link rel="stylesheet" href="{% static 'css/reset.css' %}">
|
||||
<link rel="stylesheet" href="{% static 'css/style.css' %}" media="screen" type="text/css" />
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="content">
|
||||
<div class="brief"> </div>
|
||||
{% for photo in data %}
|
||||
<ul class="gallery">
|
||||
<li class="portrait">
|
||||
<span class="date">{{ photo.name }}</span>
|
||||
<a href="{% url 'photo' %}?name={{ photo.fold }}">
|
||||
<img class="pic" src="{% static '/' %}{{ photo.pic }}" alt="BINGOO" />
|
||||
</a>
|
||||
<div class="foot">
|
||||
<span class="entypo-comment comment">{{ photo.des }}</span>
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
<div class="carrousel">
|
||||
<span class="close entypo-cancel"></span>
|
||||
<span class="entypo-arrows-ccw loanding"> Loading large photo</span>
|
||||
<div class="wrapper">
|
||||
<img src="" alt="BINGOO" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="{% static 'js/jquery.js' %}"></script>
|
||||
<!--
|
||||
<script src="{% static 'js/index.js' %}"></script>
|
||||
-->
|
||||
<div style="text-align:center;clear:both;">
|
||||
<!--
|
||||
<script src="/gg_bd_ad_720x90.js" type="text/javascript"></script>
|
||||
<script src="/follow.js" type="text/javascript"></script>
|
||||
-->
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
Reference in New Issue
Block a user