Browse Source

can run

master
felix xia 5 years ago
parent
commit
3c626f6334
  1. 120
      build.xml
  2. 56
      plugin-widget-easyslides10.iml
  3. 26
      plugin.xml
  4. 14
      pom.xml
  5. 16
      specific.md
  6. 6
      src/main/java/com/fr/plugin/easyslides/Constants.java
  7. 10
      src/main/java/com/fr/plugin/easyslides/CssFileLoader.java
  8. 249
      src/main/java/com/fr/plugin/easyslides/EasySlidesWidget.java
  9. 22
      src/main/java/com/fr/plugin/easyslides/JsFileLoader.java
  10. 10
      src/main/java/com/fr/plugin/easyslides/LocaleFinder.java
  11. 34
      src/main/java/com/fr/plugin/easyslides/OptionProvider.java
  12. 26
      src/main/java/com/fr/plugin/easyslides/Util.java
  13. BIN
      src/main/java/com/fr/plugin/easyslides/images/display.png
  14. BIN
      src/main/java/com/fr/plugin/easyslides/images/icon.png
  15. 13
      src/main/java/com/fr/plugin/easyslides/local/easyslides.properties
  16. 13
      src/main/java/com/fr/plugin/easyslides/local/easyslides_en_US.properties
  17. 13
      src/main/java/com/fr/plugin/easyslides/local/easyslides_zh_CN.properties
  18. 21
      src/main/java/com/fr/plugin/easyslides/slidestyles/FarAwayStyle.java
  19. 21
      src/main/java/com/fr/plugin/easyslides/slidestyles/HorizontalStyle.java
  20. 51
      src/main/java/com/fr/plugin/easyslides/slidestyles/SlideStyle.java
  21. 16
      src/main/java/com/fr/plugin/easyslides/slidestyles/StyleFactory.java
  22. 18
      src/main/java/com/fr/plugin/easyslides/slidestyles/VerticalStyle.java
  23. 28
      src/main/java/com/fr/plugin/easyslides/ui/AutoPlayEditor.java
  24. 87
      src/main/java/com/fr/plugin/easyslides/ui/EasySlidesWidgetUI.java
  25. 23
      src/main/java/com/fr/plugin/easyslides/ui/SlideStyleEditor.java
  26. 50
      src/main/java/com/fr/plugin/easyslides/ui/SlidesDataSourceEditor.java
  27. 810
      src/main/java/com/fr/plugin/easyslides/web/impress-default.css
  28. 918
      src/main/java/com/fr/plugin/easyslides/web/impress-main.js
  29. 3384
      src/main/java/com/fr/plugin/easyslides/web/impress-plugins.js
  30. 4296
      src/main/java/com/fr/plugin/easyslides/web/impress.js
  31. 60
      src/main/java/com/fr/plugin/easyslides/web/widget.js

120
build.xml

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="jar" name="plugin">
<!-- JDK路径,根据自己机器上实际位置修改-->
<property name="jdk.home" value="D:/Java/jdk1.8.0_25"/>
<property name="libs" value="${basedir}/lib"/>
<property name="publicLibs" value=""/>
<property name="reportLibs" value="${basedir}/../webroot/WEB-INF/lib"/>
<property name="destLoc" value="."/>
<property name="classes" value="classes"/>
<xmlproperty file="${basedir}/plugin.xml"/>
<property name="current-version" value="${plugin.version}"/>
<!-- 插件版本-->
<property name="plugin-version" value="${current-version}"/>
<!-- 插件名字-->
<property name="plugin-name" value="widget-flipconvert"/>
<property name="plugin-jar" value="fr-plugin-${plugin-name}-${plugin-version}.jar"/>
<target name="prepare">
<delete dir="${classes}"/>
<delete dir="fr-plugin-${plugin-name}-${plugin-version}"/>
<xmlproperty file="${basedir}/plugin.xml"/>
<delete dir="${destLoc}/${plugin.name}"/>
</target>
<path id="compile.classpath">
<!--<fileset dir="${libs}">
<include name="**/*.jar"/>
</fileset>-->
<fileset dir="${publicLibs}">
<include name="**/*.jar"/>
</fileset>
<fileset dir="${reportLibs}">
<include name="**/*.jar"/>
</fileset>
</path>
<patternset id="resources4Jar">
<exclude name="**/.settings/**"/>
<exclude name=".classpath"/>
<exclude name=".project"/>
<exclude name="**/*.java"/>
<exclude name="**/*.db"/>
<exclude name="**/*.g"/>
<exclude name="**/package.html"/>
</patternset>
<target name="copy_resources">
<echo message="从${resources_from}拷贝图片,JS,CSS等资源文件"/>
<delete dir="tmp"/>
<copy todir="tmp">
<fileset dir="${resources_from}\src">
<patternset refid="resources4Jar"/>
</fileset>
</copy>
<copy todir="${classes}">
<fileset dir="tmp"/>
</copy>
<delete dir="tmp"/>
</target>
<target name="compile_javas">
<echo message="编译${compile_files}下的Java文件"/>
<javac destdir="${classes}" debug="false" optimize="on" source="${source_jdk_version}"
target="${target_jdk_version}" includeantruntime="on"
fork="true" memoryMaximumSize="512m" listfiles="false" srcdir="${basedir}"
executable="${compile_jdk_version}/bin/javac">
<src path="${basedir}/src"/>
<exclude name="**/.svn/**"/>
<compilerarg line="-encoding UTF8 "/>
<classpath refid="compile.classpath"/>
</javac>
</target>
<target name="jar_classes">
<echo message="打Jar包:${jar_name}"/>
<delete file="${basedir}/${jar_name}"/>
<jar jarfile="${basedir}/${jar_name}">
<fileset dir="${classes}">
</fileset>
</jar>
</target>
<target name="super_jar" depends="prepare">
<antcall target="copy_resources">
<param name="resources_from" value="${basedir}"/>
</antcall>
<antcall target="compile_javas">
<param name="source_jdk_version" value="1.6"/>
<param name="target_jdk_version" value="1.6"/>
<param name="compile_jdk_version" value="${jdk.home}"/>
<param name="compile_files" value="${basedir}/src"/>
</antcall>
<echo message="compile plugin success!"/>
<antcall target="jar_classes">
<param name="jar_name" value="${plugin-jar}"/>
</antcall>
<delete dir="${classes}"/>
</target>
<target name="jar" depends="super_jar">
<antcall target="zip"/>
</target>
<target name="zip">
<property name="plugin-folder" value="fr-plugin-${plugin-name}-${plugin-version}"/>
<echo message="----------zip files----------"/>
<mkdir dir="${plugin-folder}"/>
<copy todir="${plugin-folder}">
<fileset dir=".">
<include name="${plugin-jar}"/>
<include name="plugin.xml"/>
</fileset>
</copy>
<zip destfile="${basedir}/${plugin-folder}.zip" basedir=".">
<include name="${plugin-folder}/*.jar"/>
<include name="${plugin-folder}/plugin.xml"/>
</zip>
<xmlproperty file="${basedir}/plugin.xml"/>
<move file="${plugin-folder}.zip" todir="${destLoc}/${plugin.name}"/>
</target>
</project>

56
plugin-widget-easyslides10.iml

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6">
<output url="file://$MODULE_DIR$/../webroot/WEB-INF/plugins/plugin-com.fr.plugin.easysilides.v10-1.0/classes" />
<output-test url="file://$MODULE_DIR$/../plugin-widget-simpleppt10/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/../plugin-widget-simpleppt10/target" />
<excludeFolder url="file://$MODULE_DIR$/../plugin-widget-simpleppt10/webroot/WEB-INF/classes" />
<excludeFolder url="file://$MODULE_DIR$/../simpleppt/target" />
<excludeFolder url="file://$MODULE_DIR$/../simpleppt/webroot/WEB-INF/classes" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: com.fr.third:fine-third:10.0-RELEASE-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fr.activator:fine-activator:10.0-RELEASE-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fr.core:fine-core:10.0-RELEASE-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-all:4.1.17" level="project" />
<orderEntry type="library" name="Maven: com.fr.webui:fine-webui:10.0-RELEASE-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fr.datasource:fine-datasource:10.0-RELEASE-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fr.decision:fine-decision:10.0-RELEASE-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fr.decision:fine-decision-report:10.0-RELEASE-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fr.schedule:fine-schedule:10.0-RELEASE-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fr.schedule:fine-schedule-report:10.0-RELEASE-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fr.intelligence:fine-swift:10.0-RELEASE-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fineio:fineio:2.0-RELEASE-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fr.third.server:servlet-api:3.0" level="project" />
<orderEntry type="library" name="Maven: com.fr.intelligence:fine-accumulator:10.0-RELEASE-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fr.report:fine-report-engine:10.0-RELEASE-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.fr.report:fine-report-designer:10.0-RELEASE-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: io.socket:socket.io-client:0.7.0" level="project" />
<orderEntry type="library" name="Maven: io.socket:engine.io-client:0.7.0" level="project" />
<orderEntry type="library" name="Maven: com.squareup.okhttp3:okhttp-ws:3.0.1" level="project" />
<orderEntry type="library" name="Maven: com.squareup.okhttp3:okhttp:3.0.1" level="project" />
<orderEntry type="library" name="Maven: com.squareup.okio:okio:1.6.0" level="project" />
<orderEntry type="library" name="Maven: org.json:json:20090211" level="project" />
<orderEntry type="library" name="Maven: org.aspectj:aspectjrt:1.6.9" level="project" />
<orderEntry type="library" name="Maven: org.swingexplorer:swexpl:2.0" level="project" />
<orderEntry type="library" name="Maven: org.swingexplorer:swag:1.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-catalina:8.5.32" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-servlet-api:8.5.32" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-jsp-api:8.5.32" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-el-api:8.5.32" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-juli:8.5.32" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-annotations-api:8.5.32" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-api:8.5.32" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-jni:8.5.32" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-coyote:8.5.32" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-util:8.5.32" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-util-scan:8.5.32" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-jaspic-api:8.5.32" level="project" />
<orderEntry type="library" name="Maven: mysql:mysql-connector-java:5.1.44" level="project" />
</component>
</module>

26
plugin.xml

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<plugin>
<id>com.fr.plugin.easyslides.v10</id>
<name><![CDATA[超酷幻灯片]]></name>
<active>yes</active>
<version>1.0</version>
<env-version>10.0</env-version>
<jartime>2019-11-1</jartime>
<vendor>Felix</vendor>
<description><![CDATA[在表单中实现幻灯片效果插件。]]></description>
<change-notes><![CDATA[
<p>[2019-11-21]Felix:适配新的API</p>
]]></change-notes>
<extra-core>
<LocaleFinder class="com.fr.plugin.easyslides.LocaleFinder"/>
<JavaScriptFileHandler class="com.fr.plugin.easyslides.JsFileLoader"/>
<CssFileHandler class="com.fr.plugin.easyslides.CssFileLoader"/>
</extra-core>
<extra-designer>
<FormWidgetOptionProvider class="com.fr.plugin.easyslides.OptionProvider"/>
</extra-designer>
<function-recorder class="com.fr.plugin.easyslides.OptionProvider"/>
</plugin>

14
pom.xml

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.fr.plugin</groupId>
<artifactId>starter</artifactId>
<version>10.0</version>
</parent>
<packaging>jar</packaging>
<artifactId>plugin-widget-simpleppt10</artifactId>
</project>

16
specific.md

@ -0,0 +1,16 @@
##UI组成
- 数据源:一列,每行为一页slide的文字内容,其中可以用h5标签
- 幻灯片样式选择列表
- 背景颜色
- 可选项:1、自动/手动播放;2、自动播放间隔时间
##幻灯片样式
- 左入,右入
- 上入,下入
- 前入,后入
##比例
- slide width:900->1536 padding:40
- slide height:700->758 padding:60
- slide fontsize:30->(1536*758)
- slide line-height:36->(1536*758)

6
src/main/java/com/fr/plugin/easyslides/Constants.java

@ -0,0 +1,6 @@
package com.fr.plugin.easyslides;
public class Constants {
public static final String PLUGIN_ID = "com.fr.plugin.easyslides";
public static final String WIDGET_TYPE = "easyslides";
}

10
src/main/java/com/fr/plugin/easyslides/CssFileLoader.java

@ -0,0 +1,10 @@
package com.fr.plugin.easyslides;
import com.fr.stable.fun.impl.AbstractCssFileHandler;
public class CssFileLoader extends AbstractCssFileHandler {
@Override
public String[] pathsForFiles() {
return new String[]{"/com/fr/plugin/easyslides/web/impress-default.css"};
}
}

249
src/main/java/com/fr/plugin/easyslides/EasySlidesWidget.java

@ -0,0 +1,249 @@
package com.fr.plugin.easyslides;
import com.fr.base.Utils;
import com.fr.form.ui.DataControl;
import com.fr.form.ui.DirectWriteEditor;
import com.fr.form.ui.Widget;
import com.fr.form.ui.WidgetValue;
import com.fr.form.ui.concept.data.ValueInitializer;
import com.fr.json.JSONArray;
import com.fr.json.JSONException;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.easyslides.slidestyles.SlideStyle;
import com.fr.plugin.easyslides.slidestyles.StyleFactory;
import com.fr.plugin.easyslides.ui.SlideStyleEditor;
import com.fr.script.Calculator;
import com.fr.stable.core.NodeVisitor;
import com.fr.stable.script.CalculatorProvider;
import com.fr.stable.web.Repository;
import com.fr.stable.xml.XMLPrintWriter;
import com.fr.stable.xml.XMLableReader;
import java.awt.*;
import java.util.List;
import static com.fr.plugin.easyslides.Util.colorValueToHexString;
public class EasySlidesWidget extends DirectWriteEditor implements DataControl {
public static final String BACKGROUND_COLOR = "backgroundColor";
public static final String AUTO_PLAY = "autoPlay";
public static final String AUTO_PLAY_INTERVAL_TIME = "autoPlayIntervalTime";
public static final String SLIDE_STYLE = "slideStyle";
public static final String TOOLBAR = "toolBar";
public static final String PROGRESSBAR = "progressBar";
public static final String PROGRESS = "progress";
private ValueInitializer widgetValue;
private Object backgroundColor;
private boolean autoPlay;
private int autoPlayIntervalTime;
private String slideStyle;
private boolean toolBar;
private boolean progressBar;
private boolean progress;
public EasySlidesWidget() {
widgetValue = new WidgetValue();
//autoPlay = true;
setAutoPlayIntervalTime(5);
backgroundColor = new Color(215, 215, 215);
slideStyle = SlideStyleEditor.DEFAULT_STYLE;
}
public Object getBackgroundColor() {
return backgroundColor;
}
public void setBackgroundColor(Object backgroundColor) {
this.backgroundColor = backgroundColor;
}
public boolean isAutoPlay() {
return autoPlay;
}
public void setAutoPlay(boolean autoPlay) {
this.autoPlay = autoPlay;
if (getAutoPlayIntervalTime() <= 0) {
setAutoPlayIntervalTime(5);
}
}
public int getAutoPlayIntervalTime() {
return autoPlayIntervalTime;
}
public void setAutoPlayIntervalTime(int autoPlayIntervalTime) {
this.autoPlayIntervalTime = autoPlayIntervalTime;
if (autoPlayIntervalTime > 0) {
setAutoPlay(true);
} else {
setAutoPlay(false);
}
}
public String getSlideStyle() {
return slideStyle;
}
public void setSlideStyle(String slideStyle) {
this.slideStyle = slideStyle;
}
public boolean isToolBar() {
return toolBar;
}
public void setToolBar(boolean toolBar) {
this.toolBar = toolBar;
}
public boolean isProgressBar() {
return progressBar;
}
public void setProgressBar(boolean progressBar) {
this.progressBar = progressBar;
}
public boolean isProgress() {
return progress;
}
public void setProgress(boolean progress) {
this.progress = progress;
}
@Override
public String[] supportedEvents() {
return new String[0];
}
@Override
public int[] getValueType() {
return new int[]{TYPE_DATABINDING};
}
@Override
public void setWidgetValue(ValueInitializer valueInitializer) {
widgetValue = valueInitializer;
}
@Override
public ValueInitializer getWidgetValue() {
return widgetValue;
}
@Override
public void createValueResult(CalculatorProvider calculatorProvider, JSONObject jsonObject) {
if (this.getWidgetValue() != null) {
calculatorProvider.setAttribute(Widget.NAME, this.getWidgetName().toUpperCase());
calculatorProvider.setAttribute(ValueInitializer.RETURN_ARRAY, true);
calculatorProvider.setAttribute(ValueInitializer.VALUE_REPEAT, true);
Object result = getWidgetValue().executeResult(calculatorProvider);
try {
jsonObject.put(this.widgetName.toUpperCase(), result == null ? "" : result);
} catch (JSONException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
@Override
public String getFormatText() {
return "";
}
@Override
public String getDataBindDefaultValue(CalculatorProvider calculatorProvider) {
if (this.widgetValue == null) {
this.setWidgetValue(new WidgetValue());
}
Object result = this.getWidgetValue().executeResult(calculatorProvider);
if (result == null) {
return null;
} else {
return Utils.objectToString(result);
}
}
@Override
public String getXType() {
return Constants.WIDGET_TYPE;
}
@Override
public String[] dependence(CalculatorProvider calculatorProvider) {
return super.dependence(calculatorProvider);
}
@Override
public JSONObject createJSONConfig(Repository repository, Calculator calculator, NodeVisitor nodeVisitor) throws JSONException {
JSONObject jsonConfig = super.createJSONConfig(repository, calculator, nodeVisitor);
Object value = jsonConfig.get("value");
if (value != null) {
JSONArray jsonVal = (JSONArray) value;
String html = buildSlidesHtml((List<String>) jsonVal.getList());
jsonConfig.put("value", html);
}
jsonConfig.put(BACKGROUND_COLOR, colorValueToHexString(getBackgroundColor()));
jsonConfig.put(TOOLBAR, isToolBar());
jsonConfig.put(PROGRESSBAR, isProgressBar());
jsonConfig.put(PROGRESS, isProgress());
return jsonConfig;
}
/**
* 对幻灯片内容和样式进行组合
*/
private String buildSlidesHtml(List<String> contents) {
SlideStyle slideStyle = StyleFactory.createStyle(getSlideStyle());
if (slideStyle != null) {
return slideStyle.buildHtml(this, contents);
}
return null;
}
@Override
public void readXML(XMLableReader reader) {
super.readXML(reader);
if (reader.isChildNode()) {
String tag = reader.getTagName();
if (tag.equals("EasySlidesAttr")) {
String s = null;
if ((s = reader.getAttrAsString(SLIDE_STYLE, null)) != null) {
setSlideStyle(s);
}
int color;
if ((color = reader.getAttrAsInt(BACKGROUND_COLOR, -1)) != -1) {
setBackgroundColor(new Color(color));
}
setAutoPlayIntervalTime(reader.getAttrAsInt(AUTO_PLAY_INTERVAL_TIME, 0));
setToolBar(reader.getAttrAsBoolean(TOOLBAR, false));
setProgressBar(reader.getAttrAsBoolean(PROGRESSBAR, false));
setProgress(reader.getAttrAsBoolean(PROGRESS, false));
} else if ("widgetValue".equals(tag)) {
this.widgetValue = new WidgetValue();
reader.readXMLObject(this.widgetValue);
}
}
}
@Override
public void writeXML(XMLPrintWriter writer) {
super.writeXML(writer);
writer.startTAG("EasySlidesAttr");
writer.attr(SLIDE_STYLE, getSlideStyle());
writer.attr(BACKGROUND_COLOR, ((Color) getBackgroundColor()).getRGB());
writer.attr(AUTO_PLAY_INTERVAL_TIME, getAutoPlayIntervalTime());
writer.attr(TOOLBAR, isToolBar());
writer.attr(PROGRESSBAR, isProgressBar());
writer.attr(PROGRESS, isProgress());
writer.end();
if (this.widgetValue != null) {
this.widgetValue.writeXML(writer);
}
}
}

22
src/main/java/com/fr/plugin/easyslides/JsFileLoader.java

@ -0,0 +1,22 @@
package com.fr.plugin.easyslides;
import com.fr.plugin.PluginLicense;
import com.fr.plugin.PluginLicenseManager;
import com.fr.stable.fun.Authorize;
import com.fr.stable.fun.impl.AbstractJavaScriptFileHandler;
@Authorize(
callSignKey = Constants.PLUGIN_ID
)
public class JsFileLoader extends AbstractJavaScriptFileHandler {
private PluginLicense license = PluginLicenseManager.getInstance().getPluginLicenseByID(Constants.PLUGIN_ID);
@Override
public String[] pathsForFiles() {
return this.license.isAvailable() ?
new String[]{
"/com/fr/plugin/easyslides/web/widget.js"
}
: null;
}
}

10
src/main/java/com/fr/plugin/easyslides/LocaleFinder.java

@ -0,0 +1,10 @@
package com.fr.plugin.easyslides;
import com.fr.stable.fun.impl.AbstractLocaleFinder;
public class LocaleFinder extends AbstractLocaleFinder {
@Override
public String find() {
return "com/fr/plugin/easyslides/local/easyslides";
}
}

34
src/main/java/com/fr/plugin/easyslides/OptionProvider.java

@ -0,0 +1,34 @@
package com.fr.plugin.easyslides;
import com.fr.design.fun.impl.AbstractFormWidgetOptionProvider;
import com.fr.form.ui.Widget;
import com.fr.general.Inter;
import com.fr.plugin.easyslides.ui.EasySlidesWidgetUI;
import com.fr.plugin.transform.ExecuteFunctionRecord;
import com.fr.plugin.transform.FunctionRecorder;
@FunctionRecorder
public class OptionProvider extends AbstractFormWidgetOptionProvider {
@ExecuteFunctionRecord
public Class<? extends Widget> classForWidget() {
return EasySlidesWidget.class;
}
public Class<?> appearanceForWidget() {
return EasySlidesWidgetUI.class;
}
public String iconPathForWidget() {//图标
return "com/fr/plugin/easyslides/images/icon.png";
}
public String nameForWidget() {//插件名称
return Inter.getLocText("Plugin-EasySlides_Widget");
}
@Override
public boolean isContainer() {//是否容器
return false;
}
}

26
src/main/java/com/fr/plugin/easyslides/Util.java

@ -0,0 +1,26 @@
package com.fr.plugin.easyslides;
import java.awt.*;
public class Util {
private Util() {
}
public static String colorValueToHexString(int color) {
return '#' + Integer.toHexString(color).substring(2);
}
public static String colorValueToHexString(Object colorObj) {
Color c = (Color) colorObj;
String r = Integer.toHexString(c.getRGB());
return '#' + r.substring(2);
}
public static String colorValueToHexString(Object colorObj, float alpha) {
Color color = (Color) colorObj;
Color c = new Color(((float) color.getRed()) / 255, ((float) color.getGreen()) / 255, ((float) color.getBlue()) / 255, alpha);
String r = Integer.toHexString(c.getRGB());
return '#' + r.substring(2) + r.substring(0, 2);
}
}

BIN
src/main/java/com/fr/plugin/easyslides/images/display.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
src/main/java/com/fr/plugin/easyslides/images/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

13
src/main/java/com/fr/plugin/easyslides/local/easyslides.properties

@ -0,0 +1,13 @@
Plugin-EasySlides_Widget=EasySlides
Plugin-EasySlides_Advanced=Advanced
Plugin-EasySlides_DataSource=DataSource
Plugin-EasySlides_ColorBackground=BackgroundColor
Plugin-EasySlides_AutoPlay=AutoPlay
Plugin-EasySlides_AutoPlayTime=APInterTime
Plugin-EasySlides_SlideStyle=SlideStyle
Plugin-EasySlides_ToolBar=ToolBar
Plugin-EasySlides_ProgressBar=ProgressBar
Plugin-EasySlides_Progress=Progress
Plugin-EasySlides_Style1=horizontal slide
Plugin-EasySlides_Style2=vertical slide
Plugin-EasySlides_Style3=far away slide

13
src/main/java/com/fr/plugin/easyslides/local/easyslides_en_US.properties

@ -0,0 +1,13 @@
Plugin-EasySlides_Widget=EasySlides
Plugin-EasySlides_Advanced=Advanced
Plugin-EasySlides_DataSource=DataSource
Plugin-EasySlides_ColorBackground=BackgroundColor
Plugin-EasySlides_AutoPlay=AutoPlay
Plugin-EasySlides_AutoPlayTime=APInterTime
Plugin-EasySlides_SlideStyle=SlideStyle
Plugin-EasySlides_ToolBar=ToolBar
Plugin-EasySlides_ProgressBar=ProgressBar
Plugin-EasySlides_Progress=Progress
Plugin-EasySlides_Style1=horizontal slide
Plugin-EasySlides_Style2=vertical slide
Plugin-EasySlides_Style3=far away slide

13
src/main/java/com/fr/plugin/easyslides/local/easyslides_zh_CN.properties

@ -0,0 +1,13 @@
Plugin-EasySlides_Widget=\u8D85\u9177\u5E7B\u706F\u7247
Plugin-EasySlides_Advanced=\u9AD8\u7EA7
Plugin-EasySlides_DataSource=\u6570\u636E\u6E90
Plugin-EasySlides_ColorBackground=\u80CC\u666F\u8272
Plugin-EasySlides_AutoPlay=\u81EA\u52A8\u64AD\u653E
Plugin-EasySlides_AutoPlayTime=\u64AD\u653E\u95F4\u9694\u65F6\u95F4
Plugin-EasySlides_SlideStyle=\u5E7B\u706F\u7247\u6837\u5F0F
Plugin-EasySlides_ToolBar=\u5DE5\u5177\u6761
Plugin-EasySlides_ProgressBar=\u8FDB\u5EA6\u6761
Plugin-EasySlides_Progress=\u8FDB\u5EA6
Plugin-EasySlides_Style1=\u6C34\u5E73\u79FB\u52A8
Plugin-EasySlides_Style2=\u4E0A\u4E0B\u79FB\u52A8
Plugin-EasySlides_Style3=\u8FDC\u8FD1\u79FB\u52A8

21
src/main/java/com/fr/plugin/easyslides/slidestyles/FarAwayStyle.java

@ -0,0 +1,21 @@
package com.fr.plugin.easyslides.slidestyles;
import java.util.List;
/**
* 远近移动
*/
public class FarAwayStyle extends SlideStyle {
@Override
protected String buildContents(List<String> contents) {
StringBuilder slides = new StringBuilder();
String divStr = "<div id=%s class=\"step slide\" data-x=\"0\" data-y=\"0\" data-z=%s>\n%s\n</div>";
for (int i = 0; i < contents.size(); i++) {
String id = "slide" + i;
String dataZ = String.valueOf(-i * 1500);
slides.append(String.format(divStr, id, dataZ, contents.get(i)));
slides.append('\n');
}
return slides.toString();
}
}

21
src/main/java/com/fr/plugin/easyslides/slidestyles/HorizontalStyle.java

@ -0,0 +1,21 @@
package com.fr.plugin.easyslides.slidestyles;
import java.util.List;
/**
* 垂直移动
*/
public class HorizontalStyle extends SlideStyle {
@Override
protected String buildContents(List<String> contents) {
StringBuilder slides = new StringBuilder();
String divStr = "<div id=%s class=\"step slide\" data-x=\"0\" data-y=%s>\n%s\n</div>";
for (int i = 0; i < contents.size(); i++) {
String id = "slide" + i;
String dataY = String.valueOf(i * 900);
slides.append(String.format(divStr, id, dataY, contents.get(i)));
slides.append('\n');
}
return slides.toString();
}
}

51
src/main/java/com/fr/plugin/easyslides/slidestyles/SlideStyle.java

@ -0,0 +1,51 @@
package com.fr.plugin.easyslides.slidestyles;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.easyslides.EasySlidesWidget;
import java.util.List;
public abstract class SlideStyle {
public final String buildHtml(final EasySlidesWidget widget, List<String> contents) {
if (contents == null || contents.size() <= 0) {
FineLoggerFactory.getLogger().info("There are no any texts in your dataset!");
return null;
}
StringBuilder impressStr = new StringBuilder("<div id=\"impress\" class=\"slide-body\">\n%s\n</div>");
String scriptStr = "<script>impress().init();</script>";
if (widget.isAutoPlay() && widget.getAutoPlayIntervalTime() > 0) {
String autoplayAttr = String.format("data-autoplay=%s", String.valueOf(widget.getAutoPlayIntervalTime()));
impressStr.insert(impressStr.indexOf(">"), " " + autoplayAttr);
}
StringBuilder plugins = new StringBuilder();
if (widget.isToolBar()) {
plugins.append("impress_toolbar(document);").append('\n');
}
if (widget.isProgressBar() || widget.isProgress()) {
plugins.append("impress_progress(document);").append('\n');
}
if (plugins.length() > 0) {
scriptStr = "<script>" + plugins.toString() + "impress().init();</script>";
}
String contentsHtml = buildContents(contents);
return (String.format(impressStr.toString(), contentsHtml) + scriptStr);
}
protected abstract String buildContents(List<String> contents);
/* public static void main(String[] param) {
String impressStr = "<div id=\"impress\" class=\"slide-body\" data-autoplay=\"3\">\n%s\n<script>impress().init();</script>";
String autoplay = String.format("data-autoplay=%s", String.valueOf(5));
StringBuilder sb = new StringBuilder(impressStr);
String r = sb.insert(sb.indexOf(">"), " " + autoplay).toString();
System.out.println(r);
}
*/
}

16
src/main/java/com/fr/plugin/easyslides/slidestyles/StyleFactory.java

@ -0,0 +1,16 @@
package com.fr.plugin.easyslides.slidestyles;
import com.fr.general.Inter;
public class StyleFactory {
public static SlideStyle createStyle(String type) {
if (Inter.getLocText("Plugin-EasySlides_Style1").equalsIgnoreCase(type)) {
return new VerticalStyle();
} else if (Inter.getLocText("Plugin-EasySlides_Style2").equalsIgnoreCase(type)) {
return new HorizontalStyle();
} else if (Inter.getLocText("Plugin-EasySlides_Style3").equalsIgnoreCase(type)) {
return new FarAwayStyle();
}
return null;
}
}

18
src/main/java/com/fr/plugin/easyslides/slidestyles/VerticalStyle.java

@ -0,0 +1,18 @@
package com.fr.plugin.easyslides.slidestyles;
import java.util.List;
public class VerticalStyle extends SlideStyle {
@Override
protected String buildContents(List<String> contents) {
StringBuilder slides = new StringBuilder();
String divStr = "<div id=%s class=\"step slide\" data-x=%s data-y=\"0\">\n%s\n</div>";
for (int i = 0; i < contents.size(); i++) {
String id = "slide" + i;
String dataX = String.valueOf(i * 1000);
slides.append(String.format(divStr, id, dataX, contents.get(i)));
slides.append('\n');
}
return slides.toString();
}
}

28
src/main/java/com/fr/plugin/easyslides/ui/AutoPlayEditor.java

@ -0,0 +1,28 @@
package com.fr.plugin.easyslides.ui;
import com.fr.design.Exception.ValidationException;
import com.fr.design.mainframe.widget.editors.AbstractPropertyEditor;
import java.awt.*;
public class AutoPlayEditor extends AbstractPropertyEditor {
@Override
public void validateValue() throws ValidationException {
}
@Override
public void setValue(Object value) {
}
@Override
public Object getValue() {
return null;
}
@Override
public Component getCustomEditor() {
return null;
}
}

87
src/main/java/com/fr/plugin/easyslides/ui/EasySlidesWidgetUI.java

@ -0,0 +1,87 @@
package com.fr.plugin.easyslides.ui;
import com.fr.design.designer.creator.CRPropertyDescriptor;
import com.fr.design.designer.creator.XWidgetCreator;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.widget.editors.*;
import com.fr.form.ui.Widget;
import com.fr.general.IOUtils;
import com.fr.general.Inter;
import com.fr.plugin.easyslides.ui.SlidesDataSourceEditor;
import com.fr.stable.ArrayUtils;
import javax.swing.*;
import java.awt.*;
import java.beans.IntrospectionException;
import static com.fr.plugin.easyslides.EasySlidesWidget.*;
public class EasySlidesWidgetUI extends XWidgetCreator {
private UITextField textField;
public EasySlidesWidgetUI(Widget widget, Dimension dimension) {
super(widget, dimension);
}
@Override
protected JComponent initEditor() {
if (this.editor == null) {
this.editor = FRGUIPaneFactory.createBorderLayout_S_Pane();
UILabel label = new UILabel();
label.setIcon(IOUtils.readIcon("/com/fr/plugin/easyslides/images/display.png"));
label.setHorizontalAlignment(0);
label.setVerticalAlignment(0);
this.editor.add(label, "Center");
this.textField = new UITextField(5);
this.textField.setOpaque(false);
this.editor.add(this.textField, "South");
this.editor.setBackground(Color.WHITE);
}
return this.editor;
}
@Override
public String getIconPath() {
return "/com/fr/plugin/easyslides/images/icon.png";
}
public CRPropertyDescriptor[] supportedDescriptor() throws IntrospectionException {
String advanced = Inter.getLocText("Plugin-EasySlides_Advanced");
return ArrayUtils.addAll(super.supportedDescriptor(),
(new CRPropertyDescriptor("widgetValue", this.data.getClass()))
.setI18NName(Inter.getLocText("Plugin-EasySlides_DataSource"))
.setEditorClass(SlidesDataSourceEditor.class)
.putKeyValue("category", advanced),
(new CRPropertyDescriptor(SLIDE_STYLE, this.data.getClass()))
.setI18NName(Inter.getLocText("Plugin-EasySlides_SlideStyle"))
.setEditorClass(SlideStyleEditor.class)
.putKeyValue("category", advanced),
(new CRPropertyDescriptor(BACKGROUND_COLOR, this.data.getClass()))
.setI18NName(Inter.getLocText("Plugin-EasySlides_ColorBackground"))
.setEditorClass(ColorEditor.class)
.putKeyValue("category", advanced),
(new CRPropertyDescriptor(AUTO_PLAY, this.data.getClass()))
.setI18NName(Inter.getLocText("Plugin-EasySlides_AutoPlay"))
.setEditorClass(BooleanEditor.class)
.putKeyValue("category", advanced),
(new CRPropertyDescriptor(AUTO_PLAY_INTERVAL_TIME, this.data.getClass()))
.setI18NName(Inter.getLocText("Plugin-EasySlides_AutoPlayTime"))
.setEditorClass(IntegerPropertyEditor.class)
.putKeyValue("category", advanced),
(new CRPropertyDescriptor(TOOLBAR, this.data.getClass()))
.setI18NName(Inter.getLocText("Plugin-EasySlides_ToolBar"))
.setEditorClass(BooleanEditor.class)
.putKeyValue("category", advanced),
(new CRPropertyDescriptor(PROGRESSBAR, this.data.getClass()))
.setI18NName(Inter.getLocText("Plugin-EasySlides_ProgressBar"))
.setEditorClass(BooleanEditor.class)
.putKeyValue("category", advanced),
(new CRPropertyDescriptor(PROGRESS, this.data.getClass()))
.setI18NName(Inter.getLocText("Plugin-EasySlides_Progress"))
.setEditorClass(BooleanEditor.class)
.putKeyValue("category", advanced)
);
}
}

23
src/main/java/com/fr/plugin/easyslides/ui/SlideStyleEditor.java

@ -0,0 +1,23 @@
package com.fr.plugin.easyslides.ui;
import com.fr.design.mainframe.widget.editors.ComboEditor;
import com.fr.general.Inter;
import javax.swing.*;
import java.util.Vector;
public class SlideStyleEditor extends ComboEditor {
public static final String DEFAULT_STYLE = Inter.getLocText("Plugin-EasySlides_Style1");
public SlideStyleEditor() {
}
@Override
public ComboBoxModel model() {
Vector<String> vector = new Vector();
for (int i = 0; i < 3; i++) {
vector.add(Inter.getLocText("Plugin-EasySlides_Style" + (i + 1)));
}
return new DefaultComboBoxModel(vector);
}
}

50
src/main/java/com/fr/plugin/easyslides/ui/SlidesDataSourceEditor.java

@ -0,0 +1,50 @@
package com.fr.plugin.easyslides.ui;
import com.fr.design.Exception.ValidationException;
import com.fr.design.editor.ValueEditorPane;
import com.fr.design.editor.editor.Editor;
import com.fr.design.mainframe.widget.editors.AbstractPropertyEditor;
import com.fr.design.mainframe.widget.editors.DataBindingEditor;
import com.fr.form.ui.WidgetValue;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.Component;
public class SlidesDataSourceEditor extends AbstractPropertyEditor {
private ValueEditorPane pane;
public SlidesDataSourceEditor() {
Editor editor = new DataBindingEditor();
editor.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
SlidesDataSourceEditor.this.firePropertyChanged();
}
});
pane = new ValueEditorPane(new Editor[]{editor});
}
@Override
public void validateValue() throws ValidationException {
}
@Override
public void setValue(Object value) {
if (value != null) {
pane.populate(((WidgetValue) value).getValue());
}
}
@Override
public Object getValue() {
return new WidgetValue(pane.update());
}
@Override
public Component getCustomEditor() {
return pane;
}
}

810
src/main/java/com/fr/plugin/easyslides/web/impress-default.css

@ -0,0 +1,810 @@
/*
So you like the style of impress.js demo?
Or maybe you are just curious how it was done?
You couldn't find a better place to find out!
Welcome to the stylesheet impress.js demo presentation.
Please remember that it is not meant to be a part of impress.js and is
not required by impress.js.
I expect that anyone creating a presentation for impress.js would create
their own set of styles.
But feel free to read through it and learn how to get the most of what
impress.js provides.
And let me be your guide.
Shall we begin?
*/
/*
We start with a good ol' reset.
That's the one by Eric Meyer http://meyerweb.com/eric/tools/css/reset/
You can probably argue if it is needed here, or not, but for sure it
doesn't do any harm and gives us a fresh start.
*/
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;
}
/* HTML5 display-role reset for older browsers */
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;
}
/*
Now here is when interesting things start to appear.
We set up <body> styles with default font and nice gradient in the background.
And yes, there is a lot of repetition there because of -prefixes but we don't
want to leave anybody behind.
*/
/*body {
font-family: 'PT Sans', sans-serif;
min-height: 740px;
background: rgb(215, 215, 215);
background: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 500, from(rgb(240, 240, 240)), to(rgb(190, 190, 190)));
background: -webkit-radial-gradient(rgb(240, 240, 240), rgb(190, 190, 190));
background: -moz-radial-gradient(rgb(240, 240, 240), rgb(190, 190, 190));
background: -ms-radial-gradient(rgb(240, 240, 240), rgb(190, 190, 190));
background: -o-radial-gradient(rgb(240, 240, 240), rgb(190, 190, 190));
background: radial-gradient(rgb(240, 240, 240), rgb(190, 190, 190));
}*/
.slide-body {
font-family: 'PT Sans', sans-serif;
min-height: 740px;
background: rgb(215, 215, 215);
background: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 500, from(rgb(240, 240, 240)), to(rgb(190, 190, 190)));
background: -webkit-radial-gradient(rgb(240, 240, 240), rgb(190, 190, 190));
background: -moz-radial-gradient(rgb(240, 240, 240), rgb(190, 190, 190));
background: -ms-radial-gradient(rgb(240, 240, 240), rgb(190, 190, 190));
background: -o-radial-gradient(rgb(240, 240, 240), rgb(190, 190, 190));
background: radial-gradient(rgb(240, 240, 240), rgb(190, 190, 190));
}
/*
Now let's bring some text styles back ...
*/
b, strong { font-weight: bold }
i, em { font-style: italic }
/*
... and give links a nice look.
*/
a {
color: inherit;
text-decoration: none;
padding: 0 0.1em;
background: rgba(255,255,255,0.5);
text-shadow: -1px -1px 2px rgba(100,100,100,0.9);
border-radius: 0.2em;
-webkit-transition: 0.5s;
-moz-transition: 0.5s;
-ms-transition: 0.5s;
-o-transition: 0.5s;
transition: 0.5s;
}
a:hover,
a:focus {
background: rgba(255,255,255,1);
text-shadow: -1px -1px 2px rgba(100,100,100,0.5);
}
/*
Because the main point behind the impress.js demo is to demo impress.js
we display a fallback message for users with browsers that don't support
all the features required by it.
All of the content will be still fully accessible for them, but I want
them to know that they are missing something - that's what the demo is
about, isn't it?
And then we hide the message, when support is detected in the browser.
*/
.fallback-message {
font-family: sans-serif;
line-height: 1.3;
width: 780px;
padding: 10px 10px 0;
margin: 20px auto;
border: 1px solid #E4C652;
border-radius: 10px;
background: #EEDC94;
}
.fallback-message p {
margin-bottom: 10px;
}
.impress-supported .fallback-message {
display: none;
}
/*
Now let's style the presentation steps.
We start with basics to make sure it displays correctly in everywhere ...
*/
.step {
position: relative;
width: 900px;
padding: 40px;
margin: 20px auto;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
font-family: 'PT Serif', georgia, serif;
font-size: 48px;
line-height: 1.5;
}
/*
... and we enhance the styles for impress.js.
Basically we remove the margin and make inactive steps a little bit transparent.
*/
.impress-enabled .step {
margin: 0;
opacity: 0.3;
-webkit-transition: opacity 1s;
-moz-transition: opacity 1s;
-ms-transition: opacity 1s;
-o-transition: opacity 1s;
transition: opacity 1s;
}
.impress-enabled .step.active { opacity: 1 }
/*
These 'slide' step styles were heavily inspired by HTML5 Slides:
http://html5slides.googlecode.com/svn/trunk/styles.css
;)
They cover everything what you see on first three steps of the demo.
*/
.slide {
display: block;
width: 900px;
height: 700px;
padding: 40px 60px;
background-color: white;
border: 1px solid rgba(0, 0, 0, .3);
border-radius: 10px;
box-shadow: 0 2px 6px rgba(0, 0, 0, .1);
color: rgb(102, 102, 102);
text-shadow: 0 2px 2px rgba(0, 0, 0, .1);
font-family: 'Open Sans', Arial, sans-serif;
font-size: 30px;
line-height: 36px;
letter-spacing: -1px;
}
.slide q {
display: block;
font-size: 50px;
line-height: 72px;
margin-top: 100px;
}
.slide q strong {
white-space: nowrap;
}
/*
And now we start to style each step separately.
I agree that this may be not the most efficient, object-oriented and
scalable way of styling, but most of steps have quite a custom look
and typography tricks here and there, so they had to be styles separately.
First is the title step with a big <h1> (no room for padding) and some
3D positioning along Z axis.
*/
#title {
padding: 0;
}
#title .try {
font-size: 64px;
position: absolute;
top: -0.5em;
left: 1.5em;
-webkit-transform: translateZ(20px);
-moz-transform: translateZ(20px);
-ms-transform: translateZ(20px);
-o-transform: translateZ(20px);
transform: translateZ(20px);
}
#title h1 {
font-size: 190px;
-webkit-transform: translateZ(50px);
-moz-transform: translateZ(50px);
-ms-transform: translateZ(50px);
-o-transform: translateZ(50px);
transform: translateZ(50px);
}
#title .footnote {
font-size: 32px;
}
/*
Second step is nothing special, just a text with a link, so it doesn't need
any special styling.
Let's move to 'big thoughts' with centered text and custom font sizes.
*/
#big {
width: 600px;
text-align: center;
font-size: 60px;
line-height: 1;
}
#big b {
display: block;
font-size: 250px;
line-height: 250px;
}
#big .thoughts {
font-size: 90px;
line-height: 150px;
}
/*
'Tiny ideas' just need some tiny styling.
*/
#tiny {
width: 500px;
text-align: center;
}
/*
This step has some animated text ...
*/
#ing { width: 500px }
/*
... so we define display to `inline-block` to enable transforms and
transition duration to 0.5s ...
*/
#ing b {
display: inline-block;
-webkit-transition: 0.5s;
-moz-transition: 0.5s;
-ms-transition: 0.5s;
-o-transition: 0.5s;
transition: 0.5s;
}
/*
... and we want 'positioning` word to move up a bit when the step gets
`present` class ...
*/
#ing.present .positioning {
-webkit-transform: translateY(-10px);
-moz-transform: translateY(-10px);
-ms-transform: translateY(-10px);
-o-transform: translateY(-10px);
transform: translateY(-10px);
}
/*
... 'rotating' to rotate quater of a second later ...
*/
#ing.present .rotating {
-webkit-transform: rotate(-10deg);
-moz-transform: rotate(-10deg);
-ms-transform: rotate(-10deg);
-o-transform: rotate(-10deg);
transform: rotate(-10deg);
-webkit-transition-delay: 0.25s;
-moz-transition-delay: 0.25s;
-ms-transition-delay: 0.25s;
-o-transition-delay: 0.25s;
transition-delay: 0.25s;
}
/*
... and 'scaling' to scale down after another quater of a second.
*/
#ing.present .scaling {
-webkit-transform: scale(0.7);
-moz-transform: scale(0.7);
-ms-transform: scale(0.7);
-o-transform: scale(0.7);
transform: scale(0.7);
-webkit-transition-delay: 0.5s;
-moz-transition-delay: 0.5s;
-ms-transition-delay: 0.5s;
-o-transition-delay: 0.5s;
transition-delay: 0.5s;
}
/*
The 'imagination' step is again some boring font-sizing.
*/
#imagination {
width: 600px;
}
#imagination .imagination {
font-size: 78px;
}
/*
There is nothing really special about 'use the source, Luke' step, too,
except maybe of the Yoda background.
As you can see below I've 'hard-coded' it in data URL.
That's not the best way to serve images, but because that's just this one
I decided it will be OK to have it this way.
Just make sure you don't blindly copy this approach.
*/
#source {
width: 700px;
padding-bottom: 300px;
/* Yoda Icon :: Pixel Art from Star Wars http://www.pixeljoint.com/pixelart/1423.htm */
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARgAAAEYCAMAAACwUBm+AAAAAXNSR0IArs4c6QAAAKtQTFRFsAAAvbWSLUUrLEQqY1s8UYJMqJ1vNTEgOiIdIzYhjIFVLhsXZ6lgSEIsP2U8JhcCVzMsSXZEgXdOO145XJdWOl03LzAYMk4vSXNExr+hwcuxRTs1Qmk+RW9Am49eFRANQz4pUoNMQWc+OSMDTz0wLBsCNVMxa2NBOyUDUoNNSnlEWo9VRGxAVzYFl6tXCggHbLNmMUIcHhwTXkk5f3VNRT8wUT8xAAAACQocRBWFFwAAAAF0Uk5TAEDm2GYAAAPCSURBVHja7d3JctNAFIZRMwRCCGEmzPM8z/D+T8bu/ptbXXJFdij5fMt2Wuo+2UgqxVmtttq5WVotLzBgwIABAwYMGDCn0qVqbo69psPqVpWx+1XG5iaavF8wYMCAAQMGDBgwi4DJ6Y6qkxB1HNlcN3a92gbR5P2CAQMGDBgwYMCAWSxMlrU+UY5yu2l9okfV4bAxUVbf7TJnAwMGDBgwYMCAAbMLMHeqbGR82Zy+VR1Ht81nVca6R+UdTLaU24Ruzd3qM/e4yjnAgAEDBgwYMGDA7AJMd1l/3NRdVGcj3eX/2WEhCmDGxnM7yqygu8XIPjJj8iN/MGDAgAEDBgwYMAuDGb8q0RGlLCHLv1t9qDKWn3vdNHVuEI6HPaxO9Jo3GDBgwIABAwYMmIXBdC9ShGgMk+XnkXUeuGcsP/e1+lhNnZsL/G5Vs3OAAQMGDBgwYMCAWSxMR3SzOmraG5atdy9wZKzb+vg16qyqe2FltbnAgAEDBgwYMGDALAxmTJSuN3WA76rnVca6GTnemGN1WoEBAwYMGDBgwIBZGMxUomy4+xO899V4LAg5Xnc2MGDAgAEDBgwYMGA218Wq+2K1LDqvY9xZu8zN8fICdM6btYABAwYMGDBgwIABMzfH0+pGU5afze2tXebmeAfVz+p8BQYMGDBgwIABAwbMPBzZ+oWmfJrln1273FhkbHzee9WWbw7AgAEDBgwYMGDALAKm43hcdctKgblcPamOhuXnXlY5Xs6bsW4FGyQCAwYMGDBgwIABswiYMceZKgvMo+h8mrHLTdn676rj+FEFoTtHd8MwOxEYMGDAgAEDBgyYRcBM5UhXqiymW3R3c9ARhWO/OmjqfjVZy+xEYMCAAQMGDBgwYBYG073OnCV0RFNhMhaOa9WfKmOB6XjHMN1tQmaAAQMGDBgwYMCA2VWY7vXjz1U4croAzgPztwIDBgwYMGDAgAEDZhswh035NBw59Dww3RgYMGDAgAEDBgwYMJuD6f4tXT7NUqfCdBvZLkxXdgQGDBgwYMCAAQNmt2DGj8WzwAfV/w7T/aq7mxwwYMCAAQMGDBgwuwqTOo7uTwTngflSzQ3TdaJvAwEDBgwYMGDAgAED5gSvgbyo5oHZ4Pc+gwEDBgwYMGDAgAEzhOm+5G0qTGaAAQMGDBgwYMCAAXNaMOcnls3tNwWm+zRzp54NDBgwYMCAAQMGDJh5YNL36k1TLuGvVq+qnKMbS5n7tulT9asCAwYMGDBgwIABA2ZumKuztLnjgQEDBgwYMGDAgNl5mH/4/ltKA6vBNAAAAABJRU5ErkJggg==);
background-position: bottom right;
background-repeat: no-repeat;
}
#source q {
font-size: 60px;
}
/*
And the "it's in 3D" step again brings some 3D typography - just for fun.
Because we want to position <span> elements in 3D we set transform-style to
`preserve-3d` on the paragraph.
It is not needed by webkit browsers, but it is in Firefox. It's hard to say
which behaviour is correct as 3D transforms spec is not very clear about it.
*/
#its-in-3d p {
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d; /* Y U need this Firefox?! */
-ms-transform-style: preserve-3d;
-o-transform-style: preserve-3d;
transform-style: preserve-3d;
}
/*
Below we position each word separately along Z axis and we want it to transition
to default position in 0.5s when the step gets `present` class.
Quite a simple idea, but lot's of styles and prefixes.
*/
#its-in-3d span,
#its-in-3d b {
display: inline-block;
-webkit-transform: translateZ(40px);
-moz-transform: translateZ(40px);
-ms-transform: translateZ(40px);
-o-transform: translateZ(40px);
transform: translateZ(40px);
-webkit-transition: 0.5s;
-moz-transition: 0.5s;
-ms-transition: 0.5s;
-o-transition: 0.5s;
transition: 0.5s;
}
#its-in-3d .have {
-webkit-transform: translateZ(-40px);
-moz-transform: translateZ(-40px);
-ms-transform: translateZ(-40px);
-o-transform: translateZ(-40px);
transform: translateZ(-40px);
}
#its-in-3d .you {
-webkit-transform: translateZ(20px);
-moz-transform: translateZ(20px);
-ms-transform: translateZ(20px);
-o-transform: translateZ(20px);
transform: translateZ(20px);
}
#its-in-3d .noticed {
-webkit-transform: translateZ(-40px);
-moz-transform: translateZ(-40px);
-ms-transform: translateZ(-40px);
-o-transform: translateZ(-40px);
transform: translateZ(-40px);
}
#its-in-3d .its {
-webkit-transform: translateZ(60px);
-moz-transform: translateZ(60px);
-ms-transform: translateZ(60px);
-o-transform: translateZ(60px);
transform: translateZ(60px);
}
#its-in-3d .in {
-webkit-transform: translateZ(-10px);
-moz-transform: translateZ(-10px);
-ms-transform: translateZ(-10px);
-o-transform: translateZ(-10px);
transform: translateZ(-10px);
}
#its-in-3d .footnote {
font-size: 32px;
-webkit-transform: translateZ(-10px);
-moz-transform: translateZ(-10px);
-ms-transform: translateZ(-10px);
-o-transform: translateZ(-10px);
transform: translateZ(-10px);
}
#its-in-3d.present span,
#its-in-3d.present b {
-webkit-transform: translateZ(0px);
-moz-transform: translateZ(0px);
-ms-transform: translateZ(0px);
-o-transform: translateZ(0px);
transform: translateZ(0px);
}
/*
The last step is an overview.
There is no content in it, so we make sure it's not visible because we want
to be able to click on other steps.
*/
#overview { display: none }
/*
We also make other steps visible and give them a pointer cursor using the
`impress-on-` class.
*/
.impress-on-overview .step {
opacity: 1;
cursor: pointer;
}
/*
Now, when we have all the steps styled let's give users a hint how to navigate
around the presentation.
The best way to do this would be to use JavaScript, show a delayed hint for a
first time users, then hide it and store a status in cookie or localStorage...
But I wanted to have some CSS fun and avoid additional scripting...
Let me explain it first, so maybe the transition magic will be more readable
when you read the code.
First of all I wanted the hint to appear only when user is idle for a while.
You can't detect the 'idle' state in CSS, but I delayed a appearing of the
hint by 5s using transition-delay.
You also can't detect in CSS if the user is a first-time visitor, so I had to
make an assumption that I'll only show the hint on the first step. And when
the step is changed hide the hint, because I can assume that user already
knows how to navigate.
To summarize it - hint is shown when the user is on the first step for longer
than 5 seconds.
The other problem I had was caused by the fact that I wanted the hint to fade
in and out. It can be easily achieved by transitioning the opacity property.
But that also meant that the hint was always on the screen, even if totally
transparent. It covered part of the screen and you couldn't correctly clicked
through it.
Unfortunately you cannot transition between display `block` and `none` in pure
CSS, so I needed a way to not only fade out the hint but also move it out of
the screen.
I solved this problem by positioning the hint below the bottom of the screen
with CSS transform and moving it up to show it. But I also didn't want this move
to be visible. I wanted the hint only to fade in and out visually, so I delayed
the fade in transition, so it starts when the hint is already in its correct
position on the screen.
I know, it sounds complicated ... maybe it would be easier with the code?
*/
.hint {
/*
We hide the hint until presentation is started and from browsers not supporting
impress.js, as they will have a linear scrollable view ...
*/
display: none;
/*
... and give it some fixed position and nice styles.
*/
position: fixed;
left: 0;
right: 0;
bottom: 200px;
background: rgba(0,0,0,0.5);
color: #EEE;
text-align: center;
font-size: 50px;
padding: 20px;
z-index: 100;
/*
By default we don't want the hint to be visible, so we make it transparent ...
*/
opacity: 0;
/*
... and position it below the bottom of the screen (relative to it's fixed position)
*/
-webkit-transform: translateY(400px);
-moz-transform: translateY(400px);
-ms-transform: translateY(400px);
-o-transform: translateY(400px);
transform: translateY(400px);
/*
Now let's imagine that the hint is visible and we want to fade it out and move out
of the screen.
So we define the transition on the opacity property with 1s duration and another
transition on transform property delayed by 1s so it will happen after the fade out
on opacity finished.
This way user will not see the hint moving down.
*/
-webkit-transition: opacity 1s, -webkit-transform 0.5s 1s;
-moz-transition: opacity 1s, -moz-transform 0.5s 1s;
-ms-transition: opacity 1s, -ms-transform 0.5s 1s;
-o-transition: opacity 1s, -o-transform 0.5s 1s;
transition: opacity 1s, transform 0.5s 1s;
}
/*
Now we 'enable' the hint when presentation is initialized ...
*/
.impress-enabled .hint { display: block }
/*
... and we will show it when the first step (with id 'bored') is active.
*/
.impress-on-bored .hint {
/*
We remove the transparency and position the hint in its default fixed
position.
*/
opacity: 1;
-webkit-transform: translateY(0px);
-moz-transform: translateY(0px);
-ms-transform: translateY(0px);
-o-transform: translateY(0px);
transform: translateY(0px);
/*
Now for fade in transition we have the oposite situation from the one
above.
First after 4.5s delay we animate the transform property to move the hint
into its correct position and after that we fade it in with opacity
transition.
*/
-webkit-transition: opacity 1s 5s, -webkit-transform 0.5s 4.5s;
-moz-transition: opacity 1s 5s, -moz-transform 0.5s 4.5s;
-ms-transition: opacity 1s 5s, -ms-transform 0.5s 4.5s;
-o-transition: opacity 1s 5s, -o-transform 0.5s 4.5s;
transition: opacity 1s 5s, transform 0.5s 4.5s;
}
/*
And as the last thing there is a workaround for quite strange bug.
It happens a lot in Chrome. I don't remember if I've seen it in Firefox.
Sometimes the element positioned in 3D (especially when it's moved back
along Z axis) is not clickable, because it falls 'behind' the <body>
element.
To prevent this, I decided to make <body> non clickable by setting
pointer-events property to `none` value.
Value if this property is inherited, so to make everything else clickable
I bring it back on the #impress element.
If you want to know more about `pointer-events` here are some docs:
https://developer.mozilla.org/en/CSS/pointer-events
There is one very important thing to notice about this workaround - it makes
everything 'unclickable' except what's in #impress element.
So use it wisely ... or don't use at all.
*/
.impress-enabled { pointer-events: none }
.impress-enabled #impress { pointer-events: auto }
/*
There is one funny thing I just realized.
Thanks to this workaround above everything except #impress element is invisible
for click events. That means that the hint element is also not clickable.
So basically all of this transforms and delayed transitions trickery was probably
not needed at all...
But it was fun to learn about it, wasn't it?
*/
/*
That's all I have for you in this file.
Thanks for reading. I hope you enjoyed it at least as much as I enjoyed writing it
for you.
*/
/******************* PLUGINS *************************************************************/
/*
This version of impress.js supports plugins, and in particular, a UI toolbar
plugin that allows easy navigation between steps and autoplay.
*/
.impress-enabled div#impress-toolbar {
position: fixed;
right: 1px;
bottom: 1px;
opacity: 0.6;
z-index: 10;
}
.impress-enabled div#impress-toolbar > span {
margin-right: 10px;
}
/*
With help from the mouse-timeout plugin, we can hide the toolbar and
have it show only when you move/click/touch the mouse.
*/
body.impress-mouse-timeout div#impress-toolbar {
display: none;
}
/*
In fact, we can hide the mouse cursor itself too, when mouse isn't used.
*/
body.impress-mouse-timeout {
cursor: none;
}
/* Progress bar */
.impress-progressbar {
position: absolute;
right: 118px;
bottom: 1px;
left: 118px;
border-radius: 7px;
border: 2px solid rgba(100, 100, 100, 0.2);
}
.impress-progressbar DIV {
width: 0;
height: 2px;
border-radius: 5px;
background: rgba(75, 75, 75, 0.4);
transition: width 1s linear;
}
.impress-progress {
position: absolute;
left: 59px;
bottom: 1px;
text-align: left;
font-size: 10pt;
opacity: 0.6;
}
/* Help popup plugin */
.impress-enabled #impress-help {
background: none repeat scroll 0 0 rgba(0, 0, 0, 0.5);
color: #EEEEEE;
font-size: 80%;
position: fixed;
left: 2em;
bottom: 2em;
width: 24em;
border-radius: 1em;
padding: 1em;
text-align: center;
z-index: 100;
font-family: Verdana, Arial, Sans;
}
.impress-enabled #impress-help td {
padding-left: 1em;
padding-right: 1em;
}
/* Substep plugin */
#impress .step .substep {
opacity: 0;
}
#impress .step .substep.substep-visible {
opacity: 1;
transition: opacity 1s;
}
.impress-enabled { pointer-events: none }
.impress-enabled #impress { pointer-events: auto }
.impress-enabled #impress-toolbar { pointer-events: auto }
.impress-enabled #impress-console-button { pointer-events: auto }

918
src/main/java/com/fr/plugin/easyslides/web/impress-main.js

@ -0,0 +1,918 @@
// This file was automatically generated from files in src/ directory.
/*! Licensed under MIT License - http://github.com/impress/impress.js */
/**
* impress.js
*
* impress.js is a presentation tool based on the power of CSS3 transforms and transitions
* in modern browsers and inspired by the idea behind prezi.com.
*
*
* Copyright 2011-2012 Bartek Szopka (@bartaz), 2016-2018 Henrik Ingo (@henrikingo)
*
* Released under the MIT License.
*
* ------------------------------------------------
* author: Bartek Szopka, Henrik Ingo
* version: 1.0.0
* url: http://impress.js.org
* source: http://github.com/impress/impress.js/
*/
// You are one of those who like to know how things work inside?
// Let me show you the cogs that make impress.js run...
( function( document, window ) {
"use strict";
var lib;
// HELPER FUNCTIONS
// `pfx` is a function that takes a standard CSS property name as a parameter
// and returns it's prefixed version valid for current browser it runs in.
// The code is heavily inspired by Modernizr http://www.modernizr.com/
var pfx = ( function() {
var style = document.createElement( "dummy" ).style,
prefixes = "Webkit Moz O ms Khtml".split( " " ),
memory = {};
return function( prop ) {
if ( typeof memory[ prop ] === "undefined" ) {
var ucProp = prop.charAt( 0 ).toUpperCase() + prop.substr( 1 ),
props = ( prop + " " + prefixes.join( ucProp + " " ) + ucProp ).split( " " );
memory[ prop ] = null;
for ( var i in props ) {
if ( style[ props[ i ] ] !== undefined ) {
memory[ prop ] = props[ i ];
break;
}
}
}
return memory[ prop ];
};
} )();
var validateOrder = function( order, fallback ) {
var validChars = "xyz";
var returnStr = "";
if ( typeof order === "string" ) {
for ( var i in order.split( "" ) ) {
if ( validChars.indexOf( order[ i ] ) >= 0 ) {
returnStr += order[ i ];
// Each of x,y,z can be used only once.
validChars = validChars.split( order[ i ] ).join( "" );
}
}
}
if ( returnStr ) {
return returnStr;
} else if ( fallback !== undefined ) {
return fallback;
} else {
return "xyz";
}
};
// `css` function applies the styles given in `props` object to the element
// given as `el`. It runs all property names through `pfx` function to make
// sure proper prefixed version of the property is used.
var css = function( el, props ) {
var key, pkey;
for ( key in props ) {
if ( props.hasOwnProperty( key ) ) {
pkey = pfx( key );
if ( pkey !== null ) {
el.style[ pkey ] = props[ key ];
}
}
}
return el;
};
// `translate` builds a translate transform string for given data.
var translate = function( t ) {
return " translate3d(" + t.x + "px," + t.y + "px," + t.z + "px) ";
};
// `rotate` builds a rotate transform string for given data.
// By default the rotations are in X Y Z order that can be reverted by passing `true`
// as second parameter.
var rotate = function( r, revert ) {
var order = r.order ? r.order : "xyz";
var css = "";
var axes = order.split( "" );
if ( revert ) {
axes = axes.reverse();
}
for ( var i = 0; i < axes.length; i++ ) {
css += " rotate" + axes[ i ].toUpperCase() + "(" + r[ axes[ i ] ] + "deg)";
}
return css;
};
// `scale` builds a scale transform string for given data.
var scale = function( s ) {
return " scale(" + s + ") ";
};
// `computeWindowScale` counts the scale factor between window size and size
// defined for the presentation in the config.
var computeWindowScale = function( config ) {
var hScale = window.innerHeight / config.height,
wScale = window.innerWidth / config.width,
scale = hScale > wScale ? wScale : hScale;
if ( config.maxScale && scale > config.maxScale ) {
scale = config.maxScale;
}
if ( config.minScale && scale < config.minScale ) {
scale = config.minScale;
}
return scale;
};
// CHECK SUPPORT
var body = document.body;
var impressSupported =
// Browser should support CSS 3D transtorms
( pfx( "perspective" ) !== null ) &&
// And `classList` and `dataset` APIs
( body.classList ) &&
( body.dataset );
if ( !impressSupported ) {
// We can't be sure that `classList` is supported
body.className += " impress-not-supported ";
}
// GLOBALS AND DEFAULTS
// This is where the root elements of all impress.js instances will be kept.
// Yes, this means you can have more than one instance on a page, but I'm not
// sure if it makes any sense in practice ;)
var roots = {};
var preInitPlugins = [];
var preStepLeavePlugins = [];
// Some default config values.
var defaults = {
width: 1024,
height: 768,
maxScale: 1,
minScale: 0,
perspective: 1000,
transitionDuration: 1000
};
// It's just an empty function ... and a useless comment.
var empty = function() { return false; };
// IMPRESS.JS API
// And that's where interesting things will start to happen.
// It's the core `impress` function that returns the impress.js API
// for a presentation based on the element with given id ("impress"
// by default).
var impress = window.impress = function( rootId ) {
// If impress.js is not supported by the browser return a dummy API
// it may not be a perfect solution but we return early and avoid
// running code that may use features not implemented in the browser.
if ( !impressSupported ) {
return {
init: empty,
goto: empty,
prev: empty,
next: empty,
swipe: empty,
tear: empty,
lib: {}
};
}
rootId = rootId || "impress";
// If given root is already initialized just return the API
if ( roots[ "impress-root-" + rootId ] ) {
return roots[ "impress-root-" + rootId ];
}
// The gc library depends on being initialized before we do any changes to DOM.
lib = initLibraries( rootId );
body.classList.remove( "impress-not-supported" );
body.classList.add( "impress-supported" );
// Data of all presentation steps
var stepsData = {};
// Element of currently active step
var activeStep = null;
// Current state (position, rotation and scale) of the presentation
var currentState = null;
// Array of step elements
var steps = null;
// Configuration options
var config = null;
// Scale factor of the browser window
var windowScale = null;
// Root presentation elements
var root = lib.util.byId( rootId );
var canvas = document.createElement( "div" );
var initialized = false;
// STEP EVENTS
//
// There are currently two step events triggered by impress.js
// `impress:stepenter` is triggered when the step is shown on the
// screen (the transition from the previous one is finished) and
// `impress:stepleave` is triggered when the step is left (the
// transition to next step just starts).
// Reference to last entered step
var lastEntered = null;
// `onStepEnter` is called whenever the step element is entered
// but the event is triggered only if the step is different than
// last entered step.
// We sometimes call `goto`, and therefore `onStepEnter`, just to redraw a step, such as
// after screen resize. In this case - more precisely, in any case - we trigger a
// `impress:steprefresh` event.
var onStepEnter = function( step ) {
if ( lastEntered !== step ) {
lib.util.triggerEvent( step, "impress:stepenter" );
lastEntered = step;
}
lib.util.triggerEvent( step, "impress:steprefresh" );
};
// `onStepLeave` is called whenever the currentStep element is left
// but the event is triggered only if the currentStep is the same as
// lastEntered step.
var onStepLeave = function( currentStep, nextStep ) {
if ( lastEntered === currentStep ) {
lib.util.triggerEvent( currentStep, "impress:stepleave", { next: nextStep } );
lastEntered = null;
}
};
// `initStep` initializes given step element by reading data from its
// data attributes and setting correct styles.
var initStep = function( el, idx ) {
var data = el.dataset,
step = {
translate: {
x: lib.util.toNumber( data.x ),
y: lib.util.toNumber( data.y ),
z: lib.util.toNumber( data.z )
},
rotate: {
x: lib.util.toNumber( data.rotateX ),
y: lib.util.toNumber( data.rotateY ),
z: lib.util.toNumber( data.rotateZ || data.rotate ),
order: validateOrder( data.rotateOrder )
},
scale: lib.util.toNumber( data.scale, 1 ),
transitionDuration: lib.util.toNumber(
data.transitionDuration, config.transitionDuration
),
el: el
};
if ( !el.id ) {
el.id = "step-" + ( idx + 1 );
}
stepsData[ "impress-" + el.id ] = step;
css( el, {
position: "absolute",
transform: "translate(-50%,-50%)" +
translate( step.translate ) +
rotate( step.rotate ) +
scale( step.scale ),
transformStyle: "preserve-3d"
} );
};
// Initialize all steps.
// Read the data-* attributes, store in internal stepsData, and render with CSS.
var initAllSteps = function() {
steps = lib.util.$$( ".step", root );
steps.forEach( initStep );
};
// `init` API function that initializes (and runs) the presentation.
var init = function() {
if ( initialized ) { return; }
execPreInitPlugins( root );
// First we set up the viewport for mobile devices.
// For some reason iPad goes nuts when it is not done properly.
var meta = lib.util.$( "meta[name='viewport']" ) || document.createElement( "meta" );
meta.content = "width=device-width, minimum-scale=1, maximum-scale=1, user-scalable=no";
if ( meta.parentNode !== document.head ) {
meta.name = "viewport";
document.head.appendChild( meta );
}
// Initialize configuration object
var rootData = root.dataset;
config = {
width: lib.util.toNumber( rootData.width, defaults.width ),
height: lib.util.toNumber( rootData.height, defaults.height ),
maxScale: lib.util.toNumber( rootData.maxScale, defaults.maxScale ),
minScale: lib.util.toNumber( rootData.minScale, defaults.minScale ),
perspective: lib.util.toNumber( rootData.perspective, defaults.perspective ),
transitionDuration: lib.util.toNumber(
rootData.transitionDuration, defaults.transitionDuration
)
};
windowScale = computeWindowScale( config );
// Wrap steps with "canvas" element
lib.util.arrayify( root.childNodes ).forEach( function( el ) {
canvas.appendChild( el );
} );
root.appendChild( canvas );
// Set initial styles
document.documentElement.style.height = "100%";
css( body, {
height: "100%",
overflow: "hidden"
} );
var rootStyles = {
position: "absolute",
transformOrigin: "top left",
transition: "all 0s ease-in-out",
transformStyle: "preserve-3d"
};
css( root, rootStyles );
css( root, {
top: "50%",
left: "50%",
perspective: ( config.perspective / windowScale ) + "px",
transform: scale( windowScale )
} );
css( canvas, rootStyles );
body.classList.remove( "impress-disabled" );
body.classList.add( "impress-enabled" );
// Get and init steps
initAllSteps();
// Set a default initial state of the canvas
currentState = {
translate: { x: 0, y: 0, z: 0 },
rotate: { x: 0, y: 0, z: 0, order: "xyz" },
scale: 1
};
initialized = true;
lib.util.triggerEvent( root, "impress:init",
{ api: roots[ "impress-root-" + rootId ] } );
};
// `getStep` is a helper function that returns a step element defined by parameter.
// If a number is given, step with index given by the number is returned, if a string
// is given step element with such id is returned, if DOM element is given it is returned
// if it is a correct step element.
var getStep = function( step ) {
if ( typeof step === "number" ) {
step = step < 0 ? steps[ steps.length + step ] : steps[ step ];
} else if ( typeof step === "string" ) {
step = lib.util.byId( step );
}
return ( step && step.id && stepsData[ "impress-" + step.id ] ) ? step : null;
};
// Used to reset timeout for `impress:stepenter` event
var stepEnterTimeout = null;
// `goto` API function that moves to step given as `el` parameter (by index, id or element).
// `duration` optionally given as second parameter, is the transition duration in css.
// `reason` is the string "next", "prev" or "goto" (default) and will be made available to
// preStepLeave plugins.
// `origEvent` may contain event that caused the call to goto, such as a key press event
var goto = function( el, duration, reason, origEvent ) {
reason = reason || "goto";
origEvent = origEvent || null;
if ( !initialized ) {
return false;
}
// Re-execute initAllSteps for each transition. This allows to edit step attributes
// dynamically, such as change their coordinates, or even remove or add steps, and have
// that change apply when goto() is called.
initAllSteps();
if ( !( el = getStep( el ) ) ) {
return false;
}
// Sometimes it's possible to trigger focus on first link with some keyboard action.
// Browser in such a case tries to scroll the page to make this element visible
// (even that body overflow is set to hidden) and it breaks our careful positioning.
//
// So, as a lousy (and lazy) workaround we will make the page scroll back to the top
// whenever slide is selected
//
// If you are reading this and know any better way to handle it, I'll be glad to hear
// about it!
window.scrollTo( 0, 0 );
var step = stepsData[ "impress-" + el.id ];
duration = ( duration !== undefined ? duration : step.transitionDuration );
// If we are in fact moving to another step, start with executing the registered
// preStepLeave plugins.
if ( activeStep && activeStep !== el ) {
var event = { target: activeStep, detail: {} };
event.detail.next = el;
event.detail.transitionDuration = duration;
event.detail.reason = reason;
if ( origEvent ) {
event.origEvent = origEvent;
}
if ( execPreStepLeavePlugins( event ) === false ) {
// PreStepLeave plugins are allowed to abort the transition altogether, by
// returning false.
// see stop and substep plugins for an example of doing just that
return false;
}
// Plugins are allowed to change the detail values
el = event.detail.next;
step = stepsData[ "impress-" + el.id ];
duration = event.detail.transitionDuration;
}
if ( activeStep ) {
activeStep.classList.remove( "active" );
body.classList.remove( "impress-on-" + activeStep.id );
}
el.classList.add( "active" );
body.classList.add( "impress-on-" + el.id );
// Compute target state of the canvas based on given step
var target = {
rotate: {
x: -step.rotate.x,
y: -step.rotate.y,
z: -step.rotate.z,
order: step.rotate.order
},
translate: {
x: -step.translate.x,
y: -step.translate.y,
z: -step.translate.z
},
scale: 1 / step.scale
};
// Check if the transition is zooming in or not.
//
// This information is used to alter the transition style:
// when we are zooming in - we start with move and rotate transition
// and the scaling is delayed, but when we are zooming out we start
// with scaling down and move and rotation are delayed.
var zoomin = target.scale >= currentState.scale;
duration = lib.util.toNumber( duration, config.transitionDuration );
var delay = ( duration / 2 );
// If the same step is re-selected, force computing window scaling,
// because it is likely to be caused by window resize
if ( el === activeStep ) {
windowScale = computeWindowScale( config );
}
var targetScale = target.scale * windowScale;
// Trigger leave of currently active element (if it's not the same step again)
if ( activeStep && activeStep !== el ) {
onStepLeave( activeStep, el );
}
// Now we alter transforms of `root` and `canvas` to trigger transitions.
//
// And here is why there are two elements: `root` and `canvas` - they are
// being animated separately:
// `root` is used for scaling and `canvas` for translate and rotations.
// Transitions on them are triggered with different delays (to make
// visually nice and "natural" looking transitions), so we need to know
// that both of them are finished.
css( root, {
// To keep the perspective look similar for different scales
// we need to "scale" the perspective, too
// For IE 11 support we must specify perspective independent
// of transform.
perspective: ( config.perspective / targetScale ) + "px",
transform: scale( targetScale ),
transitionDuration: duration + "ms",
transitionDelay: ( zoomin ? delay : 0 ) + "ms"
} );
css( canvas, {
transform: rotate( target.rotate, true ) + translate( target.translate ),
transitionDuration: duration + "ms",
transitionDelay: ( zoomin ? 0 : delay ) + "ms"
} );
// Here is a tricky part...
//
// If there is no change in scale or no change in rotation and translation, it means
// there was actually no delay - because there was no transition on `root` or `canvas`
// elements. We want to trigger `impress:stepenter` event in the correct moment, so
// here we compare the current and target values to check if delay should be taken into
// account.
//
// I know that this `if` statement looks scary, but it's pretty simple when you know
// what is going on - it's simply comparing all the values.
if ( currentState.scale === target.scale ||
( currentState.rotate.x === target.rotate.x &&
currentState.rotate.y === target.rotate.y &&
currentState.rotate.z === target.rotate.z &&
currentState.translate.x === target.translate.x &&
currentState.translate.y === target.translate.y &&
currentState.translate.z === target.translate.z ) ) {
delay = 0;
}
// Store current state
currentState = target;
activeStep = el;
// And here is where we trigger `impress:stepenter` event.
// We simply set up a timeout to fire it taking transition duration (and possible delay)
// into account.
//
// I really wanted to make it in more elegant way. The `transitionend` event seemed to
// be the best way to do it, but the fact that I'm using transitions on two separate
// elements and that the `transitionend` event is only triggered when there was a
// transition (change in the values) caused some bugs and made the code really
// complicated, cause I had to handle all the conditions separately. And it still
// needed a `setTimeout` fallback for the situations when there is no transition at all.
// So I decided that I'd rather make the code simpler than use shiny new
// `transitionend`.
//
// If you want learn something interesting and see how it was done with `transitionend`
// go back to version 0.5.2 of impress.js:
// http://github.com/bartaz/impress.js/blob/0.5.2/js/impress.js
window.clearTimeout( stepEnterTimeout );
stepEnterTimeout = window.setTimeout( function() {
onStepEnter( activeStep );
}, duration + delay );
return el;
};
// `prev` API function goes to previous step (in document order)
// `event` is optional, may contain the event that caused the need to call prev()
var prev = function( origEvent ) {
var prev = steps.indexOf( activeStep ) - 1;
prev = prev >= 0 ? steps[ prev ] : steps[ steps.length - 1 ];
return goto( prev, undefined, "prev", origEvent );
};
// `next` API function goes to next step (in document order)
// `event` is optional, may contain the event that caused the need to call next()
var next = function( origEvent ) {
var next = steps.indexOf( activeStep ) + 1;
next = next < steps.length ? steps[ next ] : steps[ 0 ];
return goto( next, undefined, "next", origEvent );
};
// Swipe for touch devices by @and3rson.
// Below we extend the api to control the animation between the currently
// active step and a presumed next/prev step. See touch plugin for
// an example of using this api.
// Helper function
var interpolate = function( a, b, k ) {
return a + ( b - a ) * k;
};
// Animate a swipe.
//
// Pct is a value between -1.0 and +1.0, designating the current length
// of the swipe.
//
// If pct is negative, swipe towards the next() step, if positive,
// towards the prev() step.
//
// Note that pre-stepleave plugins such as goto can mess with what is a
// next() and prev() step, so we need to trigger the pre-stepleave event
// here, even if a swipe doesn't guarantee that the transition will
// actually happen.
//
// Calling swipe(), with any value of pct, won't in itself cause a
// transition to happen, this is just to animate the swipe. Once the
// transition is committed - such as at a touchend event - caller is
// responsible for also calling prev()/next() as appropriate.
//
// Note: For now, this function is made available to be used by the swipe plugin (which
// is the UI counterpart to this). It is a semi-internal API and intentionally not
// documented in DOCUMENTATION.md.
var swipe = function( pct ) {
if ( Math.abs( pct ) > 1 ) {
return;
}
// Prepare & execute the preStepLeave event
var event = { target: activeStep, detail: {} };
event.detail.swipe = pct;
// Will be ignored within swipe animation, but just in case a plugin wants to read this,
// humor them
event.detail.transitionDuration = config.transitionDuration;
var idx; // Needed by jshint
if ( pct < 0 ) {
idx = steps.indexOf( activeStep ) + 1;
event.detail.next = idx < steps.length ? steps[ idx ] : steps[ 0 ];
event.detail.reason = "next";
} else if ( pct > 0 ) {
idx = steps.indexOf( activeStep ) - 1;
event.detail.next = idx >= 0 ? steps[ idx ] : steps[ steps.length - 1 ];
event.detail.reason = "prev";
} else {
// No move
return;
}
if ( execPreStepLeavePlugins( event ) === false ) {
// If a preStepLeave plugin wants to abort the transition, don't animate a swipe
// For stop, this is probably ok. For substep, the plugin it self might want to do
// some animation, but that's not the current implementation.
return false;
}
var nextElement = event.detail.next;
var nextStep = stepsData[ "impress-" + nextElement.id ];
// If the same step is re-selected, force computing window scaling,
var nextScale = nextStep.scale * windowScale;
var k = Math.abs( pct );
var interpolatedStep = {
translate: {
x: interpolate( currentState.translate.x, -nextStep.translate.x, k ),
y: interpolate( currentState.translate.y, -nextStep.translate.y, k ),
z: interpolate( currentState.translate.z, -nextStep.translate.z, k )
},
rotate: {
x: interpolate( currentState.rotate.x, -nextStep.rotate.x, k ),
y: interpolate( currentState.rotate.y, -nextStep.rotate.y, k ),
z: interpolate( currentState.rotate.z, -nextStep.rotate.z, k ),
// Unfortunately there's a discontinuity if rotation order changes. Nothing I
// can do about it?
order: k < 0.7 ? currentState.rotate.order : nextStep.rotate.order
},
scale: interpolate( currentState.scale * windowScale, nextScale, k )
};
css( root, {
// To keep the perspective look similar for different scales
// we need to 'scale' the perspective, too
perspective: config.perspective / interpolatedStep.scale + "px",
transform: scale( interpolatedStep.scale ),
transitionDuration: "0ms",
transitionDelay: "0ms"
} );
css( canvas, {
transform: rotate( interpolatedStep.rotate, true ) +
translate( interpolatedStep.translate ),
transitionDuration: "0ms",
transitionDelay: "0ms"
} );
};
// Teardown impress
// Resets the DOM to the state it was before impress().init() was called.
// (If you called impress(rootId).init() for multiple different rootId's, then you must
// also call tear() once for each of them.)
var tear = function() {
lib.gc.teardown();
delete roots[ "impress-root-" + rootId ];
};
// Adding some useful classes to step elements.
//
// All the steps that have not been shown yet are given `future` class.
// When the step is entered the `future` class is removed and the `present`
// class is given. When the step is left `present` class is replaced with
// `past` class.
//
// So every step element is always in one of three possible states:
// `future`, `present` and `past`.
//
// There classes can be used in CSS to style different types of steps.
// For example the `present` class can be used to trigger some custom
// animations when step is shown.
lib.gc.addEventListener( root, "impress:init", function() {
// STEP CLASSES
steps.forEach( function( step ) {
step.classList.add( "future" );
} );
lib.gc.addEventListener( root, "impress:stepenter", function( event ) {
event.target.classList.remove( "past" );
event.target.classList.remove( "future" );
event.target.classList.add( "present" );
}, false );
lib.gc.addEventListener( root, "impress:stepleave", function( event ) {
event.target.classList.remove( "present" );
event.target.classList.add( "past" );
}, false );
}, false );
// Adding hash change support.
lib.gc.addEventListener( root, "impress:init", function() {
// Last hash detected
var lastHash = "";
// `#/step-id` is used instead of `#step-id` to prevent default browser
// scrolling to element in hash.
//
// And it has to be set after animation finishes, because in Chrome it
// makes transtion laggy.
// BUG: http://code.google.com/p/chromium/issues/detail?id=62820
lib.gc.addEventListener( root, "impress:stepenter", function( event ) {
window.location.hash = lastHash = "#/" + event.target.id;
}, false );
lib.gc.addEventListener( window, "hashchange", function() {
// When the step is entered hash in the location is updated
// (just few lines above from here), so the hash change is
// triggered and we would call `goto` again on the same element.
//
// To avoid this we store last entered hash and compare.
if ( window.location.hash !== lastHash ) {
goto( lib.util.getElementFromHash() );
}
}, false );
// START
// by selecting step defined in url or first step of the presentation
goto( lib.util.getElementFromHash() || steps[ 0 ], 0 );
}, false );
body.classList.add( "impress-disabled" );
// Store and return API for given impress.js root element
return ( roots[ "impress-root-" + rootId ] = {
init: init,
goto: goto,
next: next,
prev: prev,
swipe: swipe,
tear: tear,
lib: lib
} );
};
// Flag that can be used in JS to check if browser have passed the support test
impress.supported = impressSupported;
// ADD and INIT LIBRARIES
// Library factories are defined in src/lib/*.js, and register themselves by calling
// impress.addLibraryFactory(libraryFactoryObject). They're stored here, and used to augment
// the API with library functions when client calls impress(rootId).
// See src/lib/README.md for clearer example.
// (Advanced usage: For different values of rootId, a different instance of the libaries are
// generated, in case they need to hold different state for different root elements.)
var libraryFactories = {};
impress.addLibraryFactory = function( obj ) {
for ( var libname in obj ) {
if ( obj.hasOwnProperty( libname ) ) {
libraryFactories[ libname ] = obj[ libname ];
}
}
};
// Call each library factory, and return the lib object that is added to the api.
var initLibraries = function( rootId ) { //jshint ignore:line
var lib = {};
for ( var libname in libraryFactories ) {
if ( libraryFactories.hasOwnProperty( libname ) ) {
if ( lib[ libname ] !== undefined ) {
throw "impress.js ERROR: Two libraries both tried to use libname: " + libname;
}
lib[ libname ] = libraryFactories[ libname ]( rootId );
}
}
return lib;
};
// `addPreInitPlugin` allows plugins to register a function that should
// be run (synchronously) at the beginning of init, before
// impress().init() itself executes.
impress.addPreInitPlugin = function( plugin, weight ) {
weight = parseInt( weight ) || 10;
if ( weight <= 0 ) {
throw "addPreInitPlugin: weight must be a positive integer";
}
if ( preInitPlugins[ weight ] === undefined ) {
preInitPlugins[ weight ] = [];
}
preInitPlugins[ weight ].push( plugin );
};
// Called at beginning of init, to execute all pre-init plugins.
var execPreInitPlugins = function( root ) { //jshint ignore:line
for ( var i = 0; i < preInitPlugins.length; i++ ) {
var thisLevel = preInitPlugins[ i ];
if ( thisLevel !== undefined ) {
for ( var j = 0; j < thisLevel.length; j++ ) {
thisLevel[ j ]( root );
}
}
}
};
// `addPreStepLeavePlugin` allows plugins to register a function that should
// be run (synchronously) at the beginning of goto()
impress.addPreStepLeavePlugin = function( plugin, weight ) { //jshint ignore:line
weight = parseInt( weight ) || 10;
if ( weight <= 0 ) {
throw "addPreStepLeavePlugin: weight must be a positive integer";
}
if ( preStepLeavePlugins[ weight ] === undefined ) {
preStepLeavePlugins[ weight ] = [];
}
preStepLeavePlugins[ weight ].push( plugin );
};
// Called at beginning of goto(), to execute all preStepLeave plugins.
var execPreStepLeavePlugins = function( event ) { //jshint ignore:line
for ( var i = 0; i < preStepLeavePlugins.length; i++ ) {
var thisLevel = preStepLeavePlugins[ i ];
if ( thisLevel !== undefined ) {
for ( var j = 0; j < thisLevel.length; j++ ) {
if ( thisLevel[ j ]( event ) === false ) {
// If a plugin returns false, the stepleave event (and related transition)
// is aborted
return false;
}
}
}
}
};
} )( document, window );
// THAT'S ALL FOLKS!
//
// Thanks for reading it all.
// Or thanks for scrolling down and reading the last part.
//
// I've learnt a lot when building impress.js and I hope this code and comments
// will help somebody learn at least some part of it.

3384
src/main/java/com/fr/plugin/easyslides/web/impress-plugins.js

File diff suppressed because it is too large Load Diff

4296
src/main/java/com/fr/plugin/easyslides/web/impress.js

File diff suppressed because it is too large Load Diff

60
src/main/java/com/fr/plugin/easyslides/web/widget.js

@ -0,0 +1,60 @@
;
(function ($) {
FR.EasySlides = FR.extend(FR.Widget, {
_defaultConfig: function () {
return $.extend(FR.EasySlides.superclass._defaultConfig.apply(), {
baseName: 'easyslides',
baseClass: 'easyslides'
});
},
_init: function () {
FR.EasySlides.superclass._init.apply(this, arguments);
FR.$defaultImport('/com/fr/plugin/easyslides/web/impress-main.js', 'js');
FR.$defaultImport('/com/fr/plugin/easyslides/web/impress-plugins.js', 'js');
var o = this.options;
var myWidgetName = o.widgetName;
var myWidget = this.element;
var contents = o.value;
debugger;
//var $topdiv = $("[widgetname='" +o.widgetName+ "']");
myWidget.css("background-color", o.backgroundColor);
// 这部分内容不能放在<div id="impress">内部
if (o.toolBar) {
$("<div id=\"impress-toolbar\"></div>").appendTo(myWidget);
}
if (o.progressBar) {
$("<div class=\"impress-progressbar\"><div></div></div>").appendTo(myWidget);
}
if (o.progress) {
$("<div class=\"impress-progress\"></div>").appendTo(myWidget);
}
myWidget.on("impress:stepenter", function (event) {
var width = parseFloat(myWidget.css("width"));
var height = parseFloat(myWidget.css("height"));
var wScale = 1536 / 900;
var hScale = 758 / 700;
var fontScale = 1536 * 758 / 30;
var lhScale = 1536 * 758 / 36;
var padxScale = 1536 / 40;
var padyScale = 1536 / 60;
var $slide = $(".slide");
$slide.css({
'width': width / wScale + 'px',
'height': height / hScale + 'px',
'font-size': width * height / fontScale + 'px',
'line-height': width * height / lhScale + 'px',
'padding': width / padxScale + 'px ' + height / padyScale + 'px'
});
});
$(contents).appendTo(myWidget);
},
});
$.shortcut("easyslides", FR.EasySlides);
})(jQuery);
Loading…
Cancel
Save